collada/header: generate animation channels
This commit is contained in:
parent
802136c03c
commit
f939e70bf9
@ -17,7 +17,7 @@ def _render(out, lines):
|
||||
if l and (l[0] == "}" or l[0] == ")"):
|
||||
level -= 2
|
||||
if level < 0:
|
||||
assert namespace >= 0
|
||||
assert namespace >= 0, l
|
||||
namespace -= 1
|
||||
level = 0
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
from typing import Dict, List, Any
|
||||
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from itertools import islice, chain
|
||||
from io import BytesIO
|
||||
@ -34,12 +35,12 @@ class State:
|
||||
# symbol_names: C++ symbols/names already emitted
|
||||
symbol_names: Dict[str, Any]
|
||||
|
||||
# joint_sids
|
||||
joint_sids: Dict[str, types.Node]
|
||||
|
||||
# emitted_input_elements_arrays
|
||||
emitted_input_elements_arrays: Dict[str, tuple]
|
||||
|
||||
# channel nodes: node_id to list of sanitized target names
|
||||
node_animation_channels: Dict[str, set]
|
||||
|
||||
def __init__(self):
|
||||
self.vertex_buffer = BytesIO()
|
||||
self.index_buffer = BytesIO()
|
||||
@ -47,14 +48,15 @@ class State:
|
||||
self.geometry__vertex_index_tables = {}
|
||||
self.node_names = {}
|
||||
self.symbol_names = {}
|
||||
self.joint_sids = {}
|
||||
self.emitted_input_elements_arrays = {}
|
||||
self.node_animation_channels = defaultdict(set)
|
||||
|
||||
def sanitize_name(state, name, value):
|
||||
assert name is not None
|
||||
def sanitize_name(state, name, value, *, allow_slash=False):
|
||||
assert name is not None, value
|
||||
assert type(name) is str
|
||||
assert '/' not in name, name
|
||||
c_id = name.lower().replace('-', '_').replace('.', '_')
|
||||
if not allow_slash:
|
||||
assert '/' not in name, name
|
||||
c_id = name.lower().replace('-', '_').replace('.', '_').replace('/', '_')
|
||||
|
||||
assert c_id not in state.node_names or state.node_names[c_id] is value
|
||||
state.symbol_names[c_id] = value
|
||||
@ -282,20 +284,37 @@ def get_node_name_id(node):
|
||||
assert name is not None, node
|
||||
return name
|
||||
|
||||
def render_node(state, collada, node):
|
||||
if node.type is types.NodeType.JOINT:
|
||||
assert node.sid is not None, node.sid
|
||||
assert node.sid not in state.joint_sids, node.sid
|
||||
state.joint_sids[node.sid] = node
|
||||
def render_node_children(state, collada, node_name, nodes):
|
||||
yield f"node const * const node_children_{node_name} = {{"
|
||||
for node in nodes:
|
||||
node_name_id = get_node_name_id(node)
|
||||
node_name = sanitize_name(state, node_name_id, node)
|
||||
yield "&node_{node_name},"
|
||||
yield "};"
|
||||
|
||||
def render_node_channels(state, collada, node, node_name):
|
||||
if node.id is None:
|
||||
# nodes with no ID can't have channels
|
||||
yield f"channel const * const node_channels_{node_name}[] = {{}};"
|
||||
return
|
||||
|
||||
target_names = state.node_animation_channels[node.id]
|
||||
yield f"channel const * const node_channels_{node_name}[] = {{"
|
||||
for target_name in target_names:
|
||||
yield f"&node_channel_{target_name},"
|
||||
yield "};"
|
||||
|
||||
def render_node(state, collada, node):
|
||||
# render children first
|
||||
for node in node.nodes:
|
||||
yield from render_node(state, collada, node)
|
||||
for child_node in node.nodes:
|
||||
yield from render_node(state, collada, child_node)
|
||||
|
||||
node_name_id = get_node_name_id(node)
|
||||
node_name = sanitize_name(state, node_name_id, node)
|
||||
yield from render_node_children(state, collada, node_name, node.nodes)
|
||||
yield from render_node_transforms(state, collada, node_name, node.transformation_elements)
|
||||
yield from render_node_instance_geometries(state, collada, node_name, node.instance_geometries)
|
||||
yield from render_node_channels(state, collada, node, node_name)
|
||||
|
||||
type = {
|
||||
types.NodeType.JOINT: "JOINT",
|
||||
@ -310,6 +329,12 @@ def render_node(state, collada, node):
|
||||
yield ""
|
||||
yield f".instance_geometries = instance_geometries_{node_name},"
|
||||
yield f".instance_geometries_count = {len(node.instance_geometries)},"
|
||||
yield ""
|
||||
yield f".channels = node_channels_{node_name},"
|
||||
yield f".channels_count = {len(state.node_animation_channels[node.id])},"
|
||||
yield ""
|
||||
yield f".nodes = node_children_{node_name},"
|
||||
yield f".nodes_count = {len(node.nodes)},"
|
||||
yield "};"
|
||||
|
||||
def linear_nodes(collada):
|
||||
@ -446,13 +471,166 @@ def render_descriptor():
|
||||
def render_end_of_namespace():
|
||||
yield "}"
|
||||
|
||||
def render_animation_children(state, collada, animation_name, animations):
|
||||
yield f"node const * const animation_children_{animation_name} = {{"
|
||||
for animation in animations:
|
||||
animation_name = sanitize_name(state, animation.id, animation)
|
||||
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
|
||||
if type(array) is types.NameArray:
|
||||
assert accessor.stride == 1
|
||||
assert accessor.params[0].name == "INTERPOLATION"
|
||||
assert len(array.names) == accessor.count
|
||||
yield f"enum interpolation const array_{array_name}[] = {{"
|
||||
for name in array.names:
|
||||
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}[] = {{"
|
||||
it = iter(array.floats)
|
||||
for i in range(accessor.count):
|
||||
vector = ", ".join(f"{float(f)}f" for f in islice(it, accessor.stride))
|
||||
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)
|
||||
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 "},"
|
||||
|
||||
def render_sampler(state, collada, sampler):
|
||||
order = dict((s, i) for i, s in
|
||||
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])
|
||||
|
||||
# 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)
|
||||
|
||||
sampler_name = sanitize_name(state, sampler.id, sampler)
|
||||
yield f"sampler const sampler_{sampler_name} = {{"
|
||||
for input in inputs:
|
||||
source = collada.lookup(input.source, types.SourceCore)
|
||||
field_name = input.semantic.lower()
|
||||
yield from render_source(state, collada, field_name, source)
|
||||
yield "};"
|
||||
|
||||
target_attributes = {
|
||||
"A", "ANGLE", "B", "G", "P", "Q", "R", "S", "T", "TIME", "U", "V", "W", "X", "Y", "Z"
|
||||
}
|
||||
|
||||
def render_transform_type(transformation_element):
|
||||
return {
|
||||
types.Lookat: "LOOKAT",
|
||||
types.Matrix: "MATRIX",
|
||||
types.Rotate: "ROTATE",
|
||||
types.Scale: "SCALE",
|
||||
types.Skew: "SKEW",
|
||||
types.Translate: "TRANSLATE",
|
||||
}[type(transformation_element)]
|
||||
|
||||
def render_channel(state, collada, channel):
|
||||
sampler = collada.lookup(channel.source, types.Sampler)
|
||||
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(".")
|
||||
assert target_attribute in target_attributes
|
||||
|
||||
node = collada.lookup(f"#{node_id}", types.Node)
|
||||
node_name_id = get_node_name_id(node)
|
||||
node_name = sanitize_name(state, node_name_id, node)
|
||||
transformation_element = node.sid_lookup[node_transform_sid]
|
||||
|
||||
target_name = sanitize_name(state, channel.target, channel, allow_slash=True)
|
||||
assert target_name not in state.node_animation_channels[node.id]
|
||||
state.node_animation_channels[node.id].add(target_name)
|
||||
|
||||
yield f"channel const node_channel_{target_name} = {{"
|
||||
yield f".source_sampler = &sampler_{sampler_name},"
|
||||
yield f".target_transform_type = transform_type::{render_transform_type(transformation_element)},"
|
||||
yield f".target_attribute = target_attribute::{target_attribute},"
|
||||
yield "};"
|
||||
|
||||
def render_animation(state, collada, animation_name, animation):
|
||||
# render children first
|
||||
for i, child_animation in enumerate(animation.animations):
|
||||
child_animation_name = f"{animation_name}_{i}"
|
||||
yield from render_animation(state, collada, child_animation_name, child_animation)
|
||||
|
||||
# samplers (includes sources)
|
||||
for sampler in animation.samplers:
|
||||
yield from render_sampler(state, collada, sampler)
|
||||
|
||||
for channel in animation.channels:
|
||||
yield from render_channel(state, collada, channel)
|
||||
|
||||
# all animations channels are referenced from the node (inverse
|
||||
# the relationship in collada)
|
||||
#
|
||||
# I haven't considered how nested or layered animations are
|
||||
# affected by this inversion.
|
||||
|
||||
#yield f"animation const animation_{animation_name} = {{"
|
||||
#yield f".animations = animation_children_{animation_name},"
|
||||
#yield f".animations_count = {len(animation.animations)},"
|
||||
#yield ""
|
||||
#yield f".channels = animation_channels_{animation_name}"
|
||||
#yield f".channels_count = {len(animation.channels)}"
|
||||
#yield "};"
|
||||
|
||||
def render_library_animations(state, collada):
|
||||
animation_ix = 0
|
||||
for library_animations in collada.library_animations:
|
||||
for animation in library_animations.animations:
|
||||
animation_name = f"{animation_ix}"
|
||||
yield from render_animation(state, collada, animation_name, animation)
|
||||
animation_ix += 1
|
||||
|
||||
def render_all(collada, namespace):
|
||||
state = State()
|
||||
render, out = renderer()
|
||||
render(render_header(namespace))
|
||||
render(render_library_animations(state, collada))
|
||||
render(render_library_effects(state, collada))
|
||||
render(render_library_materials(state, collada))
|
||||
render(render_library_geometries(state, collada))
|
||||
|
||||
# root elements
|
||||
render(render_library_visual_scenes(state, collada))
|
||||
render(render_input_elements_list(state))
|
||||
render(render_descriptor())
|
||||
|
||||
@ -874,7 +874,7 @@ def parse_animation(lookup, root):
|
||||
sources.append(parse_source_core(lookup, child))
|
||||
if child.tag == tag("sampler"):
|
||||
samplers.append(parse_sampler(lookup, child))
|
||||
if child.tag == tag("channels"):
|
||||
if child.tag == tag("channel"):
|
||||
channels.append(parse_channel(lookup, child))
|
||||
|
||||
animation = types.Animation(id, name, animations, sources, samplers, channels)
|
||||
|
||||
@ -2,6 +2,11 @@
|
||||
|
||||
namespace collada {
|
||||
|
||||
struct float2 {
|
||||
float const x;
|
||||
float const y;
|
||||
};
|
||||
|
||||
struct float3 {
|
||||
float const x;
|
||||
float const y;
|
||||
@ -25,32 +30,6 @@ namespace collada {
|
||||
float const g;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// animation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class interpolation {
|
||||
LINEAR,
|
||||
BEZIER,
|
||||
};
|
||||
|
||||
struct source {
|
||||
union {
|
||||
float const * const float_array;
|
||||
enum interpolation const name_array;
|
||||
};
|
||||
int const count;
|
||||
int const stride;
|
||||
};
|
||||
|
||||
struct sampler {
|
||||
source const input;
|
||||
source const output;
|
||||
source const intangent;
|
||||
source const outangent;
|
||||
source const interpolation;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// geometry
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -228,6 +207,74 @@ namespace collada {
|
||||
int const instance_materials_count;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// animation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class interpolation {
|
||||
LINEAR,
|
||||
BEZIER,
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct sampler {
|
||||
source const input;
|
||||
source const output;
|
||||
source const in_tangent;
|
||||
source const out_tangent;
|
||||
source const interpolation;
|
||||
};
|
||||
|
||||
enum class target_attribute {
|
||||
A, // alpha color component
|
||||
ANGLE, // euler angle
|
||||
B, // blue color component
|
||||
G, // green color component
|
||||
P, // third texture component
|
||||
Q, // fourth texture component
|
||||
R, // red color component
|
||||
S, // first texture coordinate
|
||||
T, // second texture coordinate
|
||||
TIME, // time in seconds
|
||||
U, // first generic parameter
|
||||
V, // second generic parameter
|
||||
W, // fourth cartesian coordinate
|
||||
X, // first cartesian coordinate
|
||||
Y, // second cartesian coordinate
|
||||
Z, // third cartesian coordinate
|
||||
};
|
||||
|
||||
struct channel {
|
||||
sampler const * const source_sampler;
|
||||
int const target_node_index; // an index into the nodes array
|
||||
transform_type const target_transform_type;
|
||||
target_attribute const target_attribute;
|
||||
};
|
||||
|
||||
/*
|
||||
struct animation {
|
||||
animation const * const animations; // nested animations
|
||||
int const animations_count;
|
||||
|
||||
channels const * const channels;
|
||||
int const channels_count;
|
||||
};
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// scene
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct node {
|
||||
node_type const type;
|
||||
|
||||
@ -237,6 +284,9 @@ namespace collada {
|
||||
instance_geometry const * const instance_geometries;
|
||||
int const instance_geometries_count;
|
||||
|
||||
channel const * const * const channels;
|
||||
int const channels_count;
|
||||
|
||||
node const * const nodes;
|
||||
int const nodes_count;
|
||||
};
|
||||
@ -245,7 +295,10 @@ namespace collada {
|
||||
node const * const * const nodes;
|
||||
int const nodes_count;
|
||||
|
||||
inputs const * inputs_list;
|
||||
inputs const * const inputs_list;
|
||||
int const inputs_list_count;
|
||||
|
||||
//animation const * const animations;
|
||||
//int const animations_count;
|
||||
};
|
||||
}
|
||||
|
||||
@ -4,6 +4,144 @@ 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_type = transform_type::TRANSLATE,
|
||||
.target_attribute = target_attribute::X,
|
||||
};
|
||||
|
||||
channel const node_channel_node_cube_translation_y = {
|
||||
.source_sampler = &sampler_node_cube_translation_y_sampler,
|
||||
.target_transform_type = transform_type::TRANSLATE,
|
||||
.target_attribute = target_attribute::Y,
|
||||
};
|
||||
|
||||
effect const effect_material__15 = {
|
||||
.type = effect_type::BLINN,
|
||||
.blinn = {
|
||||
@ -372,12 +510,17 @@ geometry const * const geometries[] = {
|
||||
&geometry_geom_plane001,
|
||||
};
|
||||
|
||||
node const * const node_children_node_environmentambientlight = {
|
||||
};
|
||||
|
||||
transform const transforms_node_environmentambientlight[] = {
|
||||
};
|
||||
|
||||
instance_geometry const instance_geometries_node_environmentambientlight[] = {
|
||||
};
|
||||
|
||||
channel const * const node_channels_node_environmentambientlight[] = {};
|
||||
|
||||
node const node_node_environmentambientlight = {
|
||||
.type = node_type::NODE,
|
||||
|
||||
@ -386,6 +529,15 @@ node const node_node_environmentambientlight = {
|
||||
|
||||
.instance_geometries = instance_geometries_node_environmentambientlight,
|
||||
.instance_geometries_count = 0,
|
||||
|
||||
.channels = node_channels_node_environmentambientlight,
|
||||
.channels_count = 0,
|
||||
|
||||
.nodes = node_children_node_environmentambientlight,
|
||||
.nodes_count = 0,
|
||||
};
|
||||
|
||||
node const * const node_children_node_cube = {
|
||||
};
|
||||
|
||||
transform const transforms_node_cube[] = {
|
||||
@ -430,6 +582,11 @@ instance_geometry const instance_geometries_node_cube[] = {
|
||||
},
|
||||
};
|
||||
|
||||
channel const * const node_channels_node_cube[] = {
|
||||
&node_channel_node_cube_translation_x,
|
||||
&node_channel_node_cube_translation_y,
|
||||
};
|
||||
|
||||
node const node_node_cube = {
|
||||
.type = node_type::NODE,
|
||||
|
||||
@ -438,6 +595,15 @@ node const node_node_cube = {
|
||||
|
||||
.instance_geometries = instance_geometries_node_cube,
|
||||
.instance_geometries_count = 1,
|
||||
|
||||
.channels = node_channels_node_cube,
|
||||
.channels_count = 2,
|
||||
|
||||
.nodes = node_children_node_cube,
|
||||
.nodes_count = 0,
|
||||
};
|
||||
|
||||
node const * const node_children_node_cylinder001 = {
|
||||
};
|
||||
|
||||
transform const transforms_node_cylinder001[] = {
|
||||
@ -458,6 +624,9 @@ instance_geometry const instance_geometries_node_cylinder001[] = {
|
||||
},
|
||||
};
|
||||
|
||||
channel const * const node_channels_node_cylinder001[] = {
|
||||
};
|
||||
|
||||
node const node_node_cylinder001 = {
|
||||
.type = node_type::NODE,
|
||||
|
||||
@ -466,6 +635,15 @@ node const node_node_cylinder001 = {
|
||||
|
||||
.instance_geometries = instance_geometries_node_cylinder001,
|
||||
.instance_geometries_count = 1,
|
||||
|
||||
.channels = node_channels_node_cylinder001,
|
||||
.channels_count = 0,
|
||||
|
||||
.nodes = node_children_node_cylinder001,
|
||||
.nodes_count = 0,
|
||||
};
|
||||
|
||||
node const * const node_children_node_plane001 = {
|
||||
};
|
||||
|
||||
transform const transforms_node_plane001[] = {
|
||||
@ -494,6 +672,9 @@ instance_geometry const instance_geometries_node_plane001[] = {
|
||||
},
|
||||
};
|
||||
|
||||
channel const * const node_channels_node_plane001[] = {
|
||||
};
|
||||
|
||||
node const node_node_plane001 = {
|
||||
.type = node_type::NODE,
|
||||
|
||||
@ -502,6 +683,12 @@ node const node_node_plane001 = {
|
||||
|
||||
.instance_geometries = instance_geometries_node_plane001,
|
||||
.instance_geometries_count = 1,
|
||||
|
||||
.channels = node_channels_node_plane001,
|
||||
.channels_count = 0,
|
||||
|
||||
.nodes = node_children_node_plane001,
|
||||
.nodes_count = 0,
|
||||
};
|
||||
|
||||
node const * const nodes[] = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user