From 727f5ff8d7f9c0158fde5dd775027d70902bbd3a Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 23 Feb 2026 18:40:36 +0000 Subject: [PATCH] collada: add support for lua source generation --- collada/cpp_header.py | 6 +- collada/header.py | 93 ++++++------ collada/lua_header.py | 338 ++++++++++++++++++++++++++++++++++++++++++ collada/main.py | 11 +- 4 files changed, 398 insertions(+), 50 deletions(-) create mode 100644 collada/lua_header.py diff --git a/collada/cpp_header.py b/collada/cpp_header.py index f03f6d1..a1134c6 100644 --- a/collada/cpp_header.py +++ b/collada/cpp_header.py @@ -42,7 +42,7 @@ def render_geometry(geometry_name, def render_library_geometries(geometry_names): yield "geometry const * const geometries[] = {" for geometry_name in geometry_names: - yield f"&geometry_{geometry_name}," + yield f"&geometry_{geometry_name}," yield "};" def render_float_tuple(t): @@ -269,7 +269,7 @@ def render_interpolation_array(array_name, names): def render_float_array(array_name, vectors): yield f"float const array_{array_name}[] = {{" for vector in vectors: - yield f"{vector}," + yield f"{render_float_tuple(vector)}," yield "};" def render_source(source_name, field_name, c_type, array_name, count, stride): @@ -295,7 +295,7 @@ def render_channel(target_name, sampler_name, transform_index, target_attribute) def render_light(light_name, light_type, color): yield f"light const light_{light_name} = {{" yield f".type = light_type::{light_type}," - yield f".color = {{ {color} }}," + yield f".color = {{ {render_float_tuple(color)} }}," yield "};" def render_image(image_id, image_name, resource_name): diff --git a/collada/header.py b/collada/header.py index b32f5e1..b8b78aa 100644 --- a/collada/header.py +++ b/collada/header.py @@ -14,7 +14,8 @@ from collada import parse from collada import types from collada.generate import renderer from collada import buffer -from collada import cpp_header + +lang_header = None @dataclass class State: @@ -139,7 +140,7 @@ def render_input_elements(state, collada, geometry_name, offset_tables): continue state.emitted_input_elements_arrays[key_name] = (i, key) - yield from cpp_header.render_input_elements(key_name, key) + yield from lang_header.render_input_elements(key_name, key) def render_triangles(state, collada, geometry_name, primitive_elements, mesh_buffer_state): yield from render_input_elements(state, collada, geometry_name, mesh_buffer_state.offset_tables) @@ -154,7 +155,7 @@ def render_triangles(state, collada, geometry_name, primitive_elements, mesh_buf yield triangles.count, mesh_buffer_state.index_buffer_offsets[i], index - yield from cpp_header.render_triangles(geometry_name, items()) + yield from lang_header.render_triangles(geometry_name, items()) def render_geometry(state, collada, geometry): geometry_name = sanitize_name(state, geometry.id, geometry) @@ -178,7 +179,7 @@ def render_geometry(state, collada, geometry): triangles_count = len(mesh.primitive_elements) - yield from cpp_header.render_geometry(geometry_name, + yield from lang_header.render_geometry(geometry_name, triangles_count, vertex_buffer_offset, vertex_buffer_size, @@ -200,26 +201,26 @@ def render_library_geometries(state, collada): geometry_name = sanitize_name(state, geometry.id, geometry) yield geometry_name - yield from cpp_header.render_library_geometries(geometry_names()) + yield from lang_header.render_library_geometries(geometry_names()) def render_node_transforms(state, collada, node_name, transformation_elements): def render_transform(transform): if type(transform) is types.Lookat: - yield from cpp_header.render_transform_lookat(transform.eye, transform.at, transform.up) + yield from lang_header.render_transform_lookat(transform.eye, transform.at, transform.up) elif type(transform) is types.Matrix: - yield from cpp_header.render_transform_matrix(matrix_transpose(transform.values)) + yield from lang_header.render_transform_matrix(matrix_transpose(transform.values)) elif type(transform) is types.Rotate: - yield from cpp_header.render_transform_rotate(transform.rotate) + yield from lang_header.render_transform_rotate(transform.rotate) elif type(transform) is types.Scale: - yield from cpp_header.render_transform_scale(transform.scale) + yield from lang_header.render_transform_scale(transform.scale) elif type(transform) is types.Skew: - yield from cpp_header.render_transform_skew(transform.skew) + yield from lang_header.render_transform_skew(transform.skew) elif type(transform) is types.Translate: - yield from cpp_header.render_transform_translate(transform.translate) + yield from lang_header.render_transform_translate(transform.translate) else: assert False, type(transform) - yield from cpp_header.render_node_transforms(node_name, transformation_elements, render_transform) + yield from lang_header.render_node_transforms(node_name, transformation_elements, render_transform) def find_material_symbol(geometry, material_symbol): assert material_symbol is not None @@ -279,7 +280,7 @@ def render_node_geometry_instance_materials(state, collada, prefix, node_name, i specular_input_set = shader_to_input_set(channel_to_input_set, shader, attrgetter("specular")) yield element_index, material_name, emission_input_set, ambient_input_set, diffuse_input_set, specular_input_set - yield from cpp_header.render_node_geometry_instance_materials(prefix, node_name, i, items()) + yield from lang_header.render_node_geometry_instance_materials(prefix, node_name, i, items()) def get_instance_materials(instance_geometry): return instance_geometry.bind_material.technique_common.materials if instance_geometry.bind_material is not None else [] @@ -300,7 +301,7 @@ def render_node_instance_geometries(state, collada, node_name, instance_geometri yield geometry_name, i, instance_materials_count - yield from cpp_header.render_node_instance_geometries(node_name, items()) + yield from lang_header.render_node_instance_geometries(node_name, items()) def get_node_name_id(node): name = node.id if node.id is not None else f"node-{node.name}" @@ -318,10 +319,10 @@ def get_node_name_id(node): def render_node_channels(state, collada, node, node_name): if node.id is None: # nodes with no ID can't have channels - yield from cpp_header.render_node_channels(node_name, []) + yield from lang_header.render_node_channels(node_name, []) else: target_names = state.node_animation_channels[node.id] - yield from cpp_header.render_node_channels(node_name, target_names) + yield from lang_header.render_node_channels(node_name, target_names) def render_node_instance_lights(state, collada, node_name, instance_lights): def light_names(): @@ -330,7 +331,7 @@ def render_node_instance_lights(state, collada, node_name, instance_lights): light_name = sanitize_name(state, light.id, light) yield light_name - yield from cpp_header.render_node_instance_lights(node_name, light_names()) + yield from lang_header.render_node_instance_lights(node_name, light_names()) def find_node_by_sid(root_node, sid): if sid == root_node.sid: @@ -365,7 +366,7 @@ def render_joint_node_indices(state, collada, skin, node_name, controller_name, joint_node_name = sanitize_name(state, joint_node_name_id, joint_node) yield joint_node_index, node_sid, joint_node_name - yield from cpp_header.render_joint_node_indices(node_name, controller_name, items()) + yield from lang_header.render_joint_node_indices(node_name, controller_name, items()) def render_node_instance_controller_joint_node_indices(state, collada, node_name, instance_controller): controller = collada.lookup(instance_controller.url, types.Controller) @@ -395,7 +396,7 @@ def render_node_instance_controllers(state, collada, node_name, instance_control yield controller_name, i, instance_materials_count - yield from cpp_header.render_node_instance_controllers(node_name, items()) + yield from lang_header.render_node_instance_controllers(node_name, items()) def render_node(state, collada, node, node_index): node_name_id = get_node_name_id(node) @@ -419,7 +420,7 @@ def render_node(state, collada, node, node_index): instance_lights_count = len(node.instance_lights) channels_count = len(state.node_animation_channels[node.id]) - yield from cpp_header.render_node(node_name, parent_index, type, + yield from lang_header.render_node(node_name, parent_index, type, transforms_count, instance_geometries_count, instance_controllers_count, @@ -453,7 +454,7 @@ def render_library_visual_scenes(state, collada): node_name = sanitize_name(state, node_name_id, node) yield node_name, node_index - yield from cpp_header.render_library_visual_scenes(items()) + yield from lang_header.render_library_visual_scenes(items()) def render_opt_texture(state, profile_common, field_name, texture): sampler_sid = texture.texture @@ -469,10 +470,10 @@ def render_opt_texture(state, profile_common, field_name, texture): image_id = surface.parameter_type.init_from.uri image_index = state.image_indices[image_id] - yield from cpp_header.render_opt_texture(field_name, image_index, image_id) + yield from lang_header.render_opt_texture(field_name, image_index, image_id) def render_opt_color(field_name, color): - yield from cpp_header.render_opt_color(field_name, color) + yield from lang_header.render_opt_color(field_name, color) def render_opt_color_or_texture(state, profile_common, field_name, color_or_texture): if color_or_texture is None: @@ -490,12 +491,12 @@ def render_opt_color_or_texture(state, profile_common, field_name, color_or_text else: assert False, color_or_texture - yield from cpp_header.render_opt_color_or_texture(field_name, opt_type, render_body) + yield from lang_header.render_opt_color_or_texture(field_name, opt_type, render_body) def render_opt_float(field_name, f): if f is None: f = types.Float(value=0.0) - yield from cpp_header.render_opt_float(field_name, float(f.value)) + yield from lang_header.render_opt_float(field_name, float(f.value)) def render_effect(state, collada, effect): profile_common, = effect.profile_common @@ -556,7 +557,7 @@ def render_effect(state, collada, effect): else: assert False, type(shader) - yield from cpp_header.render_effect(effect_name, type_name, field_name, render_body) + yield from lang_header.render_effect(effect_name, type_name, field_name, render_body) def render_library_effects(state, collada): for library_effects in collada.library_effects: @@ -569,21 +570,21 @@ def render_library_materials(state, collada): effect = collada.lookup(material.instance_effect.url, types.Effect) material_name = sanitize_name(state, material.id, material) effect_name = sanitize_name(state, effect.id, effect) - yield from cpp_header.render_library_material(material_name, effect_name) + yield from lang_header.render_library_material(material_name, effect_name) def render_input_elements_list(state): def items(): for key_name, (index, key) in state.emitted_input_elements_arrays.items(): elements_count = len(key) yield key_name, elements_count - yield from cpp_header.render_input_elements_list(items()) + yield from lang_header.render_input_elements_list(items()) def render_animation_children(state, collada, animation_name, animations): def items(): for animation in animations: animation_name = sanitize_name(state, animation.id, animation) yield animation_name - yield from cpp_header.render_animation_children(animation_name, items()) + yield from lang_header.render_animation_children(animation_name, items()) def render_array(state, collada, accessor, array): array_name = sanitize_name(state, array.id, array) @@ -596,14 +597,14 @@ def render_array(state, collada, accessor, array): for name in array.names: assert name in {"BEZIER", "LINEAR"}, name yield name - yield from cpp_header.render_interpolation_array(array_name, names()) + yield from lang_header.render_interpolation_array(array_name, names()) elif type(array) is types.FloatArray: def vectors(): it = iter(array.floats) for i in range(accessor.count): - vector = ", ".join(f"{float(f)}f" for f in islice(it, accessor.stride)) + vector = list(islice(it, accessor.stride)) yield vector - yield from cpp_header.render_float_array(array_name, vectors()) + yield from lang_header.render_float_array(array_name, vectors()) else: assert False, type(array) @@ -612,7 +613,7 @@ def render_source(state, collada, field_name, source): c_type = "interpolation" if type(source.array_element) is types.NameArray else "float" source_name = sanitize_name(state, source.id, source) - yield from cpp_header.render_source(source_name, + yield from lang_header.render_source(source_name, field_name, c_type, array_name, @@ -656,7 +657,7 @@ def render_sampler(state, collada, sampler): source = collada.lookup(input.source, types.SourceCore) field_name = input.semantic.lower() yield from render_source(state, collada, field_name, source) - yield from cpp_header.render_sampler(sampler_name, render_body) + yield from lang_header.render_sampler(sampler_name, render_body) target_attributes = { "A", "ANGLE", "B", "G", "P", "Q", "R", "S", "T", "TIME", "U", "V", "W", "X", "Y", "Z", "ALL" @@ -703,7 +704,7 @@ def render_channel(state, collada, channel): assert target_name not in state.node_animation_channels[node.id] state.node_animation_channels[node.id].add(target_name) - yield from cpp_header.render_channel(target_name, sampler_name, transform_index, target_attribute) + yield from lang_header.render_channel(target_name, sampler_name, transform_index, target_attribute) def render_animation(state, collada, animation_name, animation): # render children first @@ -751,9 +752,9 @@ def render_light_type(technique_common: types.TechniqueCommon_Light): def render_light(state, collada, light): technique_common = light.technique_common light_name = sanitize_name(state, light.id, light) - color = ", ".join(f"{float(f)}f" for f in technique_common.light.color) + color = technique_common.light.color light_type = render_light_type(technique_common) - yield from cpp_header.render_light(light_name, light_type, color) + yield from lang_header.render_light(light_name, light_type, color) def render_library_lights(state, collada): for library_lights in collada.library_lights: @@ -785,7 +786,7 @@ def render_image(state, collada, image, image_index): resource_name = image_resource_name(state, image.image_source.uri) image_name = sanitize_name(state, image.id, image) - yield from cpp_header.render_image(image.id, image_name, resource_name) + yield from lang_header.render_image(image.id, image_name, resource_name) def render_library_images(state, collada): image_index = 0 @@ -799,7 +800,7 @@ def render_library_images(state, collada): for image in library_images.images: image_name = sanitize_name(state, image.id, image) yield image_name - yield from cpp_header.render_library_images(image_names()) + yield from lang_header.render_library_images(image_names()) def render_inverse_bind_matrices(collada, skin, controller_name): inverse_bind_matrix_input, = find_semantics(skin.joints.inputs, "INV_BIND_MATRIX") @@ -817,7 +818,7 @@ def render_inverse_bind_matrices(collada, skin, controller_name): offset = stride * i matrix = matrix_transpose(array.floats[offset:offset+stride]) yield matrix - yield from cpp_header.render_inverse_bind_matrices(controller_name, matrices()) + yield from lang_header.render_inverse_bind_matrices(controller_name, matrices()) def renderbin_any(f, elems): fmt = { @@ -847,7 +848,7 @@ def render_controller(state, collada, controller): yield from render_inverse_bind_matrices(collada, skin, controller_name) - yield from cpp_header.render_controller(controller_name, geometry_name, vertex_buffer_offset, vertex_buffer_size) + yield from lang_header.render_controller(controller_name, geometry_name, vertex_buffer_offset, vertex_buffer_size) def render_library_controllers(state, collada): for library_controllers in collada.library_controllers: @@ -864,7 +865,7 @@ def render_camera(state, collada, camera): else: return f - yield from cpp_header.render_camera(camera_name, + yield from lang_header.render_camera(camera_name, nf(perspective.xfov), nf(perspective.yfov), nf(perspective.znear), @@ -879,7 +880,7 @@ def render_library_cameras(state, collada): def render_all(collada, namespace, input_filename): state = State(input_filename) render, out = renderer() - render(cpp_header.render_prelude(namespace)) + render(lang_header.render_prelude(namespace)) render(render_library_cameras(state, collada)) render(render_library_lights(state, collada)) render(render_library_animations(state, collada)) @@ -892,13 +893,13 @@ def render_all(collada, namespace, input_filename): # root elements render(render_library_visual_scenes(state, collada)) render(render_input_elements_list(state)) - render(cpp_header.render_descriptor(namespace)) - render(cpp_header.render_prologue()) + render(lang_header.render_descriptor(namespace)) + render(lang_header.render_prologue()) return state, out def render_all_hpp(namespace): render, out = renderer() - render(cpp_header.render_hpp(namespace)) + render(lang_header.render_hpp(namespace)) return out if __name__ == "__main__": diff --git a/collada/lua_header.py b/collada/lua_header.py new file mode 100644 index 0000000..5f0586b --- /dev/null +++ b/collada/lua_header.py @@ -0,0 +1,338 @@ +from itertools import islice + +from collada import types + +def render_input_elements(key_name, semantic__semantic_index__stride): + yield f"local input_elements_{key_name} = {{" + for semantic, semantic_index, stride in semantic__semantic_index__stride: + yield "{" + yield f'semantic = "{semantic}",' + yield f"semantic_index = {semantic_index}," + yield f"format = collada_types.input_format.FLOAT{stride}," + yield "}," + yield "}" + +def render_triangles(geometry_name, items): + yield f"local triangles_{geometry_name} = {{" + for count, index_offset, inputs_index in items: + yield "{" + yield f"count = {count}, -- triangles" + yield f"index_offset = {index_offset}, -- indices" + yield f"inputs_index = {inputs_index}, -- index into inputs_list" + yield "}," + yield "}" + +def render_geometry(geometry_name, + triangles_count, + vertex_buffer_offset, vertex_buffer_size, + index_buffer_offset, index_buffer_size): + yield f"local geometry_{geometry_name} = {{" + yield "mesh = {" + yield f"triangles = triangles_{geometry_name}," + yield f"triangles_count = {triangles_count}," + yield "" + yield f"vertex_buffer_offset = {vertex_buffer_offset}," + yield f"vertex_buffer_size = {vertex_buffer_size}," + yield "" + yield f"index_buffer_offset = {index_buffer_offset}," + yield f"index_buffer_size = {index_buffer_size}," + yield "}" + yield "}" + +def render_library_geometries(geometry_names): + yield "local geometries = {" + for geometry_name in geometry_names: + yield f"geometry_{geometry_name}," + yield "}" + +def render_float_tuple(t): + s = ", ".join((f"{float(f)}" for f in t)) + return f"{{{s}}}" + +def render_lookat(eye, at, up): + yield "type = collada_types.transform_type.LOOKAT," + yield "lookat = {" + yield f"eye = {render_float_tuple(eye)}", + yield f"at = {render_float_tuple(at)}", + yield f"up = {render_float_tuple(up)}", + yield "}," + +def render_matrix(fs): + fsi = iter(fs) + for i in range(4): + s = ", ".join(f"{f}" for f in islice(fsi, 4)) + yield f"{s}," + +def render_transform_matrix(matrix): + yield "type = collada_types.transform_type.MATRIX," + yield f"matrix = {render_float_tuple(matrix)}," + +def render_transform_rotate(rotate): + yield "type = collada_types.transform_type.ROTATE," + yield f"rotate = {render_float_tuple(rotate)}," + +def render_transform_scale(scale): + yield "type = collada_types.transform_type.SCALE," + yield f"scale = {render_float_tuple(scale)}," + +def render_transform_skew(skew): + yield "type = collada_types.transform_type.SKEW," + yield f"skew = {render_float_tuple(skew)}," + +def render_transform_translate(translate): + yield "type = collada_types.transform_type.TRANSLATE," + yield f"translate = {render_float_tuple(translate)}," + +def render_node_transforms(node_name, transformation_elements, render_transform): + yield f"local transforms_{node_name} = {{" + for transform in transformation_elements: + yield "{" + yield from render_transform(transform) + yield "}," + yield "}" + +def render_node_geometry_instance_materials(prefix, node_name, i, + items): + yield f"local {prefix}_instance_materials_{node_name}_{i} = {{" + for element_index, material_name, emission_input_set, ambient_input_set, diffuse_input_set, specular_input_set in items: + yield "{" + yield f"element_index = {element_index}, -- an index into mesh.triangles" + yield f"material = material_{material_name}," + yield "" + yield f"emission = {{ input_set = {emission_input_set} }}," + yield f"ambient = {{ input_set = {ambient_input_set} }}," + yield f"diffuse = {{ input_set = {diffuse_input_set} }}," + yield f"specular = {{ input_set = {specular_input_set} }}," + yield "}," + yield "}" + +def render_node_instance_geometries(node_name, items): + yield f"local instance_geometries_{node_name} = {{" + for geometry_name, i, instance_materials_count in items: + yield "{" + yield f"geometry = geometry_{geometry_name}," + yield "" + yield f"instance_materials = instance_geometry_instance_materials_{node_name}_{i}," + yield f"instance_materials_count = {instance_materials_count}," + yield "}," + yield "}" + +def render_node_channels(node_name, target_names): + yield f"local node_channels_{node_name} = {{" + for target_name in target_names: + yield f"node_channel_{target_name}," + yield "}" + +def render_node_instance_lights(node_name, light_names): + yield f"local instance_lights_{node_name} = {{" + for light_name in light_names: + yield "{" + yield f"light = light_{light_name}," + yield "}" + yield "}" + +def render_joint_node_indices(node_name, controller_name, items): + yield f"local joint_node_indices_{node_name}_{controller_name} = {{" + for joint_node_index, node_sid, joint_node_name in items: + yield f"{joint_node_index}, -- {node_sid} {joint_node_name}" + yield "}" + +def render_node_instance_controllers(node_name, items): + yield f"local instance_controllers_{node_name} = {{" + for controller_name, i, instance_materials_count in items: + yield "{" + yield f"controller = controller_{controller_name}," + yield "" + yield f"joint_node_indices = joint_node_indices_{node_name}_{controller_name}," + yield f"joint_count = #joint_node_indices_{node_name}_{controller_name}," + yield "" + yield f"instance_materials = instance_controller_instance_materials_{node_name}_{i}," + yield f"instance_materials_count = {instance_materials_count}," + yield "}," + yield "}" + +def render_node(node_name, parent_index, type, + transforms_count, + instance_geometries_count, + instance_controllers_count, + instance_lights_count, + channels_count): + yield f"local node_{node_name} = {{" + yield f"parent_index = {parent_index}," + yield "" + yield f"type = collada_types.node_type.{type}," + yield "" + yield f"transforms = transforms_{node_name}," + yield f"transforms_count = {transforms_count}," + yield "" + yield f"instance_geometries = instance_geometries_{node_name}," + yield f"instance_geometries_count = {instance_geometries_count}," + yield "" + yield f"instance_controllers = instance_controllers_{node_name}," + yield f"instance_controllers_count = {instance_controllers_count}," + yield "" + yield f"instance_lights = instance_lights_{node_name}," + yield f"instance_lights_count = {instance_lights_count}," + yield "" + yield f"channels = node_channels_{node_name}," + yield f"channels_count = {channels_count}," + #yield "" + #yield f"nodes = node_children_{node_name}," + #yield f"nodes_count = {len(node.nodes)}," + yield "}" + +def render_library_visual_scenes(items): + yield "local nodes = {" + for node_name, node_index in items: + yield f"node_{node_name}, -- {node_index}" + yield "}" + +def render_opt_color(field_name, color): + yield f"{field_name} = {render_float_tuple(color.value)}," + +def render_opt_texture(field_name, image_index, image_id): + yield f"{field_name} = {{ .image_index = {image_index} }}, -- {image_id}" + +def render_opt_color_or_texture(field_name, opt_type, render_body): + yield f"{field_name} = {{" + yield f"type = collada_types.color_or_texture_type.{opt_type}," + yield from render_body() + yield "}," + +def render_opt_float(field_name, value): + yield f"{field_name} = {value}," + +def render_effect(effect_name, type_name, field_name, render_body): + yield f"local effect_{effect_name} = {{" + + yield f"type = collada_types.effect_type.{type_name}," + yield f"{field_name} = {{" + yield from render_body() + yield "}" + + yield "}" + +def render_library_material(material_name, effect_name): + yield f"local material_{material_name} = {{" + yield f"effect = effect_{effect_name}," + yield "}" + +def render_input_elements_list(items): + yield "local inputs_list = {" + for key_name, elements_count in items: + yield "{" + yield f"elements = input_elements_{key_name}," + yield f"elements_count = {elements_count}," + yield "}," + yield "}" + +def render_descriptor(namespace): + yield "local descriptor = {" + yield "nodes = nodes," + yield "nodes_count = #nodes," + yield "" + yield "inputs_list = inputs_list," + yield "inputs_list_count = #inputs_list," + yield "" + yield "images = images," + yield "images_count = #images," + yield "" + #yield f'position_normal_texture_buffer = L"RES_SCENES_{namespace.upper()}_VTX",' + #yield f'joint_weight_buffer = L"RES_SCENES_{namespace.upper()}_VJW",' + #yield f'index_buffer = L"RES_SCENES_{namespace.upper()}_IDX",' + yield "}" + +def render_prelude(namespace): + yield "local collada_types = require 'collada_types'" + yield '' + +def render_prologue(): + yield "" + yield "return {" + yield "descriptor = descriptor" + yield "}" + +def render_animation_children(anomation_name, items): + yield f"local animation_children_{animation_name} = {{" + for animation_name in items: + yield "animation_{animation_name}," + yield "}" + +def render_interpolation_array(array_name, names): + yield f"local array_{array_name} = {{" + for name in names: + yield f"collada_types.interpolation.{name}," + yield "}" + +def render_float_array(array_name, vectors): + yield f"local array_{array_name} = {{" + for vector in vectors: + yield f"{render_float_tuple(vector)}," + yield "}" + +def render_source(source_name, field_name, c_type, array_name, count, stride): + yield f"-- {source_name}" + yield f"{field_name} = {{" + yield f"{c_type}_array = array_{array_name}," + yield f"count = {count}," + yield f"stride = {stride}," + yield "}," + +def render_sampler(sampler_name, render_body): + yield f"local sampler_{sampler_name} = {{" + yield from render_body() + yield "}" + +def render_channel(target_name, sampler_name, transform_index, target_attribute): + yield f"local node_channel_{target_name} = {{" + yield f"source_sampler = sampler_{sampler_name}," + yield f"target_transform_index = {transform_index}," + yield f"target_attribute = collada_types.target_attribute.{target_attribute}," + yield "}" + +def render_light(light_name, light_type, color): + yield f"local light_{light_name} = {{" + yield f"type = collada_types.light_type.{light_type}," + yield f"color = {render_float_tuple(color)}," + yield "}" + +def render_image(image_id, image_name, resource_name): + yield f"-- {image.id}" + yield f"local image_{image_name} = {{" + yield f'resource_name = L"{resource_name}",' + yield "}" + +def render_library_images(image_names): + yield "local images = {" + for image_name in image_names: + yield f"image_{image_name}," + yield "}" + +def render_inverse_bind_matrices(controller_name, matrices): + yield f"local inverse_bind_matrices_{controller_name} = {{" + for matrix in matrices: + yield "{" + yield from render_matrix(matrix) + yield "}," + yield "}" + +def render_controller(controller_name, geometry_name, vertex_buffer_offset, vertex_buffer_size): + yield f"local controller_{controller_name} = {{" + yield "skin = {" + yield f"geometry = geometry_{geometry_name}," + yield "" + yield f"inverse_bind_matrices = inverse_bind_matrices_{controller_name}," + yield "" + yield f"vertex_buffer_offset = {vertex_buffer_offset}," + yield f"vertex_buffer_size = {vertex_buffer_size}," + yield "}" + yield "}" + +def render_camera(camera_name, xfov, yfov, znear, zfar, aspect_ratio): + yield f"local camera_{camera_name} = {{" + yield f"xfov = {xfov}," + yield f"yfov = {yfov}," + yield f"znear = {znear}," + yield f"zfar = {zfar}," + yield f"aspect_ratio = {aspect_ratio}," + yield "}" diff --git a/collada/main.py b/collada/main.py index 291d8c5..36d377b 100644 --- a/collada/main.py +++ b/collada/main.py @@ -3,6 +3,8 @@ import os.path from collada import parse from collada import header +from collada import cpp_header +from collada import lua_header def usage(): name = sys.argv[0] @@ -60,7 +62,7 @@ def main(): output_resource = sys.argv[6] output_makefile = sys.argv[7] assert input_collada.lower().endswith(".dae") - assert output_source.lower().endswith(".cpp") + assert output_source.lower().endswith(".cpp") or output_source.lower().endswith(".lua") assert output_position_normal_texture.lower().endswith(".vtx") assert output_joint_weight.lower().endswith(".vjw") assert output_index.lower().endswith(".idx") @@ -71,6 +73,13 @@ def main(): collada = parse.parse_collada_file(input_collada) namespace = parse_namespace(input_collada) + + if output_source.lower().endswith(".cpp"): + header.lang_header = cpp_header + elif output_source.lower().endswith(".lua"): + header.lang_header = lua_header + else: + assert False state, out_source = header.render_all(collada, namespace, input_collada) with open(output_source, 'wb') as f: