header: bug: input element indices are global, not per-<triangles>

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.
This commit is contained in:
Zack Buhman 2026-03-31 19:10:13 -05:00
parent 58b9c254f2
commit 70b46b0dd8

View File

@ -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())