gltf: add parent node calculation

This commit is contained in:
Zack Buhman 2026-01-04 18:04:49 -06:00
parent 9111df6257
commit 07df5d9a1d
4 changed files with 47 additions and 8 deletions

View File

@ -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_

11
gltf_instance.hpp Normal file
View File

@ -0,0 +1,11 @@
#ifndef GLTF_INSTANCE_HPP_
#define GLTF_INSTANCE_HPP_
struct NodeInstance {
const Node * node;
D3DXVECTOR3 translation;
D3DXQUATERNION rotation;
D3DXVECTOR3 scale;
};
#endif

View File

@ -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())

20
tree.py Normal file
View File

@ -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)