From 683115e0c1fe36431ebd0862a4a8b62ce17e8038 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 27 Jan 2026 21:53:50 -0600 Subject: [PATCH] collada: implement animated rotate and scale This also improves the correctness of channel source interpretation. --- Makefile | 9 +- collada/header.py | 70 +- collada/main.py | 19 +- include/collada_scene.hpp | 4 +- include/collada_types.hpp | 5 +- include/scenes/curve_interpolation.hpp | 699 +--------- .../curve_interpolation.DAE | 392 +++++- .../curve_interpolation.idx | Bin 528 -> 3888 bytes .../curve_interpolation.max | Bin 249856 -> 290816 bytes .../curve_interpolation.vtx | Bin 2160 -> 11628 bytes src/collada_scene.cpp | 155 ++- src/main.cpp | 2 +- src/scenes/curve_interpolation.cpp | 1172 +++++++++++++++++ 13 files changed, 1742 insertions(+), 785 deletions(-) create mode 100644 src/scenes/curve_interpolation.cpp diff --git a/Makefile b/Makefile index 1b1b4f1..68a43c8 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,11 @@ SHADERS = \ $(BUILD_TYPE)/effect/collada.fxo \ $(BUILD_TYPE)/effect/collada_scene.fxo -$(BUILD_TYPE)/%.res: %.rc $(SHADERS) +BUFFERS = \ + models/curve_interpolation/curve_interpolation.vtx \ + models/curve_interpolation/curve_interpolation.idx + +$(BUILD_TYPE)/%.res: %.rc $(SHADERS) $(BUFFERS) @mkdir -p $(@D) $(WINDRES) -O coff -I$(BUILD_TYPE)/effect -o $@ $< @@ -67,7 +71,8 @@ OBJS = \ $(BUILD_TYPE)/render_state.obj \ $(BUILD_TYPE)/input.obj \ $(BUILD_TYPE)/collada.obj \ - $(BUILD_TYPE)/collada_scene.obj + $(BUILD_TYPE)/collada_scene.obj \ + $(BUILD_TYPE)/scenes/curve_interpolation.obj $(BUILD_TYPE)/d3d10.exe: $(OBJS) @mkdir -p $(@D) diff --git a/collada/header.py b/collada/header.py index 56a8281..27cc51e 100644 --- a/collada/header.py +++ b/collada/header.py @@ -475,8 +475,10 @@ def render_input_elements_list(state): yield "}," yield "};" -def render_descriptor(): - yield "descriptor const descriptor = {" +def render_descriptor(namespace): + yield f"extern collada::descriptor const descriptor;" + yield "" + yield "collada::descriptor const descriptor = {" yield ".nodes = nodes," yield ".nodes_count = (sizeof (nodes)) / (sizeof (nodes[0]))," yield "" @@ -494,18 +496,6 @@ def render_animation_children(state, collada, animation_name, animations): yield "&animation_{animation_name}," yield "};" -def array_c_type(accessor): - if accessor.params[0].name == "INTERPOLATION": - return "interpolation" - assert all(param.type == "float" for param in accessor.params) - if accessor.stride == 1: - return "float" - elif accessor.stride in {2, 3, 4}: - assert list(param.name for param in accessor.params) == ["X", "Y", "Z", "W"][:accessor.stride], accessor.params - return f"float{accessor.stride}" - else: - assert False, accessor.stride - def render_array(state, collada, accessor, array): array_name = sanitize_name(state, array.id, array) # render the array @@ -518,30 +508,26 @@ def render_array(state, collada, accessor, array): assert name in {"BEZIER", "LINEAR"}, name yield f"interpolation::{name}," yield "};" - return "interpolation" elif type(array) is types.FloatArray: - c_type = array_c_type(accessor) - yield f"{c_type} const array_{array_name}[] = {{" + yield f"float const array_{array_name}[] = {{" it = iter(array.floats) for i in range(accessor.count): vector = ", ".join(f"{float(f)}f" for f in islice(it, accessor.stride)) - if accessor.stride == 1: - yield f"{vector}," - else: - yield f"{{ {vector} }}," + yield f"{vector}," yield "};" else: assert False, type(array) def render_source(state, collada, field_name, source): array_name = sanitize_name(state, source.array_element.id, source.array_element) - c_type = array_c_type(source.technique_common.accessor) + c_type = "interpolation" if type(source.array_element) is types.NameArray else "float" source_name = sanitize_name(state, source.id, source) #yield f"source const source_{source_name} = {{" yield f"// {source_name}" yield f".{field_name} = {{" yield f".{c_type}_array = array_{array_name}," yield f".count = {source.technique_common.accessor.count}," + yield f".stride = {source.technique_common.accessor.stride}," yield "}," def render_sampler(state, collada, sampler): @@ -549,13 +535,32 @@ def render_sampler(state, collada, sampler): enumerate(["INPUT", "OUTPUT", "IN_TANGENT", "OUT_TANGENT", "INTERPOLATION"])) inputs = sorted((input for input in sampler.inputs if input.semantic in order), key=lambda input: order[input.semantic]) + inputs_semantics = [input.semantic for input in inputs] + assert len(inputs_semantics) == len(set(inputs_semantics)) + assert "INPUT" in inputs_semantics + assert "OUTPUT" in inputs_semantics + assert "INTERPOLATION" in inputs_semantics + + # sampler validation + counts = set() + for input in inputs: + source = collada.lookup(input.source, types.SourceCore) + if input.semantic == "INTERPOLATION": + nonlinear_interpolation_params = [e for e in source.array_element.names if e != "LINEAR"] + if nonlinear_interpolation_params: + assert "IN_TANGENT" in inputs_semantics + assert "OUT_TANGENT" in inputs_semantics + counts.add(source.technique_common.accessor.count) + assert len(counts) == 1 # render the source arrays first for input in inputs: assert type(input) is types.InputUnshared source = collada.lookup(input.source, types.SourceCore) + yield from render_array(state, collada, source.technique_common.accessor, source.array_element) + # render the sampler sampler_name = sanitize_name(state, sampler.id, sampler) yield f"sampler const sampler_{sampler_name} = {{" for input in inputs: @@ -565,7 +570,7 @@ def render_sampler(state, collada, sampler): yield "};" target_attributes = { - "A", "ANGLE", "B", "G", "P", "Q", "R", "S", "T", "TIME", "U", "V", "W", "X", "Y", "Z" + "A", "ANGLE", "B", "G", "P", "Q", "R", "S", "T", "TIME", "U", "V", "W", "X", "Y", "Z", "ALL" } def find_transform_index_in_node(node, transform): @@ -588,11 +593,14 @@ def render_channel(state, collada, channel): sampler_name = sanitize_name(state, sampler.id, sampler) assert '/' in channel.target, channel.target - assert '.' in channel.target, channel.target assert "(" not in channel.target, channel.target node_id, rest = channel.target.split("/") - node_transform_sid, target_attribute = rest.split(".") + if '.' in rest: + node_transform_sid, target_attribute = rest.split(".") + else: + node_transform_sid = rest + target_attribute = 'ALL' assert target_attribute in target_attributes node = collada.lookup(f"#{node_id}", types.Node) @@ -659,10 +667,20 @@ def render_all(collada, namespace): # root elements render(render_library_visual_scenes(state, collada)) render(render_input_elements_list(state)) - render(render_descriptor()) + render(render_descriptor(namespace)) render(render_end_of_namespace()) return state, out +def render_hpp(namespace): + yield f"namespace {namespace} {{" + yield "extern collada::descriptor const descriptor;" + yield "}" + +def render_all_hpp(namespace): + render, out = renderer() + render(render_hpp(namespace)) + return out + if __name__ == "__main__": import sys collada = parse.parse_collada_file(sys.argv[1]) diff --git a/collada/main.py b/collada/main.py index fd95b5e..058c46e 100644 --- a/collada/main.py +++ b/collada/main.py @@ -7,15 +7,16 @@ from collada import header def usage(): name = sys.argv[0] print("usage:") - print(f" {name} [input_collada.dae] [output_header.hpp] [output_vertex.vtx] [output_vertex.idx]") + print(f" {name} [input_collada.dae] [output_source.cpp] [output_header.hpp] [output_vertex.vtx] [output_vertex.idx]") sys.exit(1) def main(): try: input_collada = sys.argv[1] - output_header = sys.argv[2] - output_vertex = sys.argv[3] - output_index = sys.argv[4] + output_source = sys.argv[2] + output_header = sys.argv[3] + output_vertex = sys.argv[4] + output_index = sys.argv[5] assert input_collada.lower().endswith(".dae") assert output_header.lower().endswith(".hpp") assert output_vertex.lower().endswith(".vtx") @@ -25,10 +26,16 @@ def main(): collada = parse.parse_collada_file(input_collada) namespace = path.splitext(path.split(input_collada)[1])[0] - state, out = header.render_all(collada, namespace) + state, out_source = header.render_all(collada, namespace) + out_header = header.render_all_hpp(namespace) + + with open(output_source, 'wb') as f: + source_buf = out_source.getvalue() + assert "\r\n" in source_buf + f.write(source_buf.encode('utf-8')) with open(output_header, 'wb') as f: - header_buf = out.getvalue() + header_buf = out_header.getvalue() assert "\r\n" in header_buf f.write(header_buf.encode('utf-8')) diff --git a/include/collada_scene.hpp b/include/collada_scene.hpp index b3e46c2..b3b4b75 100644 --- a/include/collada_scene.hpp +++ b/include/collada_scene.hpp @@ -15,9 +15,7 @@ namespace collada_scene { union { lookat lookat; XMMATRIX matrix; - XMVECTOR rotate; - XMVECTOR scale; - XMVECTOR translate; + XMVECTOR vector; }; collada::transform_type type; }; diff --git a/include/collada_types.hpp b/include/collada_types.hpp index 071078d..ee8cf9d 100644 --- a/include/collada_types.hpp +++ b/include/collada_types.hpp @@ -220,12 +220,10 @@ namespace collada { struct source { union { float const * const float_array; - float2 const * const float2_array; - float3 const * const float3_array; - float4 const * const float4_array; enum interpolation const * const interpolation_array; }; int const count; + int const stride; }; struct sampler { @@ -253,6 +251,7 @@ namespace collada { X, // first cartesian coordinate Y, // second cartesian coordinate Z, // third cartesian coordinate + ALL, }; struct channel { diff --git a/include/scenes/curve_interpolation.hpp b/include/scenes/curve_interpolation.hpp index d4bae77..dc8f7aa 100644 --- a/include/scenes/curve_interpolation.hpp +++ b/include/scenes/curve_interpolation.hpp @@ -1,700 +1,3 @@ -#include "collada_types.hpp" - namespace curve_interpolation { - -using namespace collada; - -float const array_node_cube_translation_x_input_array[] = { - 0.0f, - 1.666667f, - 3.333333f, - 5.0f, -}; - -float const array_node_cube_translation_x_output_array[] = { - 10.0f, - -10.0f, - 10.0f, - -10.0f, -}; - -float2 const array_node_cube_translation_x_intangent_array[] = { - { -0.3332306f, 10.0f }, - { 1.111167f, -10.0f }, - { 2.778333f, 10.0f }, - { 4.4445f, -9.219337f }, -}; - -float2 const array_node_cube_translation_x_outtangent_array[] = { - { 0.5555f, 10.0f }, - { 2.222167f, -10.0f }, - { 3.888333f, 10.0f }, - { 4.000208f, -8.594958f }, -}; - -enum interpolation const array_node_cube_translation_x_interpolation_array[] = { - interpolation::BEZIER, - interpolation::BEZIER, - interpolation::BEZIER, - interpolation::BEZIER, -}; - -sampler const sampler_node_cube_translation_x_sampler = { - // node_cube_translation_x_input - .input = { - .float_array = array_node_cube_translation_x_input_array, - .count = 4, - }, - // node_cube_translation_x_output - .output = { - .float_array = array_node_cube_translation_x_output_array, - .count = 4, - }, - // node_cube_translation_x_intangent - .in_tangent = { - .float2_array = array_node_cube_translation_x_intangent_array, - .count = 4, - }, - // node_cube_translation_x_outtangent - .out_tangent = { - .float2_array = array_node_cube_translation_x_outtangent_array, - .count = 4, - }, - // node_cube_translation_x_interpolation - .interpolation = { - .interpolation_array = array_node_cube_translation_x_interpolation_array, - .count = 4, - }, -}; - -float const array_node_cube_translation_y_input_array[] = { - -0.8333334f, - 0.8333334f, - 2.5f, - 4.166667f, -}; - -float const array_node_cube_translation_y_output_array[] = { - -10.05776f, - 10.05852f, - -9.941484f, - 10.05852f, -}; - -float2 const array_node_cube_translation_y_intangent_array[] = { - { -1.166264f, -10.05776f }, - { 0.2778334f, 10.05852f }, - { 1.9445f, -9.941484f }, - { 3.611667f, 10.05852f }, -}; - -float2 const array_node_cube_translation_y_outtangent_array[] = { - { -0.2783333f, -10.05776f }, - { 1.388833f, 10.05852f }, - { 3.0555f, -9.941484f }, - { 4.499598f, 10.05852f }, -}; - -enum interpolation const array_node_cube_translation_y_interpolation_array[] = { - interpolation::BEZIER, - interpolation::BEZIER, - interpolation::BEZIER, - interpolation::BEZIER, -}; - -sampler const sampler_node_cube_translation_y_sampler = { - // node_cube_translation_y_input - .input = { - .float_array = array_node_cube_translation_y_input_array, - .count = 4, - }, - // node_cube_translation_y_output - .output = { - .float_array = array_node_cube_translation_y_output_array, - .count = 4, - }, - // node_cube_translation_y_intangent - .in_tangent = { - .float2_array = array_node_cube_translation_y_intangent_array, - .count = 4, - }, - // node_cube_translation_y_outtangent - .out_tangent = { - .float2_array = array_node_cube_translation_y_outtangent_array, - .count = 4, - }, - // node_cube_translation_y_interpolation - .interpolation = { - .interpolation_array = array_node_cube_translation_y_interpolation_array, - .count = 4, - }, -}; - -channel const node_channel_node_cube_translation_x = { - .source_sampler = &sampler_node_cube_translation_x_sampler, - .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_index = 0, - .target_attribute = target_attribute::Y, -}; - -effect const effect_material__15 = { - .type = effect_type::BLINN, - .blinn = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .ambient = { - .color = {0.6705883f, 0.5843138f, 1.0f, 1.0f}, - }, - .diffuse = { - .color = {0.6705883f, 0.5843138f, 1.0f, 1.0f}, - }, - .specular = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -effect const effect_material__16 = { - .type = effect_type::BLINN, - .blinn = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .ambient = { - .color = {0.5803922f, 1.0f, 0.9647059f, 1.0f}, - }, - .diffuse = { - .color = {0.5803922f, 1.0f, 0.9647059f, 1.0f}, - }, - .specular = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -effect const effect_material__17 = { - .type = effect_type::BLINN, - .blinn = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .ambient = { - .color = {0.6509804f, 1.0f, 0.5803922f, 1.0f}, - }, - .diffuse = { - .color = {0.6509804f, 1.0f, 0.5803922f, 1.0f}, - }, - .specular = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -effect const effect_material__18 = { - .type = effect_type::BLINN, - .blinn = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .ambient = { - .color = {0.9333334f, 1.0f, 0.5647059f, 1.0f}, - }, - .diffuse = { - .color = {0.9333334f, 1.0f, 0.5647059f, 1.0f}, - }, - .specular = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -effect const effect_material__19 = { - .type = effect_type::BLINN, - .blinn = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .ambient = { - .color = {1.0f, 0.7686275f, 0.5803922f, 1.0f}, - }, - .diffuse = { - .color = {1.0f, 0.7686275f, 0.5803922f, 1.0f}, - }, - .specular = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -effect const effect_material__20 = { - .type = effect_type::BLINN, - .blinn = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .ambient = { - .color = {1.0f, 0.5803922f, 0.5803922f, 1.0f}, - }, - .diffuse = { - .color = {1.0f, 0.5803922f, 0.5803922f, 1.0f}, - }, - .specular = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -effect const effect_coloreffectr229g154b215 = { - .type = effect_type::PHONG, - .phong = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 0.0f}, - }, - .ambient = { - .color = {0.8980392f, 0.6039216f, 0.8431373f, 1.0f}, - }, - .diffuse = { - .color = {0.8980392f, 0.6039216f, 0.8431373f, 1.0f}, - }, - .specular = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -effect const effect_coloreffectr28g149b177 = { - .type = effect_type::PHONG, - .phong = { - .emission = { - .color = {0.0f, 0.0f, 0.0f, 0.0f}, - }, - .ambient = { - .color = {0.1098039f, 0.5843137f, 0.6941176f, 1.0f}, - }, - .diffuse = { - .color = {0.1098039f, 0.5843137f, 0.6941176f, 1.0f}, - }, - .specular = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .shininess = 10.0f, - .reflective = { - .color = {0.0f, 0.0f, 0.0f, 1.0f}, - }, - .reflectivity = 0.0f, - .transparent = { - .color = {1.0f, 1.0f, 1.0f, 1.0f}, - }, - .transparency = 1.0f, - .index_of_refraction = 0.0f, - } -}; - -material const material_coloreffectr229g154b215_material = { - .effect = &effect_coloreffectr229g154b215, -}; - -material const material_coloreffectr28g149b177_material = { - .effect = &effect_coloreffectr28g149b177, -}; - -material const material_material__15_material = { - .effect = &effect_material__15, -}; - -material const material_material__16_material = { - .effect = &effect_material__16, -}; - -material const material_material__17_material = { - .effect = &effect_material__17, -}; - -material const material_material__18_material = { - .effect = &effect_material__18, -}; - -material const material_material__19_material = { - .effect = &effect_material__19, -}; - -material const material_material__20_material = { - .effect = &effect_material__20, -}; - -input_element const input_elements_position_0_3_normal_0_3_texcoord_0_3[] = { - { - .semantic = "POSITION", - .semantic_index = 0, - .format = input_format::FLOAT3, - }, - { - .semantic = "NORMAL", - .semantic_index = 0, - .format = input_format::FLOAT3, - }, - { - .semantic = "TEXCOORD", - .semantic_index = 0, - .format = input_format::FLOAT3, - }, -}; - -triangles const triangles_geom_cube[] = { - { - .count = 2, // triangles - .index_offset = 0, // indices - .inputs_index = 0, // index into inputs_list - }, - { - .count = 2, // triangles - .index_offset = 6, // indices - .inputs_index = 0, // index into inputs_list - }, - { - .count = 2, // triangles - .index_offset = 12, // indices - .inputs_index = 0, // index into inputs_list - }, - { - .count = 2, // triangles - .index_offset = 18, // indices - .inputs_index = 0, // index into inputs_list - }, - { - .count = 2, // triangles - .index_offset = 24, // indices - .inputs_index = 0, // index into inputs_list - }, - { - .count = 2, // triangles - .index_offset = 30, // indices - .inputs_index = 0, // index into inputs_list - }, -}; - -geometry const geometry_geom_cube = { - .mesh = { - .triangles = triangles_geom_cube, - .triangles_count = 6, - - .vertex_buffer_offset = 0, - .vertex_buffer_size = 864, - - .index_buffer_offset = 0, - .index_buffer_size = 144, - } -}; - -triangles const triangles_geom_cylinder001[] = { - { - .count = 30, // triangles - .index_offset = 0, // indices - .inputs_index = 0, // index into inputs_list - }, -}; - -geometry const geometry_geom_cylinder001 = { - .mesh = { - .triangles = triangles_geom_cylinder001, - .triangles_count = 1, - - .vertex_buffer_offset = 864, - .vertex_buffer_size = 1152, - - .index_buffer_offset = 144, - .index_buffer_size = 360, - } -}; - -triangles const triangles_geom_plane001[] = { - { - .count = 2, // triangles - .index_offset = 0, // indices - .inputs_index = 0, // index into inputs_list - }, -}; - -geometry const geometry_geom_plane001 = { - .mesh = { - .triangles = triangles_geom_plane001, - .triangles_count = 1, - - .vertex_buffer_offset = 2016, - .vertex_buffer_size = 144, - - .index_buffer_offset = 504, - .index_buffer_size = 24, - } -}; - -geometry const * const geometries[] = { - &geometry_geom_cube, - &geometry_geom_cylinder001, - &geometry_geom_plane001, -}; - -transform const transforms_node_environmentambientlight[] = { -}; - -instance_geometry const instance_geometries_node_environmentambientlight[] = { -}; - -channel const * const node_channels_node_environmentambientlight[] = {}; - -node const node_node_environmentambientlight = { - .parent_index = -1, - - .type = node_type::NODE, - - .transforms = transforms_node_environmentambientlight, - .transforms_count = 0, - - .instance_geometries = instance_geometries_node_environmentambientlight, - .instance_geometries_count = 0, - - .channels = node_channels_node_environmentambientlight, - .channels_count = 0, -}; - -transform const transforms_node_cube[] = { - { - .type = transform_type::TRANSLATE, - .translate = {10.0f, -1.14258e-07f, 0.0f}, - }, -}; - -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, - }, - { - .element_index = 3, // an index into mesh.triangles - .material = &material_material__18_material, - }, - { - .element_index = 2, // an index into mesh.triangles - .material = &material_material__19_material, - }, - { - .element_index = 4, // an index into mesh.triangles - .material = &material_material__20_material, - }, -}; - -instance_geometry const instance_geometries_node_cube[] = { - { - .geometry = &geometry_geom_cube, - .instance_materials = instance_materials_node_cube_0, - .instance_materials_count = 6, - }, -}; - -channel const * const node_channels_node_cube[] = { - &node_channel_node_cube_translation_y, - &node_channel_node_cube_translation_x, -}; - -node const node_node_cube = { - .parent_index = -1, - - .type = node_type::NODE, - - .transforms = transforms_node_cube, - .transforms_count = 1, - - .instance_geometries = instance_geometries_node_cube, - .instance_geometries_count = 1, - - .channels = node_channels_node_cube, - .channels_count = 2, -}; - -transform const transforms_node_cylinder001[] = { -}; - -instance_material const instance_materials_node_cylinder001_0[] = { - { - .element_index = 0, // an index into mesh.triangles - .material = &material_coloreffectr229g154b215_material, - }, -}; - -instance_geometry const instance_geometries_node_cylinder001[] = { - { - .geometry = &geometry_geom_cylinder001, - .instance_materials = instance_materials_node_cylinder001_0, - .instance_materials_count = 1, - }, -}; - -channel const * const node_channels_node_cylinder001[] = { -}; - -node const node_node_cylinder001 = { - .parent_index = -1, - - .type = node_type::NODE, - - .transforms = transforms_node_cylinder001, - .transforms_count = 0, - - .instance_geometries = instance_geometries_node_cylinder001, - .instance_geometries_count = 1, - - .channels = node_channels_node_cylinder001, - .channels_count = 0, -}; - -transform const transforms_node_plane001[] = { - { - .type = transform_type::TRANSLATE, - .translate = {0.0f, 0.0f, 0.01f}, - }, - { - .type = transform_type::ROTATE, - .rotate = {0.0f, 0.0f, -1.0f, -44.99999f}, - }, -}; - -instance_material const instance_materials_node_plane001_0[] = { - { - .element_index = 0, // an index into mesh.triangles - .material = &material_coloreffectr28g149b177_material, - }, -}; - -instance_geometry const instance_geometries_node_plane001[] = { - { - .geometry = &geometry_geom_plane001, - .instance_materials = instance_materials_node_plane001_0, - .instance_materials_count = 1, - }, -}; - -channel const * const node_channels_node_plane001[] = { -}; - -node const node_node_plane001 = { - .parent_index = -1, - - .type = node_type::NODE, - - .transforms = transforms_node_plane001, - .transforms_count = 2, - - .instance_geometries = instance_geometries_node_plane001, - .instance_geometries_count = 1, - - .channels = node_channels_node_plane001, - .channels_count = 0, -}; - -node const * const nodes[] = { - &node_node_environmentambientlight, - &node_node_cube, - &node_node_cylinder001, - &node_node_plane001, -}; - -inputs const inputs_list[] = { - { - .elements = input_elements_position_0_3_normal_0_3_texcoord_0_3, - .elements_count = 3, - }, -}; - -descriptor const descriptor = { - .nodes = nodes, - .nodes_count = (sizeof (nodes)) / (sizeof (nodes[0])), - - .inputs_list = inputs_list, - .inputs_list_count = (sizeof (inputs_list)) / (sizeof (inputs_list[0])), -}; - +extern collada::descriptor const descriptor; } diff --git a/models/curve_interpolation/curve_interpolation.DAE b/models/curve_interpolation/curve_interpolation.DAE index 64889c2..446f27d 100755 --- a/models/curve_interpolation/curve_interpolation.DAE +++ b/models/curve_interpolation/curve_interpolation.DAE @@ -6,8 +6,8 @@ OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68 file:///C:/cygwin/home/bilbo/d3d10/models/curve_interpolation/curve_interpolation.max - 2026-01-26T20:45:12 - 2026-01-26T20:45:12 + 2026-01-27T22:01:59 + 2026-01-27T22:01:59 Z_UP @@ -348,6 +348,35 @@ + + + + + + 0.1019608 0.6941176 0.1019608 1 + + + 0.1019608 0.6941176 0.1019608 1 + + + 1 1 1 1 + + + 10 + + + 0 0 0 1 + + + 1 1 1 1 + + + 1 + + + + + @@ -406,14 +435,49 @@ + + + + + + 0.7764706 0.8784314 0.3411765 1 + + + 0.7764706 0.8784314 0.3411765 1 + + + 1 1 1 1 + + + 10 + + + 0 0 0 1 + + + 1 1 1 1 + + + 1 + + + + + + + + + + + @@ -507,6 +571,66 @@ + + + + -1.09278e-7 2.5 0 -1.0635e-7 2.433013 0.25 -9.83506e-8 2.25 0.4330127 -8.74228e-8 2 0.5 -7.64949e-8 1.75 0.4330127 -6.84952e-8 1.566987 0.25 -6.55671e-8 1.5 7.54979e-8 -6.84952e-8 1.566987 -0.2499999 -7.64949e-8 1.75 -0.4330126 -8.74228e-8 2 -0.5 -9.83506e-8 2.25 -0.4330128 -1.0635e-7 2.433012 -0.2500003 1.469463 2.022542 0 1.430089 1.968349 0.25 1.322517 1.820288 0.4330127 1.17557 1.618034 0.5 1.028624 1.41578 0.4330127 0.921052 1.267719 0.25 0.8816779 1.213526 7.54979e-8 0.921052 1.267719 -0.2499999 1.028624 1.41578 -0.4330126 1.17557 1.618034 -0.5 1.322517 1.820288 -0.4330128 1.430089 1.968349 -0.2500003 2.377641 0.7725425 0 2.313933 0.7518423 0.25 2.139877 0.6952882 0.4330127 1.902113 0.618034 0.5 1.664349 0.5407798 0.4330127 1.490294 0.4842257 0.25 1.426585 0.4635255 7.54979e-8 1.490294 0.4842257 -0.2499999 1.664349 0.5407797 -0.4330126 1.902113 0.6180339 -0.5 2.139877 0.6952882 -0.4330128 2.313932 0.7518422 -0.2500003 2.377641 -0.7725425 0 2.313933 -0.7518423 0.25 2.139877 -0.6952882 0.4330127 1.902113 -0.618034 0.5 1.664349 -0.5407798 0.4330127 1.490294 -0.4842257 0.25 1.426585 -0.4635255 7.54979e-8 1.490294 -0.4842257 -0.2499999 1.664349 -0.5407797 -0.4330126 1.902113 -0.6180339 -0.5 2.139877 -0.6952882 -0.4330128 2.313932 -0.7518422 -0.2500003 1.469463 -2.022542 0 1.430089 -1.968349 0.25 1.322517 -1.820288 0.4330127 1.17557 -1.618034 0.5 1.028624 -1.41578 0.4330127 0.921052 -1.267719 0.25 0.8816779 -1.213526 7.54979e-8 0.921052 -1.267719 -0.2499999 1.028624 -1.41578 -0.4330126 1.17557 -1.618034 -0.5 1.322517 -1.820288 -0.4330128 1.430089 -1.968349 -0.2500003 -1.09278e-7 -2.5 0 -1.0635e-7 -2.433013 0.25 -9.83506e-8 -2.25 0.4330127 -8.74228e-8 -2 0.5 -7.64949e-8 -1.75 0.4330127 -6.84952e-8 -1.566987 0.25 -6.55671e-8 -1.5 7.54979e-8 -6.84952e-8 -1.566987 -0.2499999 -7.64949e-8 -1.75 -0.4330126 -8.74228e-8 -2 -0.5 -9.83506e-8 -2.25 -0.4330128 -1.0635e-7 -2.433012 -0.2500003 -1.469463 -2.022542 0 -1.430089 -1.968349 0.25 -1.322517 -1.820288 0.4330127 -1.17557 -1.618034 0.5 -1.028624 -1.41578 0.4330127 -0.9210519 -1.267719 0.25 -0.8816777 -1.213526 7.54979e-8 -0.9210519 -1.267719 -0.2499999 -1.028624 -1.41578 -0.4330126 -1.17557 -1.618034 -0.5 -1.322517 -1.820288 -0.4330128 -1.430089 -1.968349 -0.2500003 -2.377641 -0.7725426 0 -2.313932 -0.7518424 0.25 -2.139877 -0.6952883 0.4330127 -1.902113 -0.6180341 0.5 -1.664349 -0.5407798 0.4330127 -1.490293 -0.4842257 0.25 -1.426585 -0.4635255 7.54979e-8 -1.490293 -0.4842257 -0.2499999 -1.664349 -0.5407798 -0.4330126 -1.902113 -0.618034 -0.5 -2.139877 -0.6952882 -0.4330128 -2.313932 -0.7518423 -0.2500003 -2.377641 0.7725424 0 -2.313933 0.7518422 0.25 -2.139877 0.6952882 0.4330127 -1.902113 0.6180339 0.5 -1.664349 0.5407797 0.4330127 -1.490294 0.4842257 0.25 -1.426585 0.4635255 7.54979e-8 -1.490294 0.4842257 -0.2499999 -1.664349 0.5407797 -0.4330126 -1.902113 0.6180339 -0.5 -2.139877 0.6952881 -0.4330128 -2.313932 0.7518421 -0.2500003 -1.469464 2.022542 0 -1.430089 1.968348 0.25 -1.322517 1.820288 0.4330127 -1.175571 1.618034 0.5 -1.028625 1.415779 0.4330127 -0.9210523 1.267719 0.25 -0.8816781 1.213525 7.54979e-8 -0.9210523 1.267719 -0.2499999 -1.028624 1.415779 -0.4330126 -1.175571 1.618033 -0.5 -1.322517 1.820288 -0.4330128 -1.430089 1.968348 -0.2500003 + + + + + + + + + + -1.39645e-7 1 -2.71833e-7 0.5159397 0.71013 0.4790842 0.5877851 0.809017 -1.46424e-7 -1.12014e-7 0.8777689 0.4790842 0.3154685 0.4342053 0.8437685 -9.73266e-8 0.5367071 0.8437687 0.03035063 0.04177406 0.9986659 -1.35335e-8 0.05163556 0.9986659 -0.2699911 -0.3716109 0.8882624 4.84062e-8 -0.4593363 0.8882624 -0.5008137 -0.6893111 0.5234843 1.02225e-7 -0.8520353 0.5234844 -0.5877852 -0.809017 1.46912e-8 1.32221e-7 -0.9999999 4.89707e-9 -0.5008138 -0.6893111 -0.5234841 9.24895e-8 -0.8520354 -0.5234841 -0.2699913 -0.3716112 -0.8882623 5.80874e-8 -0.4593366 -0.8882622 0.03035033 0.04177367 -0.998666 -2.46063e-8 0.05163517 -0.998666 0.3154682 0.4342048 -0.8437689 -8.70817e-8 0.5367067 -0.8437688 0.5159394 0.7101299 -0.4790846 -1.22682e-7 0.8777687 -0.4790847 0.8348078 0.2712456 0.4790843 0.9510565 0.3090169 -2.65732e-7 0.5104388 0.1658516 0.8437687 0.04910826 0.01595625 0.998666 -0.4368547 -0.1419427 0.8882625 -0.8103337 -0.2632934 0.5234844 -0.9510565 -0.309017 -9.79413e-9 -0.8103338 -0.2632935 -0.5234841 -0.4368552 -0.1419429 -0.8882623 0.04910788 0.01595613 -0.998666 0.5104386 0.1658515 -0.8437688 0.8348075 0.2712454 -0.4790847 0.8348078 -0.2712456 0.4790842 0.9510565 -0.309017 -3.52501e-7 0.5104389 -0.1658516 0.8437686 0.04910832 -0.01595627 0.9986659 -0.4368547 0.1419427 0.8882625 -0.8103337 0.2632934 0.5234844 -0.9510565 0.309017 2.44853e-8 -0.8103338 0.2632934 -0.5234841 -0.4368552 0.1419429 -0.8882623 0.04910788 -0.01595613 -0.998666 0.5104385 -0.1658515 -0.8437688 0.8348076 -0.2712455 -0.4790847 0.5159396 -0.7101301 0.4790841 0.5877853 -0.809017 -2.11501e-7 0.3154684 -0.4342052 0.8437686 0.03035063 -0.04177404 0.998666 -0.2699911 0.3716109 0.8882624 -0.5008137 0.6893111 0.5234843 -0.5877852 0.809017 9.79413e-9 -0.5008138 0.6893111 -0.5234841 -0.2699913 0.3716112 -0.8882622 0.03035034 -0.04177368 -0.998666 0.3154682 -0.4342048 -0.8437689 0.5159395 -0.7101298 -0.4790846 -6.40082e-8 -0.8777689 0.4790843 -7.59233e-8 -1 -2.38616e-7 -2.3051e-8 -0.536707 0.8437687 2.46063e-9 -0.05163559 0.998666 2.90437e-8 0.4593363 0.8882624 1.46036e-8 0.8520353 0.5234843 9.79413e-9 0.9999999 2.93824e-8 3.40751e-8 0.8520354 -0.5234841 1.69422e-8 0.4593367 -0.8882622 -2.46063e-9 -0.05163516 -0.998666 -3.07347e-8 -0.5367067 -0.8437688 -3.73381e-8 -0.8777686 -0.4790848 -0.5159397 -0.7101299 0.4790842 -0.5877852 -0.8090169 -2.54885e-7 -0.3154685 -0.4342053 0.8437686 -0.03035061 -0.04177405 0.9986659 0.2699912 0.3716109 0.8882624 0.5008138 0.689311 0.5234843 0.5877852 0.8090171 2.93824e-8 0.5008138 0.6893111 -0.5234842 0.2699913 0.3716112 -0.8882622 -0.03035032 -0.04177361 -0.998666 -0.3154683 -0.4342048 -0.8437689 -0.5159395 -0.7101299 -0.4790846 -0.8348078 -0.2712456 0.4790843 -0.9510564 -0.309017 -3.03693e-7 -0.5104389 -0.1658517 0.8437685 -0.04910835 -0.01595627 0.998666 0.4368547 0.1419428 0.8882624 0.8103337 0.2632934 0.5234843 0.9510565 0.3090171 9.79413e-9 0.8103338 0.2632935 -0.5234842 0.4368551 0.1419429 -0.8882622 -0.04910791 -0.01595615 -0.9986661 -0.5104385 -0.1658516 -0.8437688 -0.8348075 -0.2712456 -0.4790848 -0.8348079 0.2712454 0.4790843 -0.9510565 0.3090169 -3.36232e-7 -0.5104389 0.1658516 0.8437685 -0.04910829 0.01595625 0.998666 0.4368548 -0.1419427 0.8882625 0.8103337 -0.2632933 0.5234843 0.9510565 -0.3090169 3.91765e-8 0.8103339 -0.2632934 -0.5234841 0.4368552 -0.1419428 -0.8882623 -0.04910788 0.01595612 -0.998666 -0.5104386 0.1658515 -0.8437688 -0.8348076 0.2712454 -0.4790848 -0.5159396 0.71013 0.4790843 -0.5877853 0.8090169 -2.71155e-7 -0.3154685 0.434205 0.8437687 -0.03035063 0.04177407 0.998666 0.2699911 -0.3716108 0.8882625 0.5008138 -0.6893109 0.5234844 0.5877853 -0.8090169 1.46912e-8 0.500814 -0.6893111 -0.5234841 0.2699914 -0.3716112 -0.8882623 -0.03035034 0.04177367 -0.998666 -0.3154683 0.4342048 -0.8437688 -0.5159395 0.7101298 -0.4790846 + + + + + + + + + + 0 0 0 0.08333334 0 0 0.1666667 0 0 0.25 0 0 0.3333333 0 0 0.4166667 0 0 0.5 0 0 0.5833333 0 0 0.6666667 0 0 0.75 0 0 0.8333333 0 0 0.9166667 0 0 1 0 0 0 0.1 0 0.08333334 0.1 0 0.1666667 0.1 0 0.25 0.1 0 0.3333333 0.1 0 0.4166667 0.1 0 0.5 0.1 0 0.5833333 0.1 0 0.6666667 0.1 0 0.75 0.1 0 0.8333333 0.1 0 0.9166667 0.1 0 1 0.1 0 0 0.2 0 0.08333334 0.2 0 0.1666667 0.2 0 0.25 0.2 0 0.3333333 0.2 0 0.4166667 0.2 0 0.5 0.2 0 0.5833333 0.2 0 0.6666667 0.2 0 0.75 0.2 0 0.8333333 0.2 0 0.9166667 0.2 0 1 0.2 0 0 0.3 0 0.08333334 0.3 0 0.1666667 0.3 0 0.25 0.3 0 0.3333333 0.3 0 0.4166667 0.3 0 0.5 0.3 0 0.5833333 0.3 0 0.6666667 0.3 0 0.75 0.3 0 0.8333333 0.3 0 0.9166667 0.3 0 1 0.3 0 0 0.4 0 0.08333334 0.4 0 0.1666667 0.4 0 0.25 0.4 0 0.3333333 0.4 0 0.4166667 0.4 0 0.5 0.4 0 0.5833333 0.4 0 0.6666667 0.4 0 0.75 0.4 0 0.8333333 0.4 0 0.9166667 0.4 0 1 0.4 0 0 0.5 0 0.08333334 0.5 0 0.1666667 0.5 0 0.25 0.5 0 0.3333333 0.5 0 0.4166667 0.5 0 0.5 0.5 0 0.5833333 0.5 0 0.6666667 0.5 0 0.75 0.5 0 0.8333333 0.5 0 0.9166667 0.5 0 1 0.5 0 0 0.6 0 0.08333334 0.6 0 0.1666667 0.6 0 0.25 0.6 0 0.3333333 0.6 0 0.4166667 0.6 0 0.5 0.6 0 0.5833333 0.6 0 0.6666667 0.6 0 0.75 0.6 0 0.8333333 0.6 0 0.9166667 0.6 0 1 0.6 0 0 0.7 0 0.08333334 0.7 0 0.1666667 0.7 0 0.25 0.7 0 0.3333333 0.7 0 0.4166667 0.7 0 0.5 0.7 0 0.5833333 0.7 0 0.6666667 0.7 0 0.75 0.7 0 0.8333333 0.7 0 0.9166667 0.7 0 1 0.7 0 0 0.8 0 0.08333334 0.8 0 0.1666667 0.8 0 0.25 0.8 0 0.3333333 0.8 0 0.4166667 0.8 0 0.5 0.8 0 0.5833333 0.8 0 0.6666667 0.8 0 0.75 0.8 0 0.8333333 0.8 0 0.9166667 0.8 0 1 0.8 0 0 0.9 0 0.08333334 0.9 0 0.1666667 0.9 0 0.25 0.9 0 0.3333333 0.9 0 0.4166667 0.9 0 0.5 0.9 0 0.5833333 0.9 0 0.6666667 0.9 0 0.75 0.9 0 0.8333333 0.9 0 0.9166667 0.9 0 1 0.9 0 0 1 0 0.08333334 1 0 0.1666667 1 0 0.25 1 0 0.3333333 1 0 0.4166667 1 0 0.5 1 0 0.5833333 1 0 0.6666667 1 0 0.75 1 0 0.8333333 1 0 0.9166667 1 0 1 1 0 + + + + + + + + + + + + + + + +

