From af165a38432004fad2dceea852b438173c57dbdc Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Thu, 29 Jan 2026 18:41:34 -0600 Subject: [PATCH] collada: render make and resource files --- .gitignore | 3 +- Makefile | 7 ++- collada/header.py | 17 +++---- collada/main.py | 44 +++++++++++++++++-- curve_interpolation.mk | 20 +++++++++ curve_interpolation.rc | 4 ++ .../curve_interpolation.cpp | 26 +++++------ 7 files changed, 90 insertions(+), 31 deletions(-) create mode 100644 curve_interpolation.mk create mode 100644 curve_interpolation.rc diff --git a/.gitignore b/.gitignore index 0531c73..fb16718 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ __pycache__ *.pyc .\#* \#* -*.gch \ No newline at end of file +*.gch +image/*.DDS \ No newline at end of file diff --git a/Makefile b/Makefile index 8e08727..ace80bd 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,9 @@ SHADERS = \ SCENES = \ src/scenes/curve_interpolation/curve_interpolation.cpp -$(BUILD_TYPE)/%.res: %.rc $(SHADERS) $(SCENES) +include curve_interpolation.mk + +$(BUILD_TYPE)/%.res: %.rc $(SHADERS) $(SCENES) $(IMAGES) @mkdir -p $(@D) $(WINDRES) -O coff -I$(BUILD_TYPE)/effect -o $@ $< @@ -70,10 +72,11 @@ include/scenes/%.hpp: $(COLLADA_PY_SOURCE) src/scenes/%.cpp: scenes/%.DAE include/scenes/%.hpp @mkdir -p $(@D) - PYTHONPATH=. python -m collada.main $< $@ $(<:.DAE=.vtx) $(<:.DAE=.idx) + PYTHONPATH=. python -m collada.main $< $@ $(<:.DAE=.vtx) $(<:.DAE=.idx) $(notdir $(<:.DAE=.rc)) $(notdir $(<:.DAE=.mk)) OBJS = \ $(BUILD_TYPE)/main.res \ + $(BUILD_TYPE)/curve_interpolation.res \ $(BUILD_TYPE)/robot_player.obj \ $(BUILD_TYPE)/cube.obj \ $(BUILD_TYPE)/main.obj \ diff --git a/collada/header.py b/collada/header.py index a118115..ac0bf14 100644 --- a/collada/header.py +++ b/collada/header.py @@ -87,7 +87,8 @@ def _validate_name_value(name, value): def sanitize_resource_name(state, name, value): _validate_name_value(name, value) assert '/' not in name, name - resource_name = _sanitize(name).upper() + resource_name = f'_{_sanitize(name).upper()}' + assert resource_name not in state.resource_names or state.resource_names[resource_name] is value state.resource_names[resource_name] = value return resource_name @@ -480,7 +481,7 @@ 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 f".{field_name} = {{ .image_index = {image_index} }}," + yield f".{field_name} = {{ .image_index = {image_index} }}, // {image_id}" def render_opt_color_or_texture(state, profile_common, field_name, color_or_texture): if color_or_texture is None: @@ -796,14 +797,6 @@ def render_library_lights(state, collada): for light in library_lights.lights: yield from render_light(state, collada, light) -def escape_space(s): - def _escape_space(s): - for c in s: - if c == ' ': - yield '\\' - yield c - return str(_escape_space(s)) - def image_resource_name(state, uri): uri = unquote(uri) prefix = "file:///" @@ -816,7 +809,7 @@ def image_resource_name(state, uri): filename = os.path.split(path)[1] assert filename not in state.image_paths, filename state.image_paths[filename] = path - return sanitize_resource_name(state, filename, path.lower()) + return sanitize_resource_name(state, filename, path) def render_image(state, collada, image, image_index): assert image.id is not None @@ -827,7 +820,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 f"// image_index: {image_index}" + yield f"// {image.id}" yield f"image const image_{image_name} = {{" yield f'.resource_name = L"{resource_name}",' yield "};" diff --git a/collada/main.py b/collada/main.py index 3d8619e..7a2783a 100644 --- a/collada/main.py +++ b/collada/main.py @@ -1,5 +1,5 @@ import sys -from os import path +import os.path from collada import parse from collada import header @@ -7,25 +7,57 @@ from collada import header def usage(): name = sys.argv[0] print("usage (source):") - print(f" {name} [input_collada.dae] [output_source.cpp] [output_vertex.vtx] [output_vertex.idx]") + print(f" {name} [input_collada.dae] [output_source.cpp] [output_vertex.vtx] [output_vertex.idx] [output_resource.rc]") print("usage (header):") print(f" {name} [output_header.hpp]") sys.exit(1) def parse_namespace(filename): - namespace = path.splitext(path.split(filename)[1])[0] + namespace = os.path.splitext(os.path.split(filename)[1])[0] return namespace +def render_resource_file(state, f): + for resource_name, path in state.resource_names.items(): + filename = os.path.split(path)[1] + filename = os.path.splitext(filename)[0] + f.write(f'{resource_name} RCDATA "image/{filename}.DDS"\r\n'.encode('ascii')) + +def escape_space(s): + def _escape_space(s): + for c in s: + if c == ' ': + yield '\\' + yield c + return "".join(_escape_space(s)) + +def render_makefile(state, f): + for _, path in state.resource_names.items(): + filename = os.path.split(path)[1] + filename, ext = os.path.splitext(filename) + filename = escape_space(filename) + + escaped = escape_space(path) + escaped_dds = os.path.splitext(filename) + + f.write(f"IMAGES += image/{filename}.DDS\r\n".encode('ascii')) + f.write(f"image/{filename}.DDS: {escaped}\r\n".encode('ascii')) + f.write('\ttexconv10.exe -nologo "$<"\r\n'.encode('ascii')) + f.write(f'\tmv "$(<:.{ext[1:]}=.DDS)" "$@"\r\n\r\n'.encode('ascii')) + def main(): try: input_collada = sys.argv[1] output_source = sys.argv[2] output_vertex = sys.argv[3] output_index = sys.argv[4] + output_resource = sys.argv[5] + output_makefile = sys.argv[6] assert input_collada.lower().endswith(".dae") assert output_source.lower().endswith(".cpp") assert output_vertex.lower().endswith(".vtx") assert output_index.lower().endswith(".idx") + assert output_resource.lower().endswith(".rc") + assert output_makefile.lower().endswith(".mk") except Exception as e: usage() @@ -44,6 +76,12 @@ def main(): with open(output_index, 'wb') as f: f.write(state.index_buffer.getvalue()) + with open(output_resource, 'wb') as f: + render_resource_file(state, f) + + with open(output_makefile, 'wb') as f: + render_makefile(state, f) + def main_header(): try: output_header = sys.argv[1] diff --git a/curve_interpolation.mk b/curve_interpolation.mk new file mode 100644 index 0000000..4669905 --- /dev/null +++ b/curve_interpolation.mk @@ -0,0 +1,20 @@ +IMAGES += image/american_cherry.DDS +image/american_cherry.DDS: C:/Program\ Files/Common\ Files/Autodesk\ Shared/Materials/Textures/1/Mats/american_cherry.png + texconv10.exe -nologo "$<" + mv "$(<:.png=.DDS)" "$@" + +IMAGES += image/102.DDS +image/102.DDS: C:/Program\ Files/Common\ Files/Autodesk\ Shared/Materials/Textures/3/Mats/102.png + texconv10.exe -nologo "$<" + mv "$(<:.png=.DDS)" "$@" + +IMAGES += image/Finishes.Flooring.Tile.Square.Medium\ Blue.DDS +image/Finishes.Flooring.Tile.Square.Medium\ Blue.DDS: C:/Program\ Files/Common\ Files/Autodesk\ Shared/Materials/Textures/3/Mats/Finishes.Flooring.Tile.Square.Medium\ Blue.png + texconv10.exe -nologo "$<" + mv "$(<:.png=.DDS)" "$@" + +IMAGES += image/SiteWork.Planting.Grass.Bermuda1.DDS +image/SiteWork.Planting.Grass.Bermuda1.DDS: C:/Program\ Files/Common\ Files/Autodesk\ Shared/Materials/Textures/3/Mats/SiteWork.Planting.Grass.Bermuda1.jpg + texconv10.exe -nologo "$<" + mv "$(<:.jpg=.DDS)" "$@" + diff --git a/curve_interpolation.rc b/curve_interpolation.rc new file mode 100644 index 0000000..563293e --- /dev/null +++ b/curve_interpolation.rc @@ -0,0 +1,4 @@ +_AMERICAN_CHERRY_PNG RCDATA "image/american_cherry.DDS" +_102_PNG RCDATA "image/102.DDS" +_FINISHES_FLOORING_TILE_SQUARE_MEDIUM_BLUE_PNG RCDATA "image/Finishes.Flooring.Tile.Square.Medium Blue.DDS" +_SITEWORK_PLANTING_GRASS_BERMUDA1_JPG RCDATA "image/SiteWork.Planting.Grass.Bermuda1.DDS" diff --git a/src/scenes/curve_interpolation/curve_interpolation.cpp b/src/scenes/curve_interpolation/curve_interpolation.cpp index 880751b..56db097 100644 --- a/src/scenes/curve_interpolation/curve_interpolation.cpp +++ b/src/scenes/curve_interpolation/curve_interpolation.cpp @@ -667,24 +667,24 @@ channel const node_channel_node_light_translation_z = { .target_attribute = target_attribute::Z, }; -// image_index: 0 +// american_cherry_png image const image_american_cherry_png = { - .resource_name = L"AMERICAN_CHERRY_PNG", + .resource_name = L"_AMERICAN_CHERRY_PNG", }; -// image_index: 1 +// _02_png image const image__02_png = { - .resource_name = L"102_PNG", + .resource_name = L"_102_PNG", }; -// image_index: 2 +// Finishes_Flooring_Tile_Square_Medium_Blue_png image const image_finishes_flooring_tile_square_medium_blue_png = { - .resource_name = L"FINISHES_FLOORING_TILE_SQUARE_MEDIUM_BLUE_PNG", + .resource_name = L"_FINISHES_FLOORING_TILE_SQUARE_MEDIUM_BLUE_PNG", }; -// image_index: 3 +// SiteWork_Planting_Grass_Bermuda1_jpg image const image_sitework_planting_grass_bermuda1_jpg = { - .resource_name = L"SITEWORK_PLANTING_GRASS_BERMUDA1_JPG", + .resource_name = L"_SITEWORK_PLANTING_GRASS_BERMUDA1_JPG", }; image const * const images[] = { @@ -945,7 +945,7 @@ effect const effect_grass = { }, .diffuse = { .type = color_or_texture_type::TEXTURE, - .texture = { .image_index = 3 }, + .texture = { .image_index = 3 }, // SiteWork_Planting_Grass_Bermuda1_jpg }, .specular = { .type = color_or_texture_type::COLOR, @@ -979,11 +979,11 @@ effect const effect_wood = { }, .diffuse = { .type = color_or_texture_type::TEXTURE, - .texture = { .image_index = 0 }, + .texture = { .image_index = 0 }, // american_cherry_png }, .specular = { .type = color_or_texture_type::TEXTURE, - .texture = { .image_index = 2 }, + .texture = { .image_index = 2 }, // Finishes_Flooring_Tile_Square_Medium_Blue_png }, .shininess = 10.0f, .reflective = { @@ -1629,9 +1629,9 @@ instance_light const instance_lights_node_geosphere[] = { }; channel const * const node_channels_node_geosphere[] = { - &node_channel_node_geosphere_scale, &node_channel_node_geosphere_inversescaleaxisrotation, &node_channel_node_geosphere_scaleaxisrotation, + &node_channel_node_geosphere_scale, }; node const node_node_geosphere = { @@ -1670,8 +1670,8 @@ instance_light const instance_lights_node_light[] = { channel const * const node_channels_node_light[] = { &node_channel_node_light_translation_z, - &node_channel_node_light_translation_x, &node_channel_node_light_translation_y, + &node_channel_node_light_translation_x, }; node const node_node_light = {