From 07df5d9a1dcadf2a103ae2c0cfc4520cd0f9fcd1 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sun, 4 Jan 2026 18:04:49 -0600 Subject: [PATCH] gltf: add parent node calculation --- gltf.hpp | 12 +++++++----- gltf_instance.hpp | 11 +++++++++++ render_cpp.py | 12 +++++++++--- tree.py | 20 ++++++++++++++++++++ 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 gltf_instance.hpp create mode 100644 tree.py diff --git a/gltf.hpp b/gltf.hpp index 5eb089e..deb9f69 100644 --- a/gltf.hpp +++ b/gltf.hpp @@ -1,3 +1,6 @@ +#ifndef GLTF_HPP_ +#define GLTF_HPP_ + struct Mesh { const D3DXVECTOR3 * position; const DWORD position_size; @@ -21,6 +24,7 @@ struct Mesh { struct Skin; struct Node { + const DWORD parent_ix; const Skin * skin; // skin index (global) const Mesh * mesh; // mesh index (global) const D3DXVECTOR3 translation; @@ -50,12 +54,10 @@ struct AnimationSampler { struct AnimationChannel { const AnimationSampler * sampler; // sampler index, this animation struct { - const Node * node; // node index + const int node_ix; const AnimationChannelPath path; // property to animate } target; }; -//struct Animation { -// const AnimationChannel * channels; -// const AnimationSampler * samplers; -//}; +#ifndef GLTF_HPP_ +#define GLTF_HPP_ diff --git a/gltf_instance.hpp b/gltf_instance.hpp new file mode 100644 index 0000000..2ae1f31 --- /dev/null +++ b/gltf_instance.hpp @@ -0,0 +1,11 @@ +#ifndef GLTF_INSTANCE_HPP_ +#define GLTF_INSTANCE_HPP_ + +struct NodeInstance { + const Node * node; + D3DXVECTOR3 translation; + D3DXQUATERNION rotation; + D3DXVECTOR3 scale; +}; + +#endif diff --git a/render_cpp.py b/render_cpp.py index a1561eb..66f2ef8 100644 --- a/render_cpp.py +++ b/render_cpp.py @@ -6,8 +6,7 @@ from gltf import decode_file from gltf import validate_mesh from gltf import decode_accessor -filename = sys.argv[1] -gltf = decode_file(filename) +from tree import build_tree def type_name(type): return { @@ -101,6 +100,8 @@ def render_nodes(gltf): skin = node["skin"] yield f"extern const Skin skin_{skin};" + node_parents = build_tree(gltf) + for node_ix, node in enumerate(gltf.json["nodes"]): skin = f"&skin_{node['skin']}" if "skin" in node else "NULL" mesh = f"&mesh_{node['skin']}" if "mesh" in node else "NULL" @@ -115,7 +116,10 @@ def render_nodes(gltf): if "rotation" in node: rotation = node["rotation"] + parent_ix = node_parents.get(node_ix, -1) + yield f"const Node node_{node_ix} = {{" + yield f"{parent_ix}, // parent_ix" yield f"{skin}, // skin" yield f"{mesh}, // mesh" yield f"{render_value(translation, 'D3DXVECTOR3')}, // translation" @@ -155,7 +159,7 @@ def render_animation_channels(animation_ix, channels): target_path = channel["target"]["path"] yield f"&animation_{animation_ix}__sampler_{sampler}, // animation sampler" yield "{" - yield f"&node_{target_node}, // target node" + yield f"{target_node}, // target node index" yield f"ACP__{target_path.upper()}, // target path" yield "}," yield "};" @@ -172,6 +176,8 @@ def render_gltf(gltf): yield from render_skins(gltf) yield from render_animations(gltf) +filename = sys.argv[1] +gltf = decode_file(filename) render, out = renderer() render(render_gltf(gltf)) print(out.getvalue()) diff --git a/tree.py b/tree.py new file mode 100644 index 0000000..a963311 --- /dev/null +++ b/tree.py @@ -0,0 +1,20 @@ +from gltf import decode_file + +def build_tree(gltf): + parents = {} # from child to parent + + for node_ix, node in enumerate(gltf.json["nodes"]): + if "children" not in node: + continue + for child_ix in node["children"]: + assert child_ix > node_ix, (child_ix, node_ix) + assert child_ix not in parents + parents[child_ix] = node_ix + + return parents + +if __name__ == "__main__": + import sys + filename = sys.argv[1] + gltf = decode_file(filename) + build_tree(gltf)