0 0 0 13 1 14 12 2 13 0 0 0 1 3 1 13 1 14 1 3 1 14 4 15 13 1 14 1 3 1 2 5 2 14 4 15 2 5 2 15 6 16 14 4 15 2 5 2 3 7 3 15 6 16 3 7 3 16 8 17 15 6 16 3 7 3 4 9 4 16 8 17 4 9 4 17 10 18 16 8 17 4 9 4 5 11 5 17 10 18 5 11 5 18 12 19 17 10 18 5 11 5 6 13 6 18 12 19 6 13 6 19 14 20 18 12 19 6 13 6 7 15 7 19 14 20 7 15 7 20 16 21 19 14 20 7 15 7 8 17 8 20 16 21 8 17 8 21 18 22 20 16 21 8 17 8 9 19 9 21 18 22 9 19 9 22 20 23 21 18 22 9 19 9 10 21 10 22 20 23 10 21 10 23 22 24 22 20 23 10 21 10 11 23 11 23 22 24 11 23 11 12 2 25 23 22 24 11 23 11 0 0 12 12 2 25 12 2 13 25 24 27 24 25 26 12 2 13 13 1 14 25 24 27 13 1 14 26 26 28 25 24 27 13 1 14 14 4 15 26 26 28 14 4 15 27 27 29 26 26 28 14 4 15 15 6 16 27 27 29 15 6 16 28 28 30 27 27 29 15 6 16 16 8 17 28 28 30 16 8 17 29 29 31 28 28 30 16 8 17 17 10 18 29 29 31 17 10 18 30 30 32 29 29 31 17 10 18 18 12 19 30 30 32 18 12 19 31 31 33 30 30 32 18 12 19 19 14 20 31 31 33 19 14 20 32 32 34 31 31 33 19 14 20 20 16 21 32 32 34 20 16 21 33 33 35 32 32 34 20 16 21 21 18 22 33 33 35 21 18 22 34 34 36 33 33 35 21 18 22 22 20 23 34 34 36 22 20 23 35 35 37 34 34 36 22 20 23 23 22 24 35 35 37 23 22 24 24 25 38 35 35 37 23 22 24 12 2 25 24 25 38 24 25 26 37 36 40 36 37 39 24 25 26 25 24 27 37 36 40 25 24 27 38 38 41 37 36 40 25 24 27 26 26 28 38 38 41 26 26 28 39 39 42 38 38 41 26 26 28 27 27 29 39 39 42 27 27 29 40 40 43 39 39 42 27 27 29 28 28 30 40 40 43 28 28 30 41 41 44 40 40 43 28 28 30 29 29 31 41 41 44 29 29 31 42 42 45 41 41 44 29 29 31 30 30 32 42 42 45 30 30 32 43 43 46 42 42 45 30 30 32 31 31 33 43 43 46 31 31 33 44 44 47 43 43 46 31 31 33 32 32 34 44 44 47 32 32 34 45 45 48 44 44 47 32 32 34 33 33 35 45 45 48 33 33 35 46 46 49 45 45 48 33 33 35 34 34 36 46 46 49 34 34 36 47 47 50 46 46 49 34 34 36 35 35 37 47 47 50 35 35 37 36 37 51 47 47 50 35 35 37 24 25 38 36 37 51 36 37 39 49 48 53 48 49 52 36 37 39 37 36 40 49 48 53 37 36 40 50 50 54 49 48 53 37 36 40 38 38 41 50 50 54 38 38 41 51 51 55 50 50 54 38 38 41 39 39 42 51 51 55 39 39 42 52 52 56 51 51 55 39 39 42 40 40 43 52 52 56 40 40 43 53 53 57 52 52 56 40 40 43 41 41 44 53 53 57 41 41 44 54 54 58 53 53 57 41 41 44 42 42 45 54 54 58 42 42 45 55 55 59 54 54 58 42 42 45 43 43 46 55 55 59 43 43 46 56 56 60 55 55 59 43 43 46 44 44 47 56 56 60 44 44 47 57 57 61 56 56 60 44 44 47 45 45 48 57 57 61 45 45 48 58 58 62 57 57 61 45 45 48 46 46 49 58 58 62 46 46 49 59 59 63 58 58 62 46 46 49 47 47 50 59 59 63 47 47 50 48 49 64 59 59 63 47 47 50 36 37 51 48 49 64 48 49 52 61 60 66 60 61 65 48 49 52 49 48 53 61 60 66 49 48 53 62 62 67 61 60 66 49 48 53 50 50 54 62 62 67 50 50 54 63 63 68 62 62 67 50 50 54 51 51 55 63 63 68 51 51 55 64 64 69 63 63 68 51 51 55 52 52 56 64 64 69 52 52 56 65 65 70 64 64 69 52 52 56 53 53 57 65 65 70 53 53 57 66 66 71 65 65 70 53 53 57 54 54 58 66 66 71 54 54 58 67 67 72 66 66 71 54 54 58 55 55 59 67 67 72 55 55 59 68 68 73 67 67 72 55 55 59 56 56 60 68 68 73 56 56 60 69 69 74 68 68 73 56 56 60 57 57 61 69 69 74 57 57 61 70 70 75 69 69 74 57 57 61 58 58 62 70 70 75 58 58 62 71 71 76 70 70 75 58 58 62 59 59 63 71 71 76 59 59 63 60 61 77 71 71 76 59 59 63 48 49 64 60 61 77 60 61 65 73 72 79 72 73 78 60 61 65 61 60 66 73 72 79 61 60 66 74 74 80 73 72 79 61 60 66 62 62 67 74 74 80 62 62 67 75 75 81 74 74 80 62 62 67 63 63 68 75 75 81 63 63 68 76 76 82 75 75 81 63 63 68 64 64 69 76 76 82 64 64 69 77 77 83 76 76 82 64 64 69 65 65 70 77 77 83 65 65 70 78 78 84 77 77 83 65 65 70 66 66 71 78 78 84 66 66 71 79 79 85 78 78 84 66 66 71 67 67 72 79 79 85 67 67 72 80 80 86 79 79 85 67 67 72 68 68 73 80 80 86 68 68 73 81 81 87 80 80 86 68 68 73 69 69 74 81 81 87 69 69 74 82 82 88 81 81 87 69 69 74 70 70 75 82 82 88 70 70 75 83 83 89 82 82 88 70 70 75 71 71 76 83 83 89 71 71 76 72 73 90 83 83 89 71 71 76 60 61 77 72 73 90 72 73 78 85 84 92 84 85 91 72 73 78 73 72 79 85 84 92 73 72 79 86 86 93 85 84 92 73 72 79 74 74 80 86 86 93 74 74 80 87 87 94 86 86 93 74 74 80 75 75 81 87 87 94 75 75 81 88 88 95 87 87 94 75 75 81 76 76 82 88 88 95 76 76 82 89 89 96 88 88 95 76 76 82 77 77 83 89 89 96 77 77 83 90 90 97 89 89 96 77 77 83 78 78 84 90 90 97 78 78 84 91 91 98 90 90 97 78 78 84 79 79 85 91 91 98 79 79 85 92 92 99 91 91 98 79 79 85 80 80 86 92 92 99 80 80 86 93 93 100 92 92 99 80 80 86 81 81 87 93 93 100 81 81 87 94 94 101 93 93 100 81 81 87 82 82 88 94 94 101 82 82 88 95 95 102 94 94 101 82 82 88 83 83 89 95 95 102 83 83 89 84 85 103 95 95 102 83 83 89 72 73 90 84 85 103 84 85 91 97 96 105 96 97 104 84 85 91 85 84 92 97 96 105 85 84 92 98 98 106 97 96 105 85 84 92 86 86 93 98 98 106 86 86 93 99 99 107 98 98 106 86 86 93 87 87 94 99 99 107 87 87 94 100 100 108 99 99 107 87 87 94 88 88 95 100 100 108 88 88 95 101 101 109 100 100 108 88 88 95 89 89 96 101 101 109 89 89 96 102 102 110 101 101 109 89 89 96 90 90 97 102 102 110 90 90 97 103 103 111 102 102 110 90 90 97 91 91 98 103 103 111 91 91 98 104 104 112 103 103 111 91 91 98 92 92 99 104 104 112 92 92 99 105 105 113 104 104 112 92 92 99 93 93 100 105 105 113 93 93 100 106 106 114 105 105 113 93 93 100 94 94 101 106 106 114 94 94 101 107 107 115 106 106 114 94 94 101 95 95 102 107 107 115 95 95 102 96 97 116 107 107 115 95 95 102 84 85 103 96 97 116 96 97 104 109 108 118 108 109 117 96 97 104 97 96 105 109 108 118 97 96 105 110 110 119 109 108 118 97 96 105 98 98 106 110 110 119 98 98 106 111 111 120 110 110 119 98 98 106 99 99 107 111 111 120 99 99 107 112 112 121 111 111 120 99 99 107 100 100 108 112 112 121 100 100 108 113 113 122 112 112 121 100 100 108 101 101 109 113 113 122 101 101 109 114 114 123 113 113 122 101 101 109 102 102 110 114 114 123 102 102 110 115 115 124 114 114 123 102 102 110 103 103 111 115 115 124 103 103 111 116 116 125 115 115 124 103 103 111 104 104 112 116 116 125 104 104 112 117 117 126 116 116 125 104 104 112 105 105 113 117 117 126 105 105 113 118 118 127 117 117 126 105 105 113 106 106 114 118 118 127 106 106 114 119 119 128 118 118 127 106 106 114 107 107 115 119 119 128 107 107 115 108 109 129 119 119 128 107 107 115 96 97 116 108 109 129 108 109 117 1 3 131 0 0 130 108 109 117 109 108 118 1 3 131 109 108 118 2 5 132 1 3 131 109 108 118 110 110 119 2 5 132 110 110 119 3 7 133 2 5 132 110 110 119 111 111 120 3 7 133 111 111 120 4 9 134 3 7 133 111 111 120 112 112 121 4 9 134 112 112 121 5 11 135 4 9 134 112 112 121 113 113 122 5 11 135 113 113 122 6 13 136 5 11 135 113 113 122 114 114 123 6 13 136 114 114 123 7 15 137 6 13 136 114 114 123 115 115 124 7 15 137 115 115 124 8 17 138 7 15 137 115 115 124 116 116 125 8 17 138 116 116 125 9 19 139 8 17 138 116 116 125 117 117 126 9 19 139 117 117 126 10 21 140 9 19 139 117 117 126 118 118 127 10 21 140 118 118 127 11 23 141 10 21 140 118 118 127 119 119 128 11 23 141 119 119 128 0 0 142 11 23 141 119 119 128 108 109 129 0 0 142

