From 70b46b0dd882f44309354a64a4dd19deacaca7de Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 31 Mar 2026 19:10:13 -0500 Subject: [PATCH] header: bug: input element indices are global, not per- This was never triggered in previous commits because all prior tests were with Collada files that only used a single vertex format for the entire file (therefore index=0 is always correct). 3ds Max CAT bones are (very appropriately) exported with no texture coordinates, and therefore require a different vertex attribute declaration with a different stride. Coincidentally, this meant that CAT meshes were rendered with the correct vertex attribute, while all (e.g: non-CAT, containing texture coordinates) meshes incorrectly used the CAT vertex attributes, which resulted in garbled nonsensical renderings with meaningless garbage vertex data. This bug alone consumed at least 4 hours of focused debugging time. Because the Collada file that triggered this also contained a complex skeleton, I was originally convinced that the "vertex transformation result is garbage" bug was caused by something more directly related to the animation/joint transform calculation. --- collada/header.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/collada/header.py b/collada/header.py index 5101640..6fed3af 100644 --- a/collada/header.py +++ b/collada/header.py @@ -132,13 +132,14 @@ def input_elements_key_name(key): return "_".join(map(str, chain.from_iterable(key))).lower() def render_input_elements(state, collada, geometry_name, offset_tables): - for i, offset_table in enumerate(offset_tables): + for offset_table in offset_tables: key = tuple(offset_table_key(offset_table)) key_name = input_elements_key_name(key) if key_name in state.emitted_input_elements_arrays: assert state.emitted_input_elements_arrays[key_name][1] == key continue - state.emitted_input_elements_arrays[key_name] = (i, key) + index = len(state.emitted_input_elements_arrays) + state.emitted_input_elements_arrays[key_name] = (index, key) yield from lang_header.render_input_elements(key_name, key) @@ -595,7 +596,7 @@ def render_library_materials(state, collada): def render_input_elements_list(state): def items(): - for key_name, (index, key) in state.emitted_input_elements_arrays.items(): + for key_name, (index, key) in sorted(state.emitted_input_elements_arrays.items(), key=lambda k_v: k_v[1][0]): elements_count = len(key) yield key_name, elements_count yield from lang_header.render_input_elements_list(items())