From b052718d7e30a46c831aa8dfc8d935bbdda0b2e5 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 26 Jan 2026 21:19:53 -0600 Subject: [PATCH] collada/header: reference node transforms by index rather than by type --- collada/header.py | 29 ++++++++++++++++---------- include/collada_types.hpp | 2 +- include/scenes/curve_interpolation.hpp | 16 +++++++------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/collada/header.py b/collada/header.py index 98ae9b3..6425126 100644 --- a/collada/header.py +++ b/collada/header.py @@ -549,15 +549,20 @@ target_attributes = { "A", "ANGLE", "B", "G", "P", "Q", "R", "S", "T", "TIME", "U", "V", "W", "X", "Y", "Z" } -def render_transform_type(transformation_element): - return { - types.Lookat: "LOOKAT", - types.Matrix: "MATRIX", - types.Rotate: "ROTATE", - types.Scale: "SCALE", - types.Skew: "SKEW", - types.Translate: "TRANSLATE", - }[type(transformation_element)] +def find_transform_index_in_node(node, transform): + for i, node_transform in enumerate(node.transformation_elements): + if node_transform is transform: + return i + assert False, (node, transform) + +def transform_sid_lookup(node, sid): + transform_types = { + types.Lookat, types.Matrix, types.Rotate, + types.Scale, types.Skew, types.Translate + } + transform = node.sid_lookup[sid] + assert type(transform) in transform_types, transform + return transform def render_channel(state, collada, channel): sampler = collada.lookup(channel.source, types.Sampler) @@ -574,7 +579,9 @@ def render_channel(state, collada, channel): node = collada.lookup(f"#{node_id}", types.Node) node_name_id = get_node_name_id(node) node_name = sanitize_name(state, node_name_id, node) - transformation_element = node.sid_lookup[node_transform_sid] + + transform = transform_sid_lookup(node, node_transform_sid) + transform_index = find_transform_index_in_node(node, transform) target_name = sanitize_name(state, channel.target, channel, allow_slash=True) assert target_name not in state.node_animation_channels[node.id] @@ -582,7 +589,7 @@ def render_channel(state, collada, channel): yield f"channel const node_channel_{target_name} = {{" yield f".source_sampler = &sampler_{sampler_name}," - yield f".target_transform_type = transform_type::{render_transform_type(transformation_element)}," + yield f".target_transform_index = {transform_index}," yield f".target_attribute = target_attribute::{target_attribute}," yield "};" diff --git a/include/collada_types.hpp b/include/collada_types.hpp index 3fd3d08..a1a23bf 100644 --- a/include/collada_types.hpp +++ b/include/collada_types.hpp @@ -257,7 +257,7 @@ namespace collada { struct channel { sampler const * const source_sampler; int const target_node_index; // an index into the nodes array - transform_type const target_transform_type; + int const target_transform_index; target_attribute const target_attribute; }; diff --git a/include/scenes/curve_interpolation.hpp b/include/scenes/curve_interpolation.hpp index 2da5128..09691e8 100644 --- a/include/scenes/curve_interpolation.hpp +++ b/include/scenes/curve_interpolation.hpp @@ -132,13 +132,13 @@ sampler const sampler_node_cube_translation_y_sampler = { channel const node_channel_node_cube_translation_x = { .source_sampler = &sampler_node_cube_translation_x_sampler, - .target_transform_type = transform_type::TRANSLATE, + .target_transform_index = 0, .target_attribute = target_attribute::X, }; channel const node_channel_node_cube_translation_y = { .source_sampler = &sampler_node_cube_translation_y_sampler, - .target_transform_type = transform_type::TRANSLATE, + .target_transform_index = 0, .target_attribute = target_attribute::Y, }; @@ -543,7 +543,7 @@ node const * const node_children_node_cube = { transform const transforms_node_cube[] = { { .type = transform_type::TRANSLATE, - .translate = {10.0f, 0.0f, 0.0f}, + .translate = {10.0f, -1.14258e-07f, 0.0f}, }, }; @@ -552,6 +552,10 @@ instance_material const instance_materials_node_cube_0[] = { .element_index = 1, // an index into mesh.triangles .material = &material_material__15_material, }, + { + .element_index = 0, // an index into mesh.triangles + .material = &material_material__16_material, + }, { .element_index = 5, // an index into mesh.triangles .material = &material_material__17_material, @@ -564,10 +568,6 @@ instance_material const instance_materials_node_cube_0[] = { .element_index = 2, // an index into mesh.triangles .material = &material_material__19_material, }, - { - .element_index = 0, // an index into mesh.triangles - .material = &material_material__16_material, - }, { .element_index = 4, // an index into mesh.triangles .material = &material_material__20_material, @@ -583,8 +583,8 @@ instance_geometry const instance_geometries_node_cube[] = { }; channel const * const node_channels_node_cube[] = { - &node_channel_node_cube_translation_x, &node_channel_node_cube_translation_y, + &node_channel_node_cube_translation_x, }; node const node_node_cube = {