Skip to content

Commit 10a6540

Browse files
committed
Merge pull request #109102 from aaronfranke/gltf-fix-decode
GLTF: Fix minor niche edge case issues with accessors
2 parents b75de54 + 11a1315 commit 10a6540

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

modules/gltf/gltf_document.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,15 +1503,16 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c
15031503
}
15041504

15051505
double d = 0;
1506-
1506+
// 3.11. Implementations MUST use following equations to decode real floating-point value f from a normalized integer c and vise-versa.
1507+
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#animations
15071508
switch (p_component_type) {
15081509
case GLTFAccessor::COMPONENT_TYPE_NONE: {
15091510
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "glTF: Failed to decode buffer view, component type not set.");
15101511
} break;
15111512
case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: {
15121513
int8_t b = int8_t(*src);
15131514
if (p_normalized) {
1514-
d = (double(b) / 128.0);
1515+
d = MAX(double(b) / 127.0, -1.0);
15151516
} else {
15161517
d = double(b);
15171518
}
@@ -1527,7 +1528,7 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c
15271528
case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: {
15281529
int16_t s = *(int16_t *)src;
15291530
if (p_normalized) {
1530-
d = (double(s) / 32768.0);
1531+
d = MAX(double(s) / 32767.0, -1.0);
15311532
} else {
15321533
d = double(s);
15331534
}
@@ -1628,7 +1629,7 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF
16281629
case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: {
16291630
if (a->accessor_type == GLTFAccessor::TYPE_MAT3) {
16301631
skip_every = 6;
1631-
skip_bytes = 4;
1632+
skip_bytes = 2;
16321633
element_size = 16; //override for this case
16331634
}
16341635
} break;
@@ -1724,7 +1725,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state,
17241725
int64_t size = p_state->buffers[0].size();
17251726
const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_SCALAR;
17261727
GLTFAccessor::GLTFComponentType component_type;
1727-
if (max_index > 65535 || p_for_vertex) {
1728+
if (max_index > 65534 || p_for_vertex) {
17281729
component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT;
17291730
} else {
17301731
component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT;
@@ -2274,7 +2275,7 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p
22742275
}
22752276
sparse_accessor->max = type_max;
22762277
sparse_accessor->min = type_min;
2277-
int64_t sparse_accessor_index_stride = max_changed_index > 65535 ? 4 : 2;
2278+
int64_t sparse_accessor_index_stride = max_changed_index > 65534 ? 4 : 2;
22782279

22792280
int64_t sparse_accessor_storage_size = changed_indices.size() * (sparse_accessor_index_stride + element_count * sizeof(float));
22802281
int64_t conventional_storage_size = p_attribs.size() * element_count * sizeof(float);
@@ -3051,7 +3052,7 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> p_state) {
30513052
}
30523053
}
30533054
{
3054-
const Array &a = array[Mesh::ARRAY_WEIGHTS];
3055+
const PackedRealArray &a = array[Mesh::ARRAY_WEIGHTS];
30553056
const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX];
30563057
if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) {
30573058
int32_t vertex_count = vertex_array.size();
@@ -3475,6 +3476,9 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
34753476
}
34763477
array[Mesh::ARRAY_BONES] = joints;
34773478
}
3479+
// glTF stores weights as a VEC4 array or multiple VEC4 arrays, but Godot's
3480+
// ArrayMesh uses a flat array of either 4 or 8 floats per vertex.
3481+
// Therefore, decode up to two glTF VEC4 arrays as float arrays.
34783482
if (a.has("WEIGHTS_0") && !a.has("WEIGHTS_1")) {
34793483
Vector<float> weights = _decode_accessor_as_floats(p_state, a["WEIGHTS_0"], true, indices_vec4_mapping);
34803484
ERR_FAIL_COND_V(weights.size() != 4 * vertex_num, ERR_INVALID_DATA);

0 commit comments

Comments
 (0)