+
+
+ + + + 2 + 0.5 + 0 + 0 + 10 + 12 + 2 + 0 + 0 + 0 + 1 + + + +
@@ -606,6 +730,49 @@ + + + + 0 0 1.039281 0.929561 0 0.4647805 0.2872501 0.884065 0.4647805 -0.7520307 0.5463822 0.4647805 -0.7520306 -0.5463823 0.4647805 0.2872503 -0.884065 0.4647805 0.5463822 0 0.8840649 0.1688414 0.5196404 0.8840649 -0.4420325 0.3211554 0.8840649 -0.4420325 -0.3211555 0.8840649 0.1688415 -0.5196403 0.8840649 0.7152236 0.5196404 0.5463822 -0.2731912 0.8407957 0.5463822 -0.884065 -6.664e-8 0.5463822 -0.273191 -0.8407958 0.5463822 0.7152236 -0.5196403 0.5463822 0.9884146 0.3211554 0 -3.332e-8 1.039281 0 -0.9884147 0.3211553 0 -0.6108739 -0.8407958 0 0.6108741 -0.8407956 0 0.9884148 -0.3211552 0 0.6108739 0.8407957 0 -0.6108739 0.8407957 0 -0.9884146 -0.3211555 0 1.666e-8 -1.039281 0 + + + + + + + + + + 1.05124e-8 -2.6281e-9 1 0.5257311 1.32646e-8 0.8506508 0.1624598 0.5 0.8506508 0.8944272 5.25619e-8 0.4472137 0.6881909 0.5 0.5257311 0.2763931 0.8506508 0.4472136 -0.4253254 0.3090169 0.8506508 -0.2628656 0.8090169 0.5257311 -0.7236068 0.5257311 0.4472136 -0.4253254 -0.3090171 0.8506507 -0.8506508 -9.01996e-8 0.5257311 -0.7236068 -0.5257311 0.4472137 0.1624599 -0.5 0.8506508 -0.2628654 -0.8090169 0.5257312 0.2763933 -0.8506508 0.4472136 0.6881909 -0.4999999 0.5257311 0.9224887 -0.3159864 0.2217367 0.9224886 0.3159866 0.2217367 0.5855858 0.7796935 0.2217367 -0.01545645 0.9749841 0.2217368 -0.5605768 0.7978637 0.2217367 -0.9320413 0.2865866 0.2217367 -0.9320413 -0.2865868 0.2217367 -0.5605767 -0.7978638 0.2217368 -0.01545633 -0.9749841 0.2217368 0.585586 -0.7796935 0.2217367 + + + + + + + + + + 0.6 1 1.039281 0.5 0.8237918 1.039281 0.7 0.8237918 1.039281 0.5 0.8237918 1.039281 0.5 0.6475836 1.039281 0.6 0.6762082 1.039281 0.5 0.8237918 1.039281 0.6 0.6762082 1.039281 0.7 0.8237918 1.039281 0.7 0.8237918 1.039281 0.6 0.6762082 1.039281 0.7 0.6475836 1.039281 0.8 1 1.039281 0.7 0.8237918 1.039281 0.9 0.8237918 1.039281 0.7 0.8237918 1.039281 0.7 0.6475836 1.039281 0.8 0.6762082 1.039281 0.7 0.8237918 1.039281 0.8 0.6762082 1.039281 0.9 0.8237918 1.039281 0.9 0.8237918 1.039281 0.8 0.6762082 1.039281 0.9 0.6475836 1.039281 7.45058e-9 1 1.039281 -0.1 0.8237918 1.039281 0.1 0.8237918 1.039281 -0.1 0.8237918 1.039281 -0.1 0.6475836 1.039281 3.79455e-8 0.6762082 1.039281 -0.1 0.8237918 1.039281 3.79455e-8 0.6762082 1.039281 0.1 0.8237918 1.039281 0.1 0.8237918 1.039281 3.79455e-8 0.6762082 1.039281 0.1 0.6475836 1.039281 0.2 1 1.039281 0.1 0.8237918 1.039281 0.3 0.8237918 1.039281 0.1 0.8237918 1.039281 0.1 0.6475836 1.039281 0.2 0.6762082 1.039281 0.1 0.8237918 1.039281 0.2 0.6762082 1.039281 0.3 0.8237918 1.039281 0.3 0.8237918 1.039281 0.2 0.6762082 1.039281 0.3 0.6475836 1.039281 0.4 1 1.039281 0.3 0.8237918 1.039281 0.5 0.8237918 1.039281 0.3 0.8237918 1.039281 0.3 0.6475836 1.039281 0.4 0.6762082 1.039281 0.3 0.8237918 1.039281 0.4 0.6762082 1.039281 0.5 0.8237918 1.039281 0.5 0.8237918 1.039281 0.4 0.6762082 1.039281 0.5 0.6475836 1.039281 0.5 0.6475836 1.039281 0.45 0.5 1.039281 0.55 0.5 1.039281 0.7 0.6475836 1.039281 0.65 0.5 1.039281 0.75 0.5 1.039281 0.9 0.6475836 1.039281 0.85 0.5 1.039281 0.95 0.5 1.039281 0.1 0.6475836 1.039281 0.05000002 0.5 1.039281 0.15 0.5 1.039281 0.3 0.6475836 1.039281 0.25 0.5 1.039281 0.3500001 0.5 1.039281 0.65 0.5 1.039281 0.7 0.6475836 1.039281 0.6 0.6762082 1.039281 0.65 0.5 1.039281 0.6 0.6762082 1.039281 0.55 0.5 1.039281 0.55 0.5 1.039281 0.6 0.6762082 1.039281 0.5 0.6475836 1.039281 0.85 0.5 1.039281 0.9 0.6475836 1.039281 0.8 0.6762082 1.039281 0.85 0.5 1.039281 0.8 0.6762082 1.039281 0.75 0.5 1.039281 0.75 0.5 1.039281 0.8 0.6762082 1.039281 0.7 0.6475836 1.039281 0.05000002 0.5 1.039281 0.1 0.6475836 1.039281 3.79455e-8 0.6762082 1.039281 0.05000002 0.5 1.039281 3.79455e-8 0.6762082 1.039281 -0.05000001 0.5 1.039281 -0.05000001 0.5 1.039281 3.79455e-8 0.6762082 1.039281 -0.1 0.6475836 1.039281 0.25 0.5 1.039281 0.3 0.6475836 1.039281 0.2 0.6762082 1.039281 0.25 0.5 1.039281 0.2 0.6762082 1.039281 0.15 0.5 1.039281 0.15 0.5 1.039281 0.2 0.6762082 1.039281 0.1 0.6475836 1.039281 0.45 0.5 1.039281 0.5 0.6475836 1.039281 0.4 0.6762082 1.039281 0.45 0.5 1.039281 0.4 0.6762082 1.039281 0.3500001 0.5 1.039281 0.3500001 0.5 1.039281 0.4 0.6762082 1.039281 0.3 0.6475836 1.039281 + + + + + + + + + + + + + + + +

