GLTF: Use const Vector internally instead of TypedArray copies

This commit is contained in:
Aaron Franke 2025-11-25 11:45:25 -08:00
parent 7ed0b61676
commit 342088ca31
No known key found for this signature in database
GPG key ID: 40A1750B977E56BF
9 changed files with 532 additions and 215 deletions

View file

@ -550,7 +550,7 @@ bool GLTFAccessor::is_equal_exact(const Ref<GLTFAccessor> &p_other) const {
// Private decode functions.
PackedInt64Array GLTFAccessor::_decode_sparse_indices(const Ref<GLTFState> &p_gltf_state, const TypedArray<GLTFBufferView> &p_buffer_views) const {
PackedInt64Array GLTFAccessor::_decode_sparse_indices(const Ref<GLTFState> &p_gltf_state, const Vector<Ref<GLTFBufferView>> &p_buffer_views) const {
const int64_t bytes_per_component = _get_bytes_per_component(sparse_indices_component_type);
PackedInt64Array numbers;
ERR_FAIL_INDEX_V(sparse_indices_buffer_view, p_buffer_views.size(), numbers);
@ -589,7 +589,7 @@ PackedInt64Array GLTFAccessor::_decode_sparse_indices(const Ref<GLTFState> &p_gl
}
template <typename T>
Vector<T> GLTFAccessor::_decode_raw_numbers(const Ref<GLTFState> &p_gltf_state, const TypedArray<GLTFBufferView> &p_buffer_views, bool p_sparse_values) const {
Vector<T> GLTFAccessor::_decode_raw_numbers(const Ref<GLTFState> &p_gltf_state, const Vector<Ref<GLTFBufferView>> &p_buffer_views, bool p_sparse_values) const {
const int64_t bytes_per_component = _get_bytes_per_component(component_type);
const int64_t bytes_per_vector = _get_bytes_per_vector();
const int64_t vector_size = _get_vector_size();
@ -732,7 +732,7 @@ Vector<T> GLTFAccessor::_decode_raw_numbers(const Ref<GLTFState> &p_gltf_state,
template <typename T>
Vector<T> GLTFAccessor::_decode_as_numbers(const Ref<GLTFState> &p_gltf_state) const {
const TypedArray<GLTFBufferView> &p_buffer_views = p_gltf_state->get_buffer_views();
const Vector<Ref<GLTFBufferView>> &p_buffer_views = p_gltf_state->get_buffer_views();
Vector<T> ret_numbers = _decode_raw_numbers<T>(p_gltf_state, p_buffer_views, false);
if (sparse_count == 0) {
return ret_numbers;
@ -1440,10 +1440,10 @@ GLTFAccessorIndex GLTFAccessor::store_accessor_data_into_state(const Ref<GLTFSta
ERR_FAIL_COND_V_MSG(buffer_view_index == -1, -1, "glTF export: Accessor failed to write new buffer view into glTF state.");
set_buffer_view(buffer_view_index);
// Add the new accessor to the state, but check for duplicates first.
TypedArray<GLTFAccessor> state_accessors = p_gltf_state->get_accessors();
Vector<Ref<GLTFAccessor>> state_accessors = p_gltf_state->get_accessors();
const GLTFAccessorIndex accessor_count = state_accessors.size();
for (GLTFAccessorIndex i = 0; i < accessor_count; i++) {
Ref<GLTFAccessor> existing_accessor = state_accessors[i];
const Ref<GLTFAccessor> &existing_accessor = state_accessors[i];
if (is_equal_exact(existing_accessor)) {
// An identical accessor already exists in the state, so just return the index.
return i;
@ -1675,10 +1675,10 @@ GLTFAccessorIndex GLTFAccessor::encode_new_sparse_accessor_from_vec3s(const Ref<
const PackedFloat64Array filtered_numbers = accessor->_filter_numbers(dense_values);
accessor->_calculate_min_and_max(filtered_numbers);
// Add the new accessor to the state, but check for duplicates first.
TypedArray<GLTFAccessor> state_accessors = p_gltf_state->get_accessors();
Vector<Ref<GLTFAccessor>> state_accessors = p_gltf_state->get_accessors();
const GLTFAccessorIndex accessor_count = state_accessors.size();
for (GLTFAccessorIndex i = 0; i < accessor_count; i++) {
Ref<GLTFAccessor> existing_accessor = state_accessors[i];
const Ref<GLTFAccessor> &existing_accessor = state_accessors[i];
if (accessor->is_equal_exact(existing_accessor)) {
// An identical accessor already exists in the state, so just return the index.
return i;

View file

@ -95,9 +95,9 @@ private:
int64_t _get_bytes_per_vector() const;
// Private decode functions.
PackedInt64Array _decode_sparse_indices(const Ref<GLTFState> &p_gltf_state, const TypedArray<GLTFBufferView> &p_buffer_views) const;
PackedInt64Array _decode_sparse_indices(const Ref<GLTFState> &p_gltf_state, const Vector<Ref<GLTFBufferView>> &p_buffer_views) const;
template <typename T>
Vector<T> _decode_raw_numbers(const Ref<GLTFState> &p_gltf_state, const TypedArray<GLTFBufferView> &p_buffer_views, bool p_sparse_values) const;
Vector<T> _decode_raw_numbers(const Ref<GLTFState> &p_gltf_state, const Vector<Ref<GLTFBufferView>> &p_buffer_views, bool p_sparse_values) const;
template <typename T>
Vector<T> _decode_as_numbers(const Ref<GLTFState> &p_gltf_state) const;

View file

@ -110,7 +110,7 @@ void GLTFBufferView::set_vertex_attributes(bool p_attributes) {
Vector<uint8_t> GLTFBufferView::load_buffer_view_data(const Ref<GLTFState> p_gltf_state) const {
ERR_FAIL_COND_V(p_gltf_state.is_null(), Vector<uint8_t>());
const TypedArray<Vector<uint8_t>> &buffers = p_gltf_state->get_buffers();
const Vector<PackedByteArray> &buffers = p_gltf_state->get_buffers();
ERR_FAIL_INDEX_V(buffer, buffers.size(), Vector<uint8_t>());
const PackedByteArray &buffer_data = buffers[buffer];
const int64_t byte_end = byte_offset + byte_length;
@ -127,11 +127,11 @@ GLTFBufferViewIndex GLTFBufferView::write_new_buffer_view_into_state(const Ref<G
ERR_FAIL_COND_V_MSG(p_byte_stride < 4 || p_byte_stride % 4 != 0, -1, "glTF export: Vertex attributes using TARGET_ARRAY_BUFFER must have a byte stride that is a multiple of 4 as required by section 3.6.2.4 of the glTF specification.");
}
// Check for duplicate buffer views before adding a new one.
TypedArray<GLTFBufferView> state_buffer_views = p_gltf_state->get_buffer_views();
Vector<Ref<GLTFBufferView>> state_buffer_views = p_gltf_state->get_buffer_views();
const int buffer_view_index = state_buffer_views.size();
if (p_deduplicate) {
for (int i = 0; i < buffer_view_index; i++) {
const Ref<GLTFBufferView> existing_buffer_view = state_buffer_views[i];
const Ref<GLTFBufferView> &existing_buffer_view = state_buffer_views[i];
if (existing_buffer_view->get_byte_offset() % p_alignment == 0 &&
existing_buffer_view->get_byte_length() == p_input_data.size() &&
existing_buffer_view->get_byte_stride() == p_byte_stride &&
@ -145,7 +145,7 @@ GLTFBufferViewIndex GLTFBufferView::write_new_buffer_view_into_state(const Ref<G
}
}
// Write the data into the buffer at the specified index.
TypedArray<PackedByteArray> state_buffers = p_gltf_state->get_buffers();
Vector<PackedByteArray> state_buffers = p_gltf_state->get_buffers();
if (state_buffers.size() <= p_buffer_index) {
state_buffers.resize(p_buffer_index + 1);
}
@ -160,7 +160,7 @@ GLTFBufferViewIndex GLTFBufferView::write_new_buffer_view_into_state(const Ref<G
state_buffer.resize(byte_offset + input_data_size);
uint8_t *buffer_ptr = state_buffer.ptrw();
memcpy(buffer_ptr + byte_offset, p_input_data.ptr(), input_data_size);
state_buffers[p_buffer_index] = state_buffer;
state_buffers.set(p_buffer_index, state_buffer);
p_gltf_state->set_buffers(state_buffers);
// Create a new GLTFBufferView that references the new buffer.
Ref<GLTFBufferView> buffer_view;