diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 1a9dacfa0b8..56c4d16378a 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -70,6 +70,10 @@ #include #include +constexpr int COMPONENT_COUNT_FOR_ACCESSOR_TYPE[7] = { + 1, 2, 3, 4, 4, 9, 16 +}; + static Ref _mesh_to_importer_mesh(Ref p_mesh) { Ref importer_mesh; importer_mesh.instantiate(); @@ -169,10 +173,6 @@ Error GLTFDocument::_serialize(Ref p_state) { return Error::FAILED; } - for (GLTFBufferViewIndex i = 0; i < p_state->buffer_views.size(); i++) { - p_state->buffer_views.write[i]->buffer = 0; - } - /* STEP SERIALIZE BUFFER VIEWS */ err = _encode_buffer_views(p_state); if (err != OK) { @@ -1090,18 +1090,21 @@ String GLTFDocument::_get_component_type_name(const uint32_t p_component) { return ""; } -Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_src, const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_vertex_indices) { - const int component_count_for_type[7] = { - 1, 2, 3, 4, 4, 9, 16 - }; - - const int component_count = component_count_for_type[p_accessor_type]; +Error GLTFDocument::_encode_accessor_into_buffer_view(Ref p_state, const double *p_src, const int64_t p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_type, const bool p_normalized, const int64_t p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_buffer_view, const bool p_for_vertex_indices) { + const int component_count = COMPONENT_COUNT_FOR_ACCESSOR_TYPE[p_accessor_type]; const int component_size = _get_component_type_size(p_component_type); ERR_FAIL_COND_V(component_size == 0, FAILED); + // The byte offset of an accessor MUST be a multiple of the accessor's component size. + // See 3.6.2.4: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#data-alignment + int64_t offset = p_byte_offset; + if (p_byte_offset % component_size != 0) { + offset += component_size - (p_byte_offset % component_size); + } - int skip_every = 0; - int skip_bytes = 0; - //special case of alignments, as described in spec + int64_t skip_every = 0; + int64_t skip_bytes = 0; + // Accessors of matrix type have data stored in column-major order. The start of each column MUST be aligned to 4-byte boundaries. + // See 3.6.2.4: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#data-alignment switch (p_component_type) { case COMPONENT_TYPE_BYTE: case COMPONENT_TYPE_UNSIGNED_BYTE: { @@ -1118,7 +1121,7 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ case COMPONENT_TYPE_UNSIGNED_SHORT: { if (p_accessor_type == GLTFAccessor::TYPE_MAT3) { skip_every = 6; - skip_bytes = 4; + skip_bytes = 2; } } break; default: { @@ -1127,8 +1130,10 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ Ref bv; bv.instantiate(); - const uint32_t offset = bv->byte_offset = p_byte_offset; - Vector &gltf_buffer = p_state->buffers.write[0]; + const GLTFBufferIndex buffer0 = 0; + bv->buffer = buffer0; + bv->byte_offset = offset; + Vector &gltf_buffer = p_state->buffers.write[buffer0]; int stride = component_count * component_size; if (p_for_vertex && stride % 4) { @@ -1150,139 +1155,237 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ } switch (p_component_type) { - case COMPONENT_TYPE_BYTE: { - Vector buffer; - buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + case GLTFAccessor::COMPONENT_TYPE_NONE: { + ERR_FAIL_V_MSG(ERR_INVALID_DATA, "glTF: Failed to encode buffer view, component type not set."); + } + case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } double d = *p_src; if (p_normalized) { - buffer.write[dst_i] = d * 128.0; + encoded_data.write[dst_i] = d * 128.0; } else { - buffer.write[dst_i] = d; + encoded_data.write[dst_i] = d; } p_src++; dst_i++; } } - int64_t old_size = gltf_buffer.size(); - gltf_buffer.resize(old_size + (buffer.size() * sizeof(int8_t))); - memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int8_t)); - bv->byte_length = buffer.size() * sizeof(int8_t); + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(int8_t); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; } break; - case COMPONENT_TYPE_UNSIGNED_BYTE: { - Vector buffer; - buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_BYTE: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } double d = *p_src; if (p_normalized) { - buffer.write[dst_i] = d * 255.0; + encoded_data.write[dst_i] = d * 255.0; } else { - buffer.write[dst_i] = d; + encoded_data.write[dst_i] = d; } p_src++; dst_i++; } } - gltf_buffer.append_array(buffer); - bv->byte_length = buffer.size() * sizeof(uint8_t); + gltf_buffer.append_array(encoded_data); + const size_t buffer_size = encoded_data.size() * sizeof(uint8_t); + bv->byte_length = buffer_size; } break; - case COMPONENT_TYPE_SHORT: { - Vector buffer; - buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } double d = *p_src; if (p_normalized) { - buffer.write[dst_i] = d * 32768.0; + encoded_data.write[dst_i] = d * 32768.0; } else { - buffer.write[dst_i] = d; + encoded_data.write[dst_i] = d; } p_src++; dst_i++; } } - int64_t old_size = gltf_buffer.size(); - gltf_buffer.resize(old_size + (buffer.size() * sizeof(int16_t))); - memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int16_t)); - bv->byte_length = buffer.size() * sizeof(int16_t); + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(int16_t); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; } break; - case COMPONENT_TYPE_UNSIGNED_SHORT: { - Vector buffer; - buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } double d = *p_src; if (p_normalized) { - buffer.write[dst_i] = d * 65535.0; + encoded_data.write[dst_i] = d * 65535.0; } else { - buffer.write[dst_i] = d; + encoded_data.write[dst_i] = d; } p_src++; dst_i++; } } - int64_t old_size = gltf_buffer.size(); - gltf_buffer.resize(old_size + (buffer.size() * sizeof(uint16_t))); - memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(uint16_t)); - bv->byte_length = buffer.size() * sizeof(uint16_t); + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(uint16_t); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; } break; - case COMPONENT_TYPE_INT: { - Vector buffer; - buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + case GLTFAccessor::COMPONENT_TYPE_SIGNED_INT: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } double d = *p_src; - buffer.write[dst_i] = d; + encoded_data.write[dst_i] = d; p_src++; dst_i++; } } - int64_t old_size = gltf_buffer.size(); - gltf_buffer.resize(old_size + (buffer.size() * sizeof(int32_t))); - memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(int32_t)); - bv->byte_length = buffer.size() * sizeof(int32_t); + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(int32_t); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; } break; - case COMPONENT_TYPE_FLOAT: { - Vector buffer; - buffer.resize(p_count * component_count); - int32_t dst_i = 0; - for (int i = 0; i < p_count; i++) { - for (int j = 0; j < component_count; j++) { + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { if (skip_every && j > 0 && (j % skip_every) == 0) { dst_i += skip_bytes; } double d = *p_src; - buffer.write[dst_i] = d; + encoded_data.write[dst_i] = d; p_src++; dst_i++; } } - int64_t old_size = gltf_buffer.size(); - gltf_buffer.resize(old_size + (buffer.size() * sizeof(float))); - memcpy(gltf_buffer.ptrw() + old_size, buffer.ptrw(), buffer.size() * sizeof(float)); - bv->byte_length = buffer.size() * sizeof(float); + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(uint32_t); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; + } break; + case GLTFAccessor::COMPONENT_TYPE_SINGLE_FLOAT: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + double d = *p_src; + encoded_data.write[dst_i] = d; + p_src++; + dst_i++; + } + } + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(float); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; + } break; + case GLTFAccessor::COMPONENT_TYPE_DOUBLE_FLOAT: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + double d = *p_src; + encoded_data.write[dst_i] = d; + p_src++; + dst_i++; + } + } + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(double); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; + } break; + case GLTFAccessor::COMPONENT_TYPE_HALF_FLOAT: { + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "glTF: Half float not supported yet."); + } break; + case GLTFAccessor::COMPONENT_TYPE_SIGNED_LONG: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + // FIXME: This can result in precision loss because int64_t can store some values that double can't. + double d = *p_src; + encoded_data.write[dst_i] = d; + p_src++; + dst_i++; + } + } + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(int64_t); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; + } break; + case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_LONG: { + Vector encoded_data; + encoded_data.resize(p_count * component_count); + int64_t dst_i = 0; + for (int64_t i = 0; i < p_count; i++) { + for (int64_t j = 0; j < component_count; j++) { + if (skip_every && j > 0 && (j % skip_every) == 0) { + dst_i += skip_bytes; + } + // FIXME: This can result in precision loss because int64_t can store some values that double can't. + double d = *p_src; + encoded_data.write[dst_i] = d; + p_src++; + dst_i++; + } + } + const int64_t old_size = gltf_buffer.size(); + const size_t buffer_size = encoded_data.size() * sizeof(uint64_t); + gltf_buffer.resize(old_size + buffer_size); + memcpy(gltf_buffer.ptrw() + old_size, encoded_data.ptrw(), buffer_size); + bv->byte_length = buffer_size; } break; } ERR_FAIL_COND_V(buffer_end > bv->byte_length, ERR_INVALID_DATA); @@ -1293,7 +1396,7 @@ Error GLTFDocument::_encode_buffer_view(Ref p_state, const double *p_ gltf_buffer.push_back(0); } - r_accessor = bv->buffer = p_state->buffer_views.size(); + r_buffer_view = p_state->buffer_views.size(); p_state->buffer_views.push_back(bv); return OK; } @@ -1310,6 +1413,12 @@ Error GLTFDocument::_decode_buffer_view(Ref p_state, double *p_dst, c } ERR_FAIL_INDEX_V(bv->buffer, p_state->buffers.size(), ERR_PARSE_ERROR); + if (bv->byte_offset % p_component_size != 0) { + WARN_PRINT("glTF: Buffer view byte offset is not a multiple of accessor component size. This file is invalid per the glTF specification and will not load correctly in some glTF viewers, but Godot will try to load it anyway."); + } + if (p_byte_offset % p_component_size != 0) { + WARN_PRINT("glTF: Accessor byte offset is not a multiple of accessor component size. This file is invalid per the glTF specification and will not load correctly in some glTF viewers, but Godot will try to load it anyway."); + } const uint32_t offset = bv->byte_offset + p_byte_offset; Vector buffer = p_state->buffers[bv->buffer]; //copy on write, so no performance hit @@ -1553,7 +1662,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref p_state, accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i, p_for_vertex_indices); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i, p_for_vertex_indices); if (err != OK) { return -1; } @@ -1662,7 +1771,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref p_state, accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1715,7 +1824,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref p_state accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1782,7 +1891,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref p_sta accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1833,7 +1942,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref p_stat accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1886,7 +1995,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref p accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1961,7 +2070,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref p_stat accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -2011,7 +2120,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref p_state, accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -2105,11 +2214,11 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref p } else { sparse_accessor->sparse_indices_component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; } - if (_encode_buffer_view(p_state, changed_indices.ptr(), changed_indices.size(), GLTFAccessor::TYPE_SCALAR, sparse_accessor->sparse_indices_component_type, sparse_accessor->normalized, sparse_accessor->sparse_indices_byte_offset, false, buffer_view_i_indices) != OK) { + if (_encode_accessor_into_buffer_view(p_state, changed_indices.ptr(), changed_indices.size(), GLTFAccessor::TYPE_SCALAR, sparse_accessor->sparse_indices_component_type, sparse_accessor->normalized, sparse_accessor->sparse_indices_byte_offset, false, buffer_view_i_indices) != OK) { return -1; } // We use changed_indices.size() here, because we must pass the number of vec3 values rather than the number of components. - if (_encode_buffer_view(p_state, changed_values.ptr(), changed_indices.size(), sparse_accessor->accessor_type, sparse_accessor->component_type, sparse_accessor->normalized, sparse_accessor->sparse_values_byte_offset, false, buffer_view_i_values) != OK) { + if (_encode_accessor_into_buffer_view(p_state, changed_values.ptr(), changed_indices.size(), sparse_accessor->accessor_type, sparse_accessor->component_type, sparse_accessor->normalized, sparse_accessor->sparse_values_byte_offset, false, buffer_view_i_values) != OK) { return -1; } sparse_accessor->sparse_indices_buffer_view = buffer_view_i_indices; @@ -2118,7 +2227,7 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref p } else if (changed_indices.size() > 0) { GLTFBufferIndex buffer_view_i; sparse_accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, sparse_accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, sparse_accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -2192,7 +2301,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref p_state accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_accessor_into_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index d37544750d3..9c0fa261876 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -265,11 +265,11 @@ private: GLTFAccessorIndex _encode_accessor_as_xform(Ref p_state, const Vector p_attribs, const bool p_for_vertex); - Error _encode_buffer_view(Ref p_state, const double *p_src, - const int p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, + Error _encode_accessor_into_buffer_view(Ref p_state, const double *p_src, + const int64_t p_count, const GLTFAccessor::GLTFAccessorType p_accessor_type, const int p_component_type, const bool p_normalized, - const int p_byte_offset, const bool p_for_vertex, - GLTFBufferViewIndex &r_accessor, const bool p_for_indices = false); + const int64_t p_byte_offset, const bool p_for_vertex, + GLTFBufferViewIndex &r_buffer_view, const bool p_for_indices = false); Error _encode_accessors(Ref p_state); Error _encode_buffer_views(Ref p_state); diff --git a/modules/gltf/structures/gltf_accessor.h b/modules/gltf/structures/gltf_accessor.h index 1a3a2cb4943..0e231ca3df6 100644 --- a/modules/gltf/structures/gltf_accessor.h +++ b/modules/gltf/structures/gltf_accessor.h @@ -50,6 +50,21 @@ public: TYPE_MAT4, }; + enum GLTFComponentType { + COMPONENT_TYPE_NONE = 0, + COMPONENT_TYPE_SIGNED_BYTE = 5120, + COMPONENT_TYPE_UNSIGNED_BYTE = 5121, + COMPONENT_TYPE_SIGNED_SHORT = 5122, + COMPONENT_TYPE_UNSIGNED_SHORT = 5123, + COMPONENT_TYPE_SIGNED_INT = 5124, + COMPONENT_TYPE_UNSIGNED_INT = 5125, + COMPONENT_TYPE_SINGLE_FLOAT = 5126, + COMPONENT_TYPE_DOUBLE_FLOAT = 5130, + COMPONENT_TYPE_HALF_FLOAT = 5131, + COMPONENT_TYPE_SIGNED_LONG = 5134, + COMPONENT_TYPE_UNSIGNED_LONG = 5135, + }; + private: GLTFBufferViewIndex buffer_view = -1; int byte_offset = 0;