0 0 0 6 1 1 7 2 2 6 1 3 1 3 4 11 4 5 6 1 6 11 4 7 7 2 8 7 2 9 11 4 10 2 5 11 0 0 12 7 2 13 8 6 14 7 2 15 2 5 16 12 7 17 7 2 18 12 7 19 8 6 20 8 6 21 12 7 22 3 8 23 0 0 24 8 6 25 9 9 26 8 6 27 3 8 28 13 10 29 8 6 30 13 10 31 9 9 32 9 9 33 13 10 34 4 11 35 0 0 36 9 9 37 10 12 38 9 9 39 4 11 40 14 13 41 9 9 42 14 13 43 10 12 44 10 12 45 14 13 46 5 14 47 0 0 48 10 12 49 6 1 50 10 12 51 5 14 52 15 15 53 10 12 54 15 15 55 6 1 56 6 1 57 15 15 58 1 3 59 1 3 60 21 16 61 16 17 62 2 5 63 22 18 64 17 19 65 3 8 66 23 20 67 18 21 68 4 11 69 24 22 70 19 23 71 5 14 72 25 24 73 20 25 74 22 18 75 2 5 76 11 4 77 22 18 78 11 4 79 16 17 80 16 17 81 11 4 82 1 3 83 23 20 84 3 8 85 12 7 86 23 20 87 12 7 88 17 19 89 17 19 90 12 7 91 2 5 92 24 22 93 4 11 94 13 10 95 24 22 96 13 10 97 18 21 98 18 21 99 13 10 100 3 8 101 25 24 102 5 14 103 14 13 104 25 24 105 14 13 106 19 23 107 19 23 108 14 13 109 4 11 110 21 16 111 1 3 112 15 15 113 21 16 114 15 15 115 20 25 116 20 25 117 15 15 118 5 14 119

+
+
+
@@ -629,12 +796,34 @@ + - + + 5 1.14258e-7 2 + 0 0 1 0 + 0 1 0 2.00358e-5 + 1 0 0 0 + 0.5 0.5 0.5 + + + + + + + + + + 1 + 1 + 1 + 1 + + + 1 @@ -680,6 +869,27 @@ + + 0.03164387 -0.03838623 0 + 0 0 0 0 + 1 1 1 + 0 0 0 0 + + + + + + + + + + 1 + 1 + 1 + 1 + + + @@ -768,6 +978,154 @@ + + 0 0.8333334 1.666667 2.5 3.333333 + + + + + + + + 0 -90 -180 -270 -360 + + + + + + + + 0.9997917 0 0.3270486 -89.70257 0.9961964 -179.1937 1.990403 -269.8432 2.6534 -360 + + + + + + + + + 0.6602973 0 1.324714 -90.28867 2.332406 -180.8006 3.004865 -270.1553 2.333542 -360 + + + + + + + + + BEZIER BEZIER BEZIER BEZIER BEZIER + + + + + + + + 0 1.666667 3.333333 + + + + + + + + 1 1 1 1.996525 1.996525 1.996525 1 1 1 + + + + + + + + + + 0.9997917 1 0.9997917 1 0.9997917 1 1.111167 1.996525 1.111167 1.996525 1.111167 1.996525 2.777833 1 2.777833 1 2.777833 1 + + + + + + + + + + + + + 0.5555 1 0.5555 1 0.5555 1 2.222167 1.996525 2.222167 1.996525 2.222167 1.996525 2.333542 1 2.333542 1 2.333542 1 + + + + + + + + + + + + + BEZIER BEZIER BEZIER + + + + + + + + 0 1.666667 3.333333 + + + + + + + + 0 0 0 0 0 0 0 0 0 0 0 0 + + + + + + + + + + + LINEAR LINEAR LINEAR + + + + + + + + 0 1.666667 3.333333 + + + + + + + + 0 0 0 0 0 0 0 0 0 0 0 0 + + + + + + + + + + + LINEAR LINEAR LINEAR + + + + + + @@ -782,8 +1140,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/models/curve_interpolation/curve_interpolation.idx b/models/curve_interpolation/curve_interpolation.idx index f1f1a855c6087d076e0b3f3c16ce03c06f4c405c..5de993b9460148813ee21502014e42b02c9c6011 100644 GIT binary patch literal 3888 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 delta 19586 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 diff --git a/models/curve_interpolation/curve_interpolation.vtx b/models/curve_interpolation/curve_interpolation.vtx index 76208f7089caa7f2277c5754f7c36c12e2877696..5d5454844877e97abe89e4f4bcafbcf058678de9 100644 GIT binary patch literal 11628 zcma)C3vdkSHbnzO(1wY;F>Ac4jAc_kQ>L zAKy9u|L;O97Spld#2+~lxR+3Jg}=l^uW>1u5XbKuz~F8z7r)oMQ+tr7&cSP(AuleY zpAA+ujH!bo250mhKg(%&bi){a7ygbIp7yBcFYkl5Axy{-!N@(~;kDc|9Iz$Vg5l5Q zUMylOyhlLvAciN7C?@*Zd=CuoMeoruoy*kNna$$-+^MLO zD$f|H_6)w+@CfGlDW^*olx6^v@FuMIu4K-xNg)q^$0PS=TU1ufm+Hfk6JDpK>%Bgs zKK1TwHeS6^+}9JHzu$2TKHm^0=0vl9lx!?)t$u1T0ZS~_vFH`}a0EWb)T#AVL-I5F z<*wYk$iyH#1IzbVq*G^Ba6m_7~C_*g)K`|{@`84pZkU^_um`p`+W-wRB>@} z=+AS*Hi73egX#aDk=Z@_e;s0k=Z1rit9AEoF!sj|is|ih2I%(9TdD`g9S?anbY4}G zw(5Yv99;Hs_T}yqbq9+Pp19}a7iITDer~lG;fd&_^PtzKH}%V1wRw?-JRwg+FMaIc zV>_lnFTn_pte=lz>sqXz&R9RW&Bi0HaUqYaA7ZvO+gtJ)*3aD*BRsO^+r$$7t61|L zu;yPL{=L7o__2_O>v=BLGchaQZoYFC*7F}NMtB<{OXe89wWIIqUp3L;LKYZNUf+ z*I{e$Ob3swL&4CWj!?XzGimg0Y%vYI+`; zZvSk#FPaL*YTAGn2_+a?H-Jfa>rgj3y+24V3HNEG(bU$2Bz%r_4SJ=%(4|0nrNP)b zX0+&lI@W8{r=g~(^9EyUrqPr=E-#~BdF?(8Ft$D$9^1dXNdGcCwig(mZEsSM-efSg z@90S1QP`)_ck1v&dWsTF#b@y+(l0#e1%iphrSlQj=Qo+S;GgLQ#+KwKQs@0hoi`ZK zf||YtE!sniNDVib#Sb-;$9q zn&Oth*uInGKK*O6{X5ndw$@U61!H?$lGmSf&K&sRqA{VSg0cP7Xu5xXbr$B0P*cI! z-fc7;^~Jm_%o3rdg0XXg(Ue+ZPEf0-UN)KvMtG=c)r1>41B99iM*N|s4?O=;R)6>- znhGWomquLMrv`BuO$8(Qp{AM5u3=x+vQGtLdv21NzVUF6l9|wAZEeqOLJQMR4F+pN zW2QCv!Az^s-*s*6?P@Ss8yYih61HQUwf17x>iOaGw)O@XtV4}?)o6iv)yKRV?$fnv z0u0tO=CmWQ6;uCOUsZN5_GxYH4KUaj8gr)MxqrxV4|8UysqnNr__)RlX?(`arrw$} zAkvv7om=9&2Dvdc@G!=~S*nO%ni>h{Z_7jZwWA~|txh~XHFp;?Q5X5yjvQGsg z`JtvaAU~ML!hI?j(ZcRiqlN5K!8EP~Yj2Q4)bOM~H*WHSeyTAe`La*5v$Kt+sNu

`9@|e9W+YEE z6^!^pO^e_UW~5M4!7wh&e$0=agt&?j*J?Y53x@f@45@8D)tDi}ekvGhfqB*RQ_M(4 z3)!cFXfXC(R@d9DmF zjNQ(MYCmF6nR|^b=8$tHd7eTJQ|4ZS!E8fK(L2oCt0rS!6-~uwtEtSroYnnnhW5#3 zjS!6RP}8>0jO5yg&b@W~p{AI7xyGV%ufas(;*3=OXx+KjV3?m@-?X#f)UM5KYBrYTB?CX6`jS-0vUQ_X(JhG~XwPrqiZPGnm4l_QsJ9&Pc4i>Yi1> zdkMkV+G4a|?d^_dJ?W={=@!&pa`HVu*>JoEkbNqc%c#Ao_8H&Xhi6!sdj*po)L!r; zJl5Vf@%%1xuV6N#_8zp)=A7%;FXY)=Fv3GkCxD0V0c1uJ3~Mj_p{AqI3!=}|f?-^{ zg7+Jok;oL~3vNEF&1vLTWE&r0_XcFpX=GP=dMoyB*VaWkxcZ)_>O&VC31H z`>X!Dod6Sg575ASn*by49LQ7uolJm{_Z!r-{`-~ybM<#Ab$O_1{r4nw{h_Ay-+=^} zNL&rP-v}_0A8K0v-9>=8`g@50bMJ01bxV?xbJTj#x%H^*RV(puz=IBBcZxpO!ww3o@g-SAXfwsBhTPf+j76@mTxfhg+4_w^r!WijNE-c4ltOz z5EEmIV#w2D`prXjS9LL%ceV^4R6j?OyO_cB*M2?~u@|=U_BWzr~k)OM9reYRh?c8qjGZY-nTeql4#k__!IK}3<48C-S zPf-m0*^afm#OigXv|3jqwkU@Fa8JB$b z+(4ec0LSZgpZ3IB-k72n{n-OwcG>;@1NK%4a+K=NR>U;L){VaK1!p`J6I=)T%wm#J z3~fcP$&tzvV1ir|Yca{_??j8b_hPZkR!ddOwRdFU+)hmJ{E<++zw=~UW4q(%DQeU! zE!Egl1zGWTC-9zXaeB1DymR_C@77i=6fq}$*&F*ZrikIpD;O7^(o0VoTcwx2@%mR! zRZk=*XJ=KPHhgUk^fI>2bjeY)MZWyoS=(a9FZ%pr#_i5NyYRTg<$`gs^~{Z{ymaJ` zu@^4+gU9^!N9@d@#4fs}>J`kYfnF~Dq>n!3&!4f$qh9fMKl1r}L3^BiL@yT}7oY!j z^7np$_mI(R^efAJ&b?em^jY+BvE{G~zQc;xpEuemmpE62^u#p({!% zN*LSH>RYl!FE^jvcwFLY8q>6`j)=YVWLq84OS85xhZ6f$_7`UjQ(IiLcn|fkcdHhf zdVLYpL(Togcj{5Snu^QC=k3^Eh2BGEEj|$JFFiWgUtUzNrfj+JxWwgxaj{ht)I+1! z6G1)H++WOL(|YmW3Ie@c{Bh|`E<7$ivlnn}NdNj@O^qMa!^%)E7h5hoE^)bFTx_}Y zZWl~N+CnuOwT^pnaGxhs)q(Z?x$6s1SO0D10QSCeU|8#jxf7V01M59v4pm-j<^f_{ zdehxgx+(T1@|^!NU0qp|uL4`WL!P%Y+Le%xnCo&Emc96=B2^7r{I?t23Ti?lbv4=x zU`vawi_f;xmGKeA*4j0}EJYhSZK0lPsBOHDw2H1|7wCeO2b zSDG9itsKGs+hTmCKdc+XT!24^;v+QU!W5wdykexY%;xaoJxk7#CYE z>&Ip9xa>ifIm*SB3r}Np<4EO*a@p@L7#CZOt)J)&=~5G1YKzO9;9|>#hwHhidgy|2 evE{OUT>79(O>pVmF1B2FTJM)`uRWK=R1l3 delta 12 TcmaD8^+8}m0`uk?aRF8UCiMih diff --git a/src/collada_scene.cpp b/src/collada_scene.cpp index a4b3a6b..41f5821 100644 --- a/src/collada_scene.cpp +++ b/src/collada_scene.cpp @@ -83,13 +83,13 @@ namespace collada_scene { transform.matrix = XMLoadFloat4x4((XMFLOAT4X4 *)&node->transforms[i].matrix); break; case transform_type::ROTATE: - transform.rotate = XMLoadFloat4((XMFLOAT4 *)&node->transforms[i].rotate); + transform.vector = XMLoadFloat4((XMFLOAT4 *)&node->transforms[i].rotate); break; case transform_type::SCALE: - transform.scale = XMLoadFloat3((XMFLOAT3 *)&node->transforms[i].scale); + transform.vector = XMLoadFloat3((XMFLOAT3*)&node->transforms[i].scale); break; case transform_type::TRANSLATE: - transform.translate = XMLoadFloat3((XMFLOAT3*)&node->transforms[i].translate); + transform.vector = XMLoadFloat3((XMFLOAT3*)&node->transforms[i].translate); break; default: assert(false); @@ -271,12 +271,12 @@ namespace collada_scene { { switch (transform.type) { case transform_type::TRANSLATE: - return XMMatrixTranslationFromVector(transform.translate); + return XMMatrixTranslationFromVector(transform.vector); case transform_type::ROTATE: - return XMMatrixRotationNormal(transform.rotate, - XMConvertToRadians(XMVectorGetW(transform.rotate))); + return XMMatrixRotationNormal(transform.vector, + XMConvertToRadians(XMVectorGetW(transform.vector))); case transform_type::SCALE: - return XMMatrixScalingFromVector(transform.scale); + return XMMatrixScalingFromVector(transform.vector); default: assert(false); break; @@ -360,17 +360,17 @@ namespace collada_scene { return -1; } - static inline float interpolation_value(source const& source, int ix, float t) + static inline float linear_interpolate_iv(source const& source, int frame_ix, float t) { - float prev = source.float_array[ix]; - float next = source.float_array[ix+1]; + float prev = source.float_array[(frame_ix+0) * source.stride]; + float next = source.float_array[(frame_ix+1) * source.stride]; return (t - prev) / (next - prev); } - static inline float linear_interpolate(source const& source, int ix, float iv) + static inline float linear_interpolate_value(source const& source, int frame_ix, int parameter_ix, float iv) { - float prev = source.float_array[ix]; - float next = source.float_array[ix+1]; + float prev = source.float_array[(frame_ix+0) * source.stride + parameter_ix]; + float next = source.float_array[(frame_ix+1) * source.stride + parameter_ix]; return prev + iv * (next - prev); } @@ -425,7 +425,13 @@ namespace collada_scene { assert(false); } - static float bezier_sampler(sampler const * const sampler, int ix, float t) + static inline XMFLOAT2 const * tangent_index(source const& source, int frame_ix, int parameter_ix) + { + int ix = frame_ix * source.stride + parameter_ix * 2; + return (XMFLOAT2 const *)&source.float_array[ix]; + } + + static float bezier_sampler(sampler const * const sampler, int frame_ix, int parameter_ix, float t) { /* P0 is (INPUT[i] , OUTPUT[i]) @@ -433,14 +439,100 @@ namespace collada_scene { C1 (or T1) is (IN_TANGENT[i+1][0], IN_TANGENT[i+1][1]) P1 is (INPUT[i+1], OUTPUT[i+1]) */ - XMVECTOR p0 = XMVectorSet(sampler->input.float_array[ix], sampler->output.float_array[ix], 0, 0); - XMVECTOR c0 = XMLoadFloat2((XMFLOAT2 *)&sampler->out_tangent.float2_array[ix]); - XMVECTOR c1 = XMLoadFloat2((XMFLOAT2 *)&sampler->in_tangent.float2_array[ix+1]); - XMVECTOR p1 = XMVectorSet(sampler->input.float_array[ix+1], sampler->output.float_array[ix+1], 0, 0); + + float frame0_input = sampler->input.float_array[frame_ix+0]; + float frame1_input = sampler->input.float_array[frame_ix+1]; + + float frame0_output = sampler->output.float_array[(frame_ix+0) * sampler->output.stride + parameter_ix]; + float frame1_output = sampler->output.float_array[(frame_ix+1) * sampler->output.stride + parameter_ix]; + + XMVECTOR p0 = XMVectorSet(frame0_input, frame0_output, 0, 0); + XMVECTOR c0 = XMLoadFloat2(tangent_index(sampler->out_tangent, frame_ix + 0, parameter_ix)); + XMVECTOR c1 = XMLoadFloat2(tangent_index(sampler->in_tangent, frame_ix + 1, parameter_ix)); + XMVECTOR p1 = XMVectorSet(frame1_input, frame1_output, 0, 0); return bezier_binary_search(p0, c0, c1, p1, t); } + static void apply_transform_target(transform& transform, + enum target_attribute channel_target_attribute, + float value) + { + switch (transform.type) { + case transform_type::TRANSLATE: __attribute__((fallthrough)); + case transform_type::SCALE: + switch (channel_target_attribute) { + case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return; + case target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return; + case target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return; + default: assert(false); + } + case transform_type::ROTATE: + switch (channel_target_attribute) { + case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return; + case target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return; + case target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return; + case target_attribute::ANGLE: transform.vector = XMVectorSetW(transform.vector, value); return; + default: assert(false); + } + default: + assert(false); + break; + } + } + + static enum target_attribute const rotate_target_attributes[] = { + target_attribute::X, + target_attribute::Y, + target_attribute::Z, + target_attribute::ANGLE, + }; + + static enum target_attribute const translate_scale_target_attributes[] = { + target_attribute::X, + target_attribute::Y, + target_attribute::Z, + }; + + static void animate_channel_segment(channel const& channel, + transform& transform, + int frame_ix, float t) + { + enum target_attribute const * target_attributes = &channel.target_attribute; + int target_attributes_count = 1; + if (channel.target_attribute == target_attribute::ALL) { + switch (transform.type) { + case transform_type::TRANSLATE: __attribute__((fallthrough)); + case transform_type::SCALE: + target_attributes = translate_scale_target_attributes; + target_attributes_count = 3; + break; + case transform_type::ROTATE: + target_attributes = rotate_target_attributes; + target_attributes_count = 4; + break; + default: + assert(false); + break; + } + } + + for (int parameter_ix = 0; parameter_ix < target_attributes_count; parameter_ix++) { + + enum collada::interpolation interpolation = channel.source_sampler->interpolation.interpolation_array[frame_ix]; + + float value; + if (interpolation == interpolation::BEZIER) { + value = bezier_sampler(channel.source_sampler, frame_ix, parameter_ix, t); + } else { + float iv = linear_interpolate_iv(channel.source_sampler->input, frame_ix, t); + value = linear_interpolate_value(channel.source_sampler->output, frame_ix, parameter_ix, iv); + } + + apply_transform_target(transform, target_attributes[parameter_ix], value); + } + } + static void animate_node(node const& node, node_instance& node_instance, float t) { for (int i = 0; i < node.channels_count; i++) { @@ -448,32 +540,9 @@ namespace collada_scene { transform& transform = node_instance.transforms[channel.target_transform_index]; int frame_ix = find_frame_ix(channel.source_sampler->input, t); - if (frame_ix < 0) - continue; // animation is missing a key frame + assert(frame_ix >= 0); // animation is missing a key frame - enum collada::interpolation const * const interpolation = - channel.source_sampler->interpolation.interpolation_array; - - float value; - if (interpolation[frame_ix] == interpolation::BEZIER) { - value = bezier_sampler(channel.source_sampler, frame_ix, t); - } else { - float iv = interpolation_value(channel.source_sampler->input, frame_ix, t); - value = linear_interpolate(channel.source_sampler->output, frame_ix, iv); - } - - switch (transform.type) { - case transform_type::TRANSLATE: - switch (channel.target_attribute) { - case target_attribute::X: transform.translate = XMVectorSetX(transform.translate, value); break; - case target_attribute::Y: transform.translate = XMVectorSetY(transform.translate, value); break; - case target_attribute::Z: transform.translate = XMVectorSetZ(transform.translate, value); break; - default: break; - } - break; - default: - break; - } + animate_channel_segment(channel, transform, frame_ix, t); } } diff --git a/src/main.cpp b/src/main.cpp index bebd4e3..e6273c8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -129,7 +129,7 @@ XMFLOAT4 g_vLightColors[2] = { // -XMVECTOR g_Eye = XMVectorSet(0.0f, -3.0f, 13.0f, 1.0f); +XMVECTOR g_Eye = XMVectorSet(0.0f, -10.0f, 13.0f, 1.0f); XMVECTOR g_At = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); // collada scene state diff --git a/src/scenes/curve_interpolation.cpp b/src/scenes/curve_interpolation.cpp new file mode 100644 index 0000000..b9df8d9 --- /dev/null +++ b/src/scenes/curve_interpolation.cpp @@ -0,0 +1,1172 @@ +#include "collada_types.hpp" + +namespace curve_interpolation { + +using namespace collada; + +float const array_node_cube_translation_x_input_array[] = { + 0.0f, + 1.666667f, + 3.333333f, + 5.0f, +}; + +float const array_node_cube_translation_x_output_array[] = { + 10.0f, + -10.0f, + 10.0f, + -10.0f, +}; + +float const array_node_cube_translation_x_intangent_array[] = { + -0.3332306f, 10.0f, + 1.111167f, -10.0f, + 2.778333f, 10.0f, + 4.4445f, -9.219337f, +}; + +float const array_node_cube_translation_x_outtangent_array[] = { + 0.5555f, 10.0f, + 2.222167f, -10.0f, + 3.888333f, 10.0f, + 4.000208f, -8.594958f, +}; + +enum interpolation const array_node_cube_translation_x_interpolation_array[] = { + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, +}; + +sampler const sampler_node_cube_translation_x_sampler = { + // node_cube_translation_x_input + .input = { + .float_array = array_node_cube_translation_x_input_array, + .count = 4, + .stride = 1, + }, + // node_cube_translation_x_output + .output = { + .float_array = array_node_cube_translation_x_output_array, + .count = 4, + .stride = 1, + }, + // node_cube_translation_x_intangent + .in_tangent = { + .float_array = array_node_cube_translation_x_intangent_array, + .count = 4, + .stride = 2, + }, + // node_cube_translation_x_outtangent + .out_tangent = { + .float_array = array_node_cube_translation_x_outtangent_array, + .count = 4, + .stride = 2, + }, + // node_cube_translation_x_interpolation + .interpolation = { + .interpolation_array = array_node_cube_translation_x_interpolation_array, + .count = 4, + .stride = 1, + }, +}; + +float const array_node_cube_translation_y_input_array[] = { + -0.8333334f, + 0.8333334f, + 2.5f, + 4.166667f, +}; + +float const array_node_cube_translation_y_output_array[] = { + -10.05776f, + 10.05852f, + -9.941484f, + 10.05852f, +}; + +float const array_node_cube_translation_y_intangent_array[] = { + -1.166264f, -10.05776f, + 0.2778334f, 10.05852f, + 1.9445f, -9.941484f, + 3.611667f, 10.05852f, +}; + +float const array_node_cube_translation_y_outtangent_array[] = { + -0.2783333f, -10.05776f, + 1.388833f, 10.05852f, + 3.0555f, -9.941484f, + 4.499598f, 10.05852f, +}; + +enum interpolation const array_node_cube_translation_y_interpolation_array[] = { + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, +}; + +sampler const sampler_node_cube_translation_y_sampler = { + // node_cube_translation_y_input + .input = { + .float_array = array_node_cube_translation_y_input_array, + .count = 4, + .stride = 1, + }, + // node_cube_translation_y_output + .output = { + .float_array = array_node_cube_translation_y_output_array, + .count = 4, + .stride = 1, + }, + // node_cube_translation_y_intangent + .in_tangent = { + .float_array = array_node_cube_translation_y_intangent_array, + .count = 4, + .stride = 2, + }, + // node_cube_translation_y_outtangent + .out_tangent = { + .float_array = array_node_cube_translation_y_outtangent_array, + .count = 4, + .stride = 2, + }, + // node_cube_translation_y_interpolation + .interpolation = { + .interpolation_array = array_node_cube_translation_y_interpolation_array, + .count = 4, + .stride = 1, + }, +}; + +float const array_node_torus001_rotationx_angle_input_array[] = { + 0.0f, + 0.8333334f, + 1.666667f, + 2.5f, + 3.333333f, +}; + +float const array_node_torus001_rotationx_angle_output_array[] = { + 0.0f, + -90.0f, + -180.0f, + -270.0f, + -360.0f, +}; + +float const array_node_torus001_rotationx_angle_intangent_array[] = { + 0.9997917f, 0.0f, + 0.3270486f, -89.70257f, + 0.9961964f, -179.1937f, + 1.990403f, -269.8432f, + 2.6534f, -360.0f, +}; + +float const array_node_torus001_rotationx_angle_outtangent_array[] = { + 0.6602973f, 0.0f, + 1.324714f, -90.28867f, + 2.332406f, -180.8006f, + 3.004865f, -270.1553f, + 2.333542f, -360.0f, +}; + +enum interpolation const array_node_torus001_rotationx_angle_interpolation_array[] = { + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, +}; + +sampler const sampler_node_torus001_rotationx_angle_sampler = { + // node_torus001_rotationx_angle_input + .input = { + .float_array = array_node_torus001_rotationx_angle_input_array, + .count = 5, + .stride = 1, + }, + // node_torus001_rotationx_angle_output + .output = { + .float_array = array_node_torus001_rotationx_angle_output_array, + .count = 5, + .stride = 1, + }, + // node_torus001_rotationx_angle_intangent + .in_tangent = { + .float_array = array_node_torus001_rotationx_angle_intangent_array, + .count = 5, + .stride = 2, + }, + // node_torus001_rotationx_angle_outtangent + .out_tangent = { + .float_array = array_node_torus001_rotationx_angle_outtangent_array, + .count = 5, + .stride = 2, + }, + // node_torus001_rotationx_angle_interpolation + .interpolation = { + .interpolation_array = array_node_torus001_rotationx_angle_interpolation_array, + .count = 5, + .stride = 1, + }, +}; + +float const array_node_geosphere001_scale_input_array[] = { + 0.0f, + 1.666667f, + 3.333333f, +}; + +float const array_node_geosphere001_scale_output_array[] = { + 1.0f, 1.0f, 1.0f, + 1.996525f, 1.996525f, 1.996525f, + 1.0f, 1.0f, 1.0f, +}; + +float const array_node_geosphere001_scale_intangent_array[] = { + 0.9997917f, 1.0f, 0.9997917f, 1.0f, 0.9997917f, 1.0f, + 1.111167f, 1.996525f, 1.111167f, 1.996525f, 1.111167f, 1.996525f, + 2.777833f, 1.0f, 2.777833f, 1.0f, 2.777833f, 1.0f, +}; + +float const array_node_geosphere001_scale_outtangent_array[] = { + 0.5555f, 1.0f, 0.5555f, 1.0f, 0.5555f, 1.0f, + 2.222167f, 1.996525f, 2.222167f, 1.996525f, 2.222167f, 1.996525f, + 2.333542f, 1.0f, 2.333542f, 1.0f, 2.333542f, 1.0f, +}; + +enum interpolation const array_node_geosphere001_scale_interpolation_array[] = { + interpolation::BEZIER, + interpolation::BEZIER, + interpolation::BEZIER, +}; + +sampler const sampler_node_geosphere001_scale_sampler = { + // node_geosphere001_scale_input + .input = { + .float_array = array_node_geosphere001_scale_input_array, + .count = 3, + .stride = 1, + }, + // node_geosphere001_scale_output + .output = { + .float_array = array_node_geosphere001_scale_output_array, + .count = 3, + .stride = 3, + }, + // node_geosphere001_scale_intangent + .in_tangent = { + .float_array = array_node_geosphere001_scale_intangent_array, + .count = 3, + .stride = 6, + }, + // node_geosphere001_scale_outtangent + .out_tangent = { + .float_array = array_node_geosphere001_scale_outtangent_array, + .count = 3, + .stride = 6, + }, + // node_geosphere001_scale_interpolation + .interpolation = { + .interpolation_array = array_node_geosphere001_scale_interpolation_array, + .count = 3, + .stride = 1, + }, +}; + +float const array_node_geosphere001_inversescaleaxisrotation_input_array[] = { + 0.0f, + 1.666667f, + 3.333333f, +}; + +float const array_node_geosphere001_inversescaleaxisrotation_output_array[] = { + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, +}; + +enum interpolation const array_node_geosphere001_inversescaleaxisrotation_interpolation_array[] = { + interpolation::LINEAR, + interpolation::LINEAR, + interpolation::LINEAR, +}; + +sampler const sampler_node_geosphere001_inversescaleaxisrotation_sampler = { + // node_geosphere001_inversescaleaxisrotation_input + .input = { + .float_array = array_node_geosphere001_inversescaleaxisrotation_input_array, + .count = 3, + .stride = 1, + }, + // node_geosphere001_inversescaleaxisrotation_output + .output = { + .float_array = array_node_geosphere001_inversescaleaxisrotation_output_array, + .count = 3, + .stride = 4, + }, + // node_geosphere001_inversescaleaxisrotation_interpolation + .interpolation = { + .interpolation_array = array_node_geosphere001_inversescaleaxisrotation_interpolation_array, + .count = 3, + .stride = 1, + }, +}; + +float const array_node_geosphere001_scaleaxisrotation_input_array[] = { + 0.0f, + 1.666667f, + 3.333333f, +}; + +float const array_node_geosphere001_scaleaxisrotation_output_array[] = { + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, +}; + +enum interpolation const array_node_geosphere001_scaleaxisrotation_interpolation_array[] = { + interpolation::LINEAR, + interpolation::LINEAR, + interpolation::LINEAR, +}; + +sampler const sampler_node_geosphere001_scaleaxisrotation_sampler = { + // node_geosphere001_scaleaxisrotation_input + .input = { + .float_array = array_node_geosphere001_scaleaxisrotation_input_array, + .count = 3, + .stride = 1, + }, + // node_geosphere001_scaleaxisrotation_output + .output = { + .float_array = array_node_geosphere001_scaleaxisrotation_output_array, + .count = 3, + .stride = 4, + }, + // node_geosphere001_scaleaxisrotation_interpolation + .interpolation = { + .interpolation_array = array_node_geosphere001_scaleaxisrotation_interpolation_array, + .count = 3, + .stride = 1, + }, +}; + +channel const node_channel_node_cube_translation_x = { + .source_sampler = &sampler_node_cube_translation_x_sampler, + .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_index = 0, + .target_attribute = target_attribute::Y, +}; + +channel const node_channel_node_torus001_rotationx_angle = { + .source_sampler = &sampler_node_torus001_rotationx_angle_sampler, + .target_transform_index = 3, + .target_attribute = target_attribute::ANGLE, +}; + +channel const node_channel_node_geosphere001_scale = { + .source_sampler = &sampler_node_geosphere001_scale_sampler, + .target_transform_index = 2, + .target_attribute = target_attribute::ALL, +}; + +channel const node_channel_node_geosphere001_inversescaleaxisrotation = { + .source_sampler = &sampler_node_geosphere001_inversescaleaxisrotation_sampler, + .target_transform_index = 1, + .target_attribute = target_attribute::ALL, +}; + +channel const node_channel_node_geosphere001_scaleaxisrotation = { + .source_sampler = &sampler_node_geosphere001_scaleaxisrotation_sampler, + .target_transform_index = 3, + .target_attribute = target_attribute::ALL, +}; + +effect const effect_material__15 = { + .type = effect_type::BLINN, + .blinn = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .ambient = { + .color = {0.6705883f, 0.5843138f, 1.0f, 1.0f}, + }, + .diffuse = { + .color = {0.6705883f, 0.5843138f, 1.0f, 1.0f}, + }, + .specular = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_material__16 = { + .type = effect_type::BLINN, + .blinn = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .ambient = { + .color = {0.5803922f, 1.0f, 0.9647059f, 1.0f}, + }, + .diffuse = { + .color = {0.5803922f, 1.0f, 0.9647059f, 1.0f}, + }, + .specular = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_material__17 = { + .type = effect_type::BLINN, + .blinn = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .ambient = { + .color = {0.6509804f, 1.0f, 0.5803922f, 1.0f}, + }, + .diffuse = { + .color = {0.6509804f, 1.0f, 0.5803922f, 1.0f}, + }, + .specular = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_material__18 = { + .type = effect_type::BLINN, + .blinn = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .ambient = { + .color = {0.9333334f, 1.0f, 0.5647059f, 1.0f}, + }, + .diffuse = { + .color = {0.9333334f, 1.0f, 0.5647059f, 1.0f}, + }, + .specular = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_material__19 = { + .type = effect_type::BLINN, + .blinn = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .ambient = { + .color = {1.0f, 0.7686275f, 0.5803922f, 1.0f}, + }, + .diffuse = { + .color = {1.0f, 0.7686275f, 0.5803922f, 1.0f}, + }, + .specular = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_material__20 = { + .type = effect_type::BLINN, + .blinn = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .ambient = { + .color = {1.0f, 0.5803922f, 0.5803922f, 1.0f}, + }, + .diffuse = { + .color = {1.0f, 0.5803922f, 0.5803922f, 1.0f}, + }, + .specular = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_coloreffectr26g177b26 = { + .type = effect_type::PHONG, + .phong = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 0.0f}, + }, + .ambient = { + .color = {0.1019608f, 0.6941176f, 0.1019608f, 1.0f}, + }, + .diffuse = { + .color = {0.1019608f, 0.6941176f, 0.1019608f, 1.0f}, + }, + .specular = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_coloreffectr229g154b215 = { + .type = effect_type::PHONG, + .phong = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 0.0f}, + }, + .ambient = { + .color = {0.8980392f, 0.6039216f, 0.8431373f, 1.0f}, + }, + .diffuse = { + .color = {0.8980392f, 0.6039216f, 0.8431373f, 1.0f}, + }, + .specular = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_coloreffectr28g149b177 = { + .type = effect_type::PHONG, + .phong = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 0.0f}, + }, + .ambient = { + .color = {0.1098039f, 0.5843137f, 0.6941176f, 1.0f}, + }, + .diffuse = { + .color = {0.1098039f, 0.5843137f, 0.6941176f, 1.0f}, + }, + .specular = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +effect const effect_coloreffectr198g224b87 = { + .type = effect_type::PHONG, + .phong = { + .emission = { + .color = {0.0f, 0.0f, 0.0f, 0.0f}, + }, + .ambient = { + .color = {0.7764706f, 0.8784314f, 0.3411765f, 1.0f}, + }, + .diffuse = { + .color = {0.7764706f, 0.8784314f, 0.3411765f, 1.0f}, + }, + .specular = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .shininess = 10.0f, + .reflective = { + .color = {0.0f, 0.0f, 0.0f, 1.0f}, + }, + .reflectivity = 0.0f, + .transparent = { + .color = {1.0f, 1.0f, 1.0f, 1.0f}, + }, + .transparency = 1.0f, + .index_of_refraction = 0.0f, + } +}; + +material const material_coloreffectr26g177b26_material = { + .effect = &effect_coloreffectr26g177b26, +}; + +material const material_coloreffectr229g154b215_material = { + .effect = &effect_coloreffectr229g154b215, +}; + +material const material_coloreffectr28g149b177_material = { + .effect = &effect_coloreffectr28g149b177, +}; + +material const material_coloreffectr198g224b87_material = { + .effect = &effect_coloreffectr198g224b87, +}; + +material const material_material__15_material = { + .effect = &effect_material__15, +}; + +material const material_material__16_material = { + .effect = &effect_material__16, +}; + +material const material_material__17_material = { + .effect = &effect_material__17, +}; + +material const material_material__18_material = { + .effect = &effect_material__18, +}; + +material const material_material__19_material = { + .effect = &effect_material__19, +}; + +material const material_material__20_material = { + .effect = &effect_material__20, +}; + +input_element const input_elements_position_0_3_normal_0_3_texcoord_0_3[] = { + { + .semantic = "POSITION", + .semantic_index = 0, + .format = input_format::FLOAT3, + }, + { + .semantic = "NORMAL", + .semantic_index = 0, + .format = input_format::FLOAT3, + }, + { + .semantic = "TEXCOORD", + .semantic_index = 0, + .format = input_format::FLOAT3, + }, +}; + +triangles const triangles_geom_cube[] = { + { + .count = 2, // triangles + .index_offset = 0, // indices + .inputs_index = 0, // index into inputs_list + }, + { + .count = 2, // triangles + .index_offset = 6, // indices + .inputs_index = 0, // index into inputs_list + }, + { + .count = 2, // triangles + .index_offset = 12, // indices + .inputs_index = 0, // index into inputs_list + }, + { + .count = 2, // triangles + .index_offset = 18, // indices + .inputs_index = 0, // index into inputs_list + }, + { + .count = 2, // triangles + .index_offset = 24, // indices + .inputs_index = 0, // index into inputs_list + }, + { + .count = 2, // triangles + .index_offset = 30, // indices + .inputs_index = 0, // index into inputs_list + }, +}; + +geometry const geometry_geom_cube = { + .mesh = { + .triangles = triangles_geom_cube, + .triangles_count = 6, + + .vertex_buffer_offset = 0, + .vertex_buffer_size = 864, + + .index_buffer_offset = 0, + .index_buffer_size = 144, + } +}; + +triangles const triangles_geom_torus001[] = { + { + .count = 240, // triangles + .index_offset = 0, // indices + .inputs_index = 0, // index into inputs_list + }, +}; + +geometry const geometry_geom_torus001 = { + .mesh = { + .triangles = triangles_geom_torus001, + .triangles_count = 1, + + .vertex_buffer_offset = 864, + .vertex_buffer_size = 5148, + + .index_buffer_offset = 144, + .index_buffer_size = 2880, + } +}; + +triangles const triangles_geom_cylinder001[] = { + { + .count = 30, // triangles + .index_offset = 0, // indices + .inputs_index = 0, // index into inputs_list + }, +}; + +geometry const geometry_geom_cylinder001 = { + .mesh = { + .triangles = triangles_geom_cylinder001, + .triangles_count = 1, + + .vertex_buffer_offset = 6012, + .vertex_buffer_size = 1152, + + .index_buffer_offset = 3024, + .index_buffer_size = 360, + } +}; + +triangles const triangles_geom_plane001[] = { + { + .count = 2, // triangles + .index_offset = 0, // indices + .inputs_index = 0, // index into inputs_list + }, +}; + +geometry const geometry_geom_plane001 = { + .mesh = { + .triangles = triangles_geom_plane001, + .triangles_count = 1, + + .vertex_buffer_offset = 7164, + .vertex_buffer_size = 144, + + .index_buffer_offset = 3384, + .index_buffer_size = 24, + } +}; + +triangles const triangles_geom_geosphere001[] = { + { + .count = 40, // triangles + .index_offset = 0, // indices + .inputs_index = 0, // index into inputs_list + }, +}; + +geometry const geometry_geom_geosphere001 = { + .mesh = { + .triangles = triangles_geom_geosphere001, + .triangles_count = 1, + + .vertex_buffer_offset = 7308, + .vertex_buffer_size = 4320, + + .index_buffer_offset = 3408, + .index_buffer_size = 480, + } +}; + +geometry const * const geometries[] = { + &geometry_geom_cube, + &geometry_geom_torus001, + &geometry_geom_cylinder001, + &geometry_geom_plane001, + &geometry_geom_geosphere001, +}; + +transform const transforms_node_environmentambientlight[] = { +}; + +instance_geometry const instance_geometries_node_environmentambientlight[] = { +}; + +channel const * const node_channels_node_environmentambientlight[] = {}; + +node const node_node_environmentambientlight = { + .parent_index = -1, + + .type = node_type::NODE, + + .transforms = transforms_node_environmentambientlight, + .transforms_count = 0, + + .instance_geometries = instance_geometries_node_environmentambientlight, + .instance_geometries_count = 0, + + .channels = node_channels_node_environmentambientlight, + .channels_count = 0, +}; + +transform const transforms_node_cube[] = { + { + .type = transform_type::TRANSLATE, + .translate = {10.0f, -1.14258e-07f, 0.0f}, + }, +}; + +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, + }, + { + .element_index = 4, // an index into mesh.triangles + .material = &material_material__20_material, + }, + { + .element_index = 3, // an index into mesh.triangles + .material = &material_material__18_material, + }, + { + .element_index = 2, // an index into mesh.triangles + .material = &material_material__19_material, + }, +}; + +instance_geometry const instance_geometries_node_cube[] = { + { + .geometry = &geometry_geom_cube, + .instance_materials = instance_materials_node_cube_0, + .instance_materials_count = 6, + }, +}; + +channel const * const node_channels_node_cube[] = { + &node_channel_node_cube_translation_y, + &node_channel_node_cube_translation_x, +}; + +node const node_node_cube = { + .parent_index = -1, + + .type = node_type::NODE, + + .transforms = transforms_node_cube, + .transforms_count = 1, + + .instance_geometries = instance_geometries_node_cube, + .instance_geometries_count = 1, + + .channels = node_channels_node_cube, + .channels_count = 2, +}; + +transform const transforms_node_torus001[] = { + { + .type = transform_type::TRANSLATE, + .translate = {5.0f, 1.14258e-07f, 2.0f}, + }, + { + .type = transform_type::ROTATE, + .rotate = {0.0f, 0.0f, 1.0f, 0.0f}, + }, + { + .type = transform_type::ROTATE, + .rotate = {0.0f, 1.0f, 0.0f, 2.00358e-05f}, + }, + { + .type = transform_type::ROTATE, + .rotate = {1.0f, 0.0f, 0.0f, 0.0f}, + }, + { + .type = transform_type::SCALE, + .scale = {0.5f, 0.5f, 0.5f}, + }, +}; + +instance_material const instance_materials_node_torus001_0[] = { + { + .element_index = 0, // an index into mesh.triangles + .material = &material_coloreffectr26g177b26_material, + }, +}; + +instance_geometry const instance_geometries_node_torus001[] = { + { + .geometry = &geometry_geom_torus001, + .instance_materials = instance_materials_node_torus001_0, + .instance_materials_count = 1, + }, +}; + +channel const * const node_channels_node_torus001[] = { + &node_channel_node_torus001_rotationx_angle, +}; + +node const node_node_torus001 = { + .parent_index = 1, + + .type = node_type::NODE, + + .transforms = transforms_node_torus001, + .transforms_count = 5, + + .instance_geometries = instance_geometries_node_torus001, + .instance_geometries_count = 1, + + .channels = node_channels_node_torus001, + .channels_count = 1, +}; + +transform const transforms_node_cylinder001[] = { +}; + +instance_material const instance_materials_node_cylinder001_0[] = { + { + .element_index = 0, // an index into mesh.triangles + .material = &material_coloreffectr229g154b215_material, + }, +}; + +instance_geometry const instance_geometries_node_cylinder001[] = { + { + .geometry = &geometry_geom_cylinder001, + .instance_materials = instance_materials_node_cylinder001_0, + .instance_materials_count = 1, + }, +}; + +channel const * const node_channels_node_cylinder001[] = { +}; + +node const node_node_cylinder001 = { + .parent_index = -1, + + .type = node_type::NODE, + + .transforms = transforms_node_cylinder001, + .transforms_count = 0, + + .instance_geometries = instance_geometries_node_cylinder001, + .instance_geometries_count = 1, + + .channels = node_channels_node_cylinder001, + .channels_count = 0, +}; + +transform const transforms_node_plane001[] = { + { + .type = transform_type::TRANSLATE, + .translate = {0.0f, 0.0f, 0.01f}, + }, + { + .type = transform_type::ROTATE, + .rotate = {0.0f, 0.0f, -1.0f, -44.99999f}, + }, +}; + +instance_material const instance_materials_node_plane001_0[] = { + { + .element_index = 0, // an index into mesh.triangles + .material = &material_coloreffectr28g149b177_material, + }, +}; + +instance_geometry const instance_geometries_node_plane001[] = { + { + .geometry = &geometry_geom_plane001, + .instance_materials = instance_materials_node_plane001_0, + .instance_materials_count = 1, + }, +}; + +channel const * const node_channels_node_plane001[] = { +}; + +node const node_node_plane001 = { + .parent_index = -1, + + .type = node_type::NODE, + + .transforms = transforms_node_plane001, + .transforms_count = 2, + + .instance_geometries = instance_geometries_node_plane001, + .instance_geometries_count = 1, + + .channels = node_channels_node_plane001, + .channels_count = 0, +}; + +transform const transforms_node_geosphere001[] = { + { + .type = transform_type::TRANSLATE, + .translate = {0.03164387f, -0.03838623f, 0.0f}, + }, + { + .type = transform_type::ROTATE, + .rotate = {0.0f, 0.0f, 0.0f, 0.0f}, + }, + { + .type = transform_type::SCALE, + .scale = {1.0f, 1.0f, 1.0f}, + }, + { + .type = transform_type::ROTATE, + .rotate = {0.0f, 0.0f, 0.0f, 0.0f}, + }, +}; + +instance_material const instance_materials_node_geosphere001_0[] = { + { + .element_index = 0, // an index into mesh.triangles + .material = &material_coloreffectr198g224b87_material, + }, +}; + +instance_geometry const instance_geometries_node_geosphere001[] = { + { + .geometry = &geometry_geom_geosphere001, + .instance_materials = instance_materials_node_geosphere001_0, + .instance_materials_count = 1, + }, +}; + +channel const * const node_channels_node_geosphere001[] = { + &node_channel_node_geosphere001_inversescaleaxisrotation, + &node_channel_node_geosphere001_scale, + &node_channel_node_geosphere001_scaleaxisrotation, +}; + +node const node_node_geosphere001 = { + .parent_index = -1, + + .type = node_type::NODE, + + .transforms = transforms_node_geosphere001, + .transforms_count = 4, + + .instance_geometries = instance_geometries_node_geosphere001, + .instance_geometries_count = 1, + + .channels = node_channels_node_geosphere001, + .channels_count = 3, +}; + +node const * const nodes[] = { + &node_node_environmentambientlight, + &node_node_cube, + &node_node_torus001, + &node_node_cylinder001, + &node_node_plane001, + &node_node_geosphere001, +}; + +inputs const inputs_list[] = { + { + .elements = input_elements_position_0_3_normal_0_3_texcoord_0_3, + .elements_count = 3, + }, +}; + +extern collada::descriptor const descriptor; + +collada::descriptor const descriptor = { + .nodes = nodes, + .nodes_count = (sizeof (nodes)) / (sizeof (nodes[0])), + + .inputs_list = inputs_list, + .inputs_list_count = (sizeof (inputs_list)) / (sizeof (inputs_list[0])), +}; + +}