Compare commits

...

2 Commits

Author SHA1 Message Date
f939e70bf9 collada/header: generate animation channels 2026-01-26 20:47:22 -06:00
802136c03c collada_scene: render materials 2026-01-26 20:46:54 -06:00
11 changed files with 1691 additions and 873 deletions

View File

@ -17,7 +17,7 @@ def _render(out, lines):
if l and (l[0] == "}" or l[0] == ")"): if l and (l[0] == "}" or l[0] == ")"):
level -= 2 level -= 2
if level < 0: if level < 0:
assert namespace >= 0 assert namespace >= 0, l
namespace -= 1 namespace -= 1
level = 0 level = 0

View File

@ -1,5 +1,6 @@
from typing import Dict, List, Any from typing import Dict, List, Any
from collections import defaultdict
from dataclasses import dataclass from dataclasses import dataclass
from itertools import islice, chain from itertools import islice, chain
from io import BytesIO from io import BytesIO
@ -34,12 +35,12 @@ class State:
# symbol_names: C++ symbols/names already emitted # symbol_names: C++ symbols/names already emitted
symbol_names: Dict[str, Any] symbol_names: Dict[str, Any]
# joint_sids
joint_sids: Dict[str, types.Node]
# emitted_input_elements_arrays # emitted_input_elements_arrays
emitted_input_elements_arrays: Dict[str, tuple] 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): def __init__(self):
self.vertex_buffer = BytesIO() self.vertex_buffer = BytesIO()
self.index_buffer = BytesIO() self.index_buffer = BytesIO()
@ -47,14 +48,15 @@ class State:
self.geometry__vertex_index_tables = {} self.geometry__vertex_index_tables = {}
self.node_names = {} self.node_names = {}
self.symbol_names = {} self.symbol_names = {}
self.joint_sids = {}
self.emitted_input_elements_arrays = {} self.emitted_input_elements_arrays = {}
self.node_animation_channels = defaultdict(set)
def sanitize_name(state, name, value): def sanitize_name(state, name, value, *, allow_slash=False):
assert name is not None assert name is not None, value
assert type(name) is str assert type(name) is str
if not allow_slash:
assert '/' not in name, name assert '/' not in name, name
c_id = name.lower().replace('-', '_').replace('.', '_') c_id = name.lower().replace('-', '_').replace('.', '_').replace('/', '_')
assert c_id not in state.node_names or state.node_names[c_id] is value assert c_id not in state.node_names or state.node_names[c_id] is value
state.symbol_names[c_id] = value state.symbol_names[c_id] = value
@ -282,20 +284,37 @@ def get_node_name_id(node):
assert name is not None, node assert name is not None, node
return name return name
def render_node(state, collada, node): def render_node_children(state, collada, node_name, nodes):
if node.type is types.NodeType.JOINT: yield f"node const * const node_children_{node_name} = {{"
assert node.sid is not None, node.sid for node in nodes:
assert node.sid not in state.joint_sids, node.sid node_name_id = get_node_name_id(node)
state.joint_sids[node.sid] = 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 # render children first
for node in node.nodes: for child_node in node.nodes:
yield from render_node(state, collada, node) yield from render_node(state, collada, child_node)
node_name_id = get_node_name_id(node) node_name_id = get_node_name_id(node)
node_name = sanitize_name(state, 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_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_instance_geometries(state, collada, node_name, node.instance_geometries)
yield from render_node_channels(state, collada, node, node_name)
type = { type = {
types.NodeType.JOINT: "JOINT", types.NodeType.JOINT: "JOINT",
@ -310,6 +329,12 @@ def render_node(state, collada, node):
yield "" yield ""
yield f".instance_geometries = instance_geometries_{node_name}," yield f".instance_geometries = instance_geometries_{node_name},"
yield f".instance_geometries_count = {len(node.instance_geometries)}," 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 "};" yield "};"
def linear_nodes(collada): def linear_nodes(collada):
@ -446,13 +471,166 @@ def render_descriptor():
def render_end_of_namespace(): def render_end_of_namespace():
yield "}" 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): def render_all(collada, namespace):
state = State() state = State()
render, out = renderer() render, out = renderer()
render(render_header(namespace)) render(render_header(namespace))
render(render_library_animations(state, collada))
render(render_library_effects(state, collada)) render(render_library_effects(state, collada))
render(render_library_materials(state, collada)) render(render_library_materials(state, collada))
render(render_library_geometries(state, collada)) render(render_library_geometries(state, collada))
# root elements
render(render_library_visual_scenes(state, collada)) render(render_library_visual_scenes(state, collada))
render(render_input_elements_list(state)) render(render_input_elements_list(state))
render(render_descriptor()) render(render_descriptor())

View File

@ -874,7 +874,7 @@ def parse_animation(lookup, root):
sources.append(parse_source_core(lookup, child)) sources.append(parse_source_core(lookup, child))
if child.tag == tag("sampler"): if child.tag == tag("sampler"):
samplers.append(parse_sampler(lookup, child)) samplers.append(parse_sampler(lookup, child))
if child.tag == tag("channels"): if child.tag == tag("channel"):
channels.append(parse_channel(lookup, child)) channels.append(parse_channel(lookup, child))
animation = types.Animation(id, name, animations, sources, samplers, channels) animation = types.Animation(id, name, animations, sources, samplers, channels)

View File

@ -2,6 +2,11 @@
namespace collada { namespace collada {
struct float2 {
float const x;
float const y;
};
struct float3 { struct float3 {
float const x; float const x;
float const y; float const y;
@ -25,32 +30,6 @@ namespace collada {
float const g; 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 // geometry
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -228,6 +207,74 @@ namespace collada {
int const instance_materials_count; 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 { struct node {
node_type const type; node_type const type;
@ -237,6 +284,9 @@ namespace collada {
instance_geometry const * const instance_geometries; instance_geometry const * const instance_geometries;
int const instance_geometries_count; int const instance_geometries_count;
channel const * const * const channels;
int const channels_count;
node const * const nodes; node const * const nodes;
int const nodes_count; int const nodes_count;
}; };
@ -245,7 +295,10 @@ namespace collada {
node const * const * const nodes; node const * const * const nodes;
int const nodes_count; int const nodes_count;
inputs const * inputs_list; inputs const * const inputs_list;
int const inputs_list_count; int const inputs_list_count;
//animation const * const animations;
//int const animations_count;
}; };
} }

View File

@ -4,6 +4,144 @@ namespace curve_interpolation {
using namespace collada; 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 = { effect const effect_material__15 = {
.type = effect_type::BLINN, .type = effect_type::BLINN,
.blinn = { .blinn = {
@ -372,12 +510,17 @@ geometry const * const geometries[] = {
&geometry_geom_plane001, &geometry_geom_plane001,
}; };
node const * const node_children_node_environmentambientlight = {
};
transform const transforms_node_environmentambientlight[] = { transform const transforms_node_environmentambientlight[] = {
}; };
instance_geometry const instance_geometries_node_environmentambientlight[] = { instance_geometry const instance_geometries_node_environmentambientlight[] = {
}; };
channel const * const node_channels_node_environmentambientlight[] = {};
node const node_node_environmentambientlight = { node const node_node_environmentambientlight = {
.type = node_type::NODE, .type = node_type::NODE,
@ -386,6 +529,15 @@ node const node_node_environmentambientlight = {
.instance_geometries = instance_geometries_node_environmentambientlight, .instance_geometries = instance_geometries_node_environmentambientlight,
.instance_geometries_count = 0, .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[] = { 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 = { node const node_node_cube = {
.type = node_type::NODE, .type = node_type::NODE,
@ -438,6 +595,15 @@ node const node_node_cube = {
.instance_geometries = instance_geometries_node_cube, .instance_geometries = instance_geometries_node_cube,
.instance_geometries_count = 1, .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[] = { 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 = { node const node_node_cylinder001 = {
.type = node_type::NODE, .type = node_type::NODE,
@ -466,6 +635,15 @@ node const node_node_cylinder001 = {
.instance_geometries = instance_geometries_node_cylinder001, .instance_geometries = instance_geometries_node_cylinder001,
.instance_geometries_count = 1, .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[] = { 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 = { node const node_node_plane001 = {
.type = node_type::NODE, .type = node_type::NODE,
@ -502,6 +683,12 @@ node const node_node_plane001 = {
.instance_geometries = instance_geometries_node_plane001, .instance_geometries = instance_geometries_node_plane001,
.instance_geometries_count = 1, .instance_geometries_count = 1,
.channels = node_channels_node_plane001,
.channels_count = 0,
.nodes = node_children_node_plane001,
.nodes_count = 0,
}; };
node const * const nodes[] = { node const * const nodes[] = {

View File

@ -6,8 +6,8 @@
<authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool> <authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool>
<source_data>file:///C:/cygwin/home/bilbo/d3d10/models/curve_interpolation/curve_interpolation.max</source_data> <source_data>file:///C:/cygwin/home/bilbo/d3d10/models/curve_interpolation/curve_interpolation.max</source_data>
</contributor> </contributor>
<created>2026-01-25T13:40:01</created> <created>2026-01-26T20:45:12</created>
<modified>2026-01-25T13:40:01</modified> <modified>2026-01-26T20:45:12</modified>
<unit name="inch" meter="0.0254"/> <unit name="inch" meter="0.0254"/>
<up_axis>Z_UP</up_axis> <up_axis>Z_UP</up_axis>
</asset> </asset>
@ -622,15 +622,15 @@
<instance_light url="#EnvironmentAmbientLight"/> <instance_light url="#EnvironmentAmbientLight"/>
</node> </node>
<node id="node-Cube" name="Cube"> <node id="node-Cube" name="Cube">
<translate sid="translation">10 0 0</translate> <translate sid="translation">10 -1.14258e-7 0</translate>
<instance_geometry url="#geom-Cube"> <instance_geometry url="#geom-Cube">
<bind_material> <bind_material>
<technique_common> <technique_common>
<instance_material symbol="Material__15_1" target="#Material__15-material"/> <instance_material symbol="Material__15_1" target="#Material__15-material"/>
<instance_material symbol="Material__16_1" target="#Material__16-material"/>
<instance_material symbol="Material__17_1" target="#Material__17-material"/> <instance_material symbol="Material__17_1" target="#Material__17-material"/>
<instance_material symbol="Material__18_1" target="#Material__18-material"/> <instance_material symbol="Material__18_1" target="#Material__18-material"/>
<instance_material symbol="Material__19_1" target="#Material__19-material"/> <instance_material symbol="Material__19_1" target="#Material__19-material"/>
<instance_material symbol="Material__16_1" target="#Material__16-material"/>
<instance_material symbol="Material__20_1" target="#Material__20-material"/> <instance_material symbol="Material__20_1" target="#Material__20-material"/>
</technique_common> </technique_common>
</bind_material> </bind_material>

View File

@ -6,24 +6,27 @@
<authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool> <authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool>
<source_data>file:///C:/cygwin/home/bilbo/d3d10/models/skinned_cube/skinned_cube.max</source_data> <source_data>file:///C:/cygwin/home/bilbo/d3d10/models/skinned_cube/skinned_cube.max</source_data>
</contributor> </contributor>
<created>2026-01-24T13:01:29</created> <created>2026-01-25T14:06:19</created>
<modified>2026-01-24T13:01:29</modified> <modified>2026-01-25T14:06:19</modified>
<unit name="inch" meter="0.0254"/> <unit name="inch" meter="0.0254"/>
<up_axis>Z_UP</up_axis> <up_axis>Z_UP</up_axis>
</asset> </asset>
<library_effects> <library_effects>
<effect id="ColorEffectR26G177B26"> <effect id="Material__13">
<profile_COMMON> <profile_COMMON>
<technique sid="common"> <technique sid="common">
<phong> <blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient> <ambient>
<color>0.1019608 0.6941176 0.1019608 1</color> <color>0.5882353 0.5882353 1 1</color>
</ambient> </ambient>
<diffuse> <diffuse>
<color>0.1019608 0.6941176 0.1019608 1</color> <color>0.5882353 0.5882353 1 1</color>
</diffuse> </diffuse>
<specular> <specular>
<color>1 1 1 1</color> <color>0 0 0 1</color>
</specular> </specular>
<shininess> <shininess>
<float>10</float> <float>10</float>
@ -31,20 +34,339 @@
<reflective> <reflective>
<color>0 0 0 1</color> <color>0 0 0 1</color>
</reflective> </reflective>
<transparent> <transparent opaque="A_ONE">
<color>1 1 1 1</color> <color>1 1 1 1</color>
</transparent> </transparent>
<transparency> <transparency>
<float>1</float> <float>1</float>
</transparency> </transparency>
</phong> </blinn>
</technique> </technique>
</profile_COMMON> </profile_COMMON>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<extended_shader>
<opacity_type sid="opacity_type" type="int">0</opacity_type>
<falloff_type sid="falloff_type" type="int">0</falloff_type>
<falloff sid="falloff" type="float">0</falloff>
<index_of_refraction sid="index_of_refraction" type="float">1.5</index_of_refraction>
<wire_size sid="wire_size" type="float">1</wire_size>
<wire_units sid="wire_units" type="int">0</wire_units>
<apply_reflection_dimming sid="apply_reflection_dimming" type="bool">0</apply_reflection_dimming>
<dim_level sid="dim_level" type="float">0</dim_level>
<reflection_level sid="reflection_level" type="float">3</reflection_level>
</extended_shader>
<shader>
<ambient_diffuse_texture_lock sid="ambient_diffuse_texture_lock" type="bool">1</ambient_diffuse_texture_lock>
<ambient_diffuse_lock sid="ambient_diffuse_lock" type="bool">1</ambient_diffuse_lock>
<diffuse_specular_lock sid="diffuse_specular_lock" type="bool">0</diffuse_specular_lock>
<use_self_illum_color sid="use_self_illum_color" type="bool">0</use_self_illum_color>
<self_illumination sid="self_illumination" type="float">0</self_illumination>
<specular_level sid="specular_level" type="float">0</specular_level>
<soften sid="soften" type="float">0.1</soften>
</shader>
</technique>
</extra>
</effect>
<effect id="Material__14">
<profile_COMMON>
<technique sid="common">
<blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0.5882353 0.9450981 1 1</color>
</ambient>
<diffuse>
<color>0.5882353 0.9450981 1 1</color>
</diffuse>
<specular>
<color>0 0 0 1</color>
</specular>
<shininess>
<float>10</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<transparent opaque="A_ONE">
<color>1 1 1 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
</blinn>
</technique>
</profile_COMMON>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<extended_shader>
<opacity_type sid="opacity_type" type="int">0</opacity_type>
<falloff_type sid="falloff_type" type="int">0</falloff_type>
<falloff sid="falloff" type="float">0</falloff>
<index_of_refraction sid="index_of_refraction" type="float">1.5</index_of_refraction>
<wire_size sid="wire_size" type="float">1</wire_size>
<wire_units sid="wire_units" type="int">0</wire_units>
<apply_reflection_dimming sid="apply_reflection_dimming" type="bool">0</apply_reflection_dimming>
<dim_level sid="dim_level" type="float">0</dim_level>
<reflection_level sid="reflection_level" type="float">3</reflection_level>
</extended_shader>
<shader>
<ambient_diffuse_texture_lock sid="ambient_diffuse_texture_lock" type="bool">1</ambient_diffuse_texture_lock>
<ambient_diffuse_lock sid="ambient_diffuse_lock" type="bool">1</ambient_diffuse_lock>
<diffuse_specular_lock sid="diffuse_specular_lock" type="bool">0</diffuse_specular_lock>
<use_self_illum_color sid="use_self_illum_color" type="bool">0</use_self_illum_color>
<self_illumination sid="self_illumination" type="float">0</self_illumination>
<specular_level sid="specular_level" type="float">0</specular_level>
<soften sid="soften" type="float">0.1</soften>
</shader>
</technique>
</extra>
</effect>
<effect id="Material__15">
<profile_COMMON>
<technique sid="common">
<blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0.5882353 1 0.6156863 1</color>
</ambient>
<diffuse>
<color>0.5882353 1 0.6156863 1</color>
</diffuse>
<specular>
<color>0 0 0 1</color>
</specular>
<shininess>
<float>10</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<transparent opaque="A_ONE">
<color>1 1 1 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
</blinn>
</technique>
</profile_COMMON>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<extended_shader>
<opacity_type sid="opacity_type" type="int">0</opacity_type>
<falloff_type sid="falloff_type" type="int">0</falloff_type>
<falloff sid="falloff" type="float">0</falloff>
<index_of_refraction sid="index_of_refraction" type="float">1.5</index_of_refraction>
<wire_size sid="wire_size" type="float">1</wire_size>
<wire_units sid="wire_units" type="int">0</wire_units>
<apply_reflection_dimming sid="apply_reflection_dimming" type="bool">0</apply_reflection_dimming>
<dim_level sid="dim_level" type="float">0</dim_level>
<reflection_level sid="reflection_level" type="float">3</reflection_level>
</extended_shader>
<shader>
<ambient_diffuse_texture_lock sid="ambient_diffuse_texture_lock" type="bool">1</ambient_diffuse_texture_lock>
<ambient_diffuse_lock sid="ambient_diffuse_lock" type="bool">1</ambient_diffuse_lock>
<diffuse_specular_lock sid="diffuse_specular_lock" type="bool">0</diffuse_specular_lock>
<use_self_illum_color sid="use_self_illum_color" type="bool">0</use_self_illum_color>
<self_illumination sid="self_illumination" type="float">0</self_illumination>
<specular_level sid="specular_level" type="float">0</specular_level>
<soften sid="soften" type="float">0.1</soften>
</shader>
</technique>
</extra>
</effect>
<effect id="Material__16">
<profile_COMMON>
<technique sid="common">
<blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0.9960785 1 0.5882353 1</color>
</ambient>
<diffuse>
<color>0.9960785 1 0.5882353 1</color>
</diffuse>
<specular>
<color>0 0 0 1</color>
</specular>
<shininess>
<float>10</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<transparent opaque="A_ONE">
<color>1 1 1 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
</blinn>
</technique>
</profile_COMMON>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<extended_shader>
<opacity_type sid="opacity_type" type="int">0</opacity_type>
<falloff_type sid="falloff_type" type="int">0</falloff_type>
<falloff sid="falloff" type="float">0</falloff>
<index_of_refraction sid="index_of_refraction" type="float">1.5</index_of_refraction>
<wire_size sid="wire_size" type="float">1</wire_size>
<wire_units sid="wire_units" type="int">0</wire_units>
<apply_reflection_dimming sid="apply_reflection_dimming" type="bool">0</apply_reflection_dimming>
<dim_level sid="dim_level" type="float">0</dim_level>
<reflection_level sid="reflection_level" type="float">3</reflection_level>
</extended_shader>
<shader>
<ambient_diffuse_texture_lock sid="ambient_diffuse_texture_lock" type="bool">1</ambient_diffuse_texture_lock>
<ambient_diffuse_lock sid="ambient_diffuse_lock" type="bool">1</ambient_diffuse_lock>
<diffuse_specular_lock sid="diffuse_specular_lock" type="bool">0</diffuse_specular_lock>
<use_self_illum_color sid="use_self_illum_color" type="bool">0</use_self_illum_color>
<self_illumination sid="self_illumination" type="float">0</self_illumination>
<specular_level sid="specular_level" type="float">0</specular_level>
<soften sid="soften" type="float">0.1</soften>
</shader>
</technique>
</extra>
</effect>
<effect id="Material__17">
<profile_COMMON>
<technique sid="common">
<blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0.9960785 0.8196079 0.5882353 1</color>
</ambient>
<diffuse>
<color>0.9960785 0.8196079 0.5882353 1</color>
</diffuse>
<specular>
<color>0 0 0 1</color>
</specular>
<shininess>
<float>10</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<transparent opaque="A_ONE">
<color>1 1 1 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
</blinn>
</technique>
</profile_COMMON>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<extended_shader>
<opacity_type sid="opacity_type" type="int">0</opacity_type>
<falloff_type sid="falloff_type" type="int">0</falloff_type>
<falloff sid="falloff" type="float">0</falloff>
<index_of_refraction sid="index_of_refraction" type="float">1.5</index_of_refraction>
<wire_size sid="wire_size" type="float">1</wire_size>
<wire_units sid="wire_units" type="int">0</wire_units>
<apply_reflection_dimming sid="apply_reflection_dimming" type="bool">0</apply_reflection_dimming>
<dim_level sid="dim_level" type="float">0</dim_level>
<reflection_level sid="reflection_level" type="float">3</reflection_level>
</extended_shader>
<shader>
<ambient_diffuse_texture_lock sid="ambient_diffuse_texture_lock" type="bool">1</ambient_diffuse_texture_lock>
<ambient_diffuse_lock sid="ambient_diffuse_lock" type="bool">1</ambient_diffuse_lock>
<diffuse_specular_lock sid="diffuse_specular_lock" type="bool">0</diffuse_specular_lock>
<use_self_illum_color sid="use_self_illum_color" type="bool">0</use_self_illum_color>
<self_illumination sid="self_illumination" type="float">0</self_illumination>
<specular_level sid="specular_level" type="float">0</specular_level>
<soften sid="soften" type="float">0.1</soften>
</shader>
</technique>
</extra>
</effect>
<effect id="Material__18">
<profile_COMMON>
<technique sid="common">
<blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>1 0.5882353 0.5882353 1</color>
</ambient>
<diffuse>
<color>1 0.5882353 0.5882353 1</color>
</diffuse>
<specular>
<color>0 0 0 1</color>
</specular>
<shininess>
<float>10</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<transparent opaque="A_ONE">
<color>1 1 1 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
</blinn>
</technique>
</profile_COMMON>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<extended_shader>
<opacity_type sid="opacity_type" type="int">0</opacity_type>
<falloff_type sid="falloff_type" type="int">0</falloff_type>
<falloff sid="falloff" type="float">0</falloff>
<index_of_refraction sid="index_of_refraction" type="float">1.5</index_of_refraction>
<wire_size sid="wire_size" type="float">1</wire_size>
<wire_units sid="wire_units" type="int">0</wire_units>
<apply_reflection_dimming sid="apply_reflection_dimming" type="bool">0</apply_reflection_dimming>
<dim_level sid="dim_level" type="float">0</dim_level>
<reflection_level sid="reflection_level" type="float">3</reflection_level>
</extended_shader>
<shader>
<ambient_diffuse_texture_lock sid="ambient_diffuse_texture_lock" type="bool">1</ambient_diffuse_texture_lock>
<ambient_diffuse_lock sid="ambient_diffuse_lock" type="bool">1</ambient_diffuse_lock>
<diffuse_specular_lock sid="diffuse_specular_lock" type="bool">0</diffuse_specular_lock>
<use_self_illum_color sid="use_self_illum_color" type="bool">0</use_self_illum_color>
<self_illumination sid="self_illumination" type="float">0</self_illumination>
<specular_level sid="specular_level" type="float">0</specular_level>
<soften sid="soften" type="float">0.1</soften>
</shader>
</technique>
</extra>
</effect> </effect>
</library_effects> </library_effects>
<library_materials> <library_materials>
<material id="ColorEffectR26G177B26-material" name="ColorEffectR26G177B26-material"> <material id="Material__13-material" name="Material__13">
<instance_effect url="#ColorEffectR26G177B26"/> <instance_effect url="#Material__13"/>
</material>
<material id="Material__14-material" name="Material__14">
<instance_effect url="#Material__14"/>
</material>
<material id="Material__15-material" name="Material__15">
<instance_effect url="#Material__15"/>
</material>
<material id="Material__16-material" name="Material__16">
<instance_effect url="#Material__16"/>
</material>
<material id="Material__17-material" name="Material__17">
<instance_effect url="#Material__17"/>
</material>
<material id="Material__18-material" name="Material__18">
<instance_effect url="#Material__18"/>
</material> </material>
</library_materials> </library_materials>
<library_geometries> <library_geometries>
@ -71,9 +393,9 @@
</technique_common> </technique_common>
</source> </source>
<source id="geom-Box001-map1"> <source id="geom-Box001-map1">
<float_array id="geom-Box001-map1-array" count="84">0 0 0 1 0 0 0 0.2 0 1 0.2 0 0 0.4 0 1 0.4 0 0 0.6 0 1 0.6 0 0 0.8 0 1 0.8 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0.2 0 1 0.2 0 0 0.4 0 1 0.4 0 0 0.6 0 1 0.6 0 0 0.8 0 1 0.8 0 0 1 0 1 1 0 0 0 0 1 0 0 0 1 0 1 1 0</float_array> <float_array id="geom-Box001-map1-array" count="168">1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0.2 0 1 0.2 0 0 0.4 0 1 0.4 0 0 0.6 0 1 0.6 0 0 0.8 0 1 0.8 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0.2 0 1 0.2 0 0 0.4 0 1 0.4 0 0 0.6 0 1 0.6 0 0 0.8 0 1 0.8 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0.2 0 1 0.2 0 0 0.4 0 1 0.4 0 0 0.6 0 1 0.6 0 0 0.8 0 1 0.8 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0.2 0 1 0.2 0 0 0.4 0 1 0.4 0 0 0.6 0 1 0.6 0 0 0.8 0 1 0.8 0 0 1 0 1 1 0</float_array>
<technique_common> <technique_common>
<accessor source="#geom-Box001-map1-array" count="28" stride="3"> <accessor source="#geom-Box001-map1-array" count="56" stride="3">
<param name="S" type="float"/> <param name="S" type="float"/>
<param name="T" type="float"/> <param name="T" type="float"/>
<param name="P" type="float"/> <param name="P" type="float"/>
@ -83,26 +405,43 @@
<vertices id="geom-Box001-vertices"> <vertices id="geom-Box001-vertices">
<input semantic="POSITION" source="#geom-Box001-positions"/> <input semantic="POSITION" source="#geom-Box001-positions"/>
</vertices> </vertices>
<triangles material="ColorMaterial" count="44"> <triangles material="Material__14_1" count="2">
<input semantic="VERTEX" source="#geom-Box001-vertices" offset="0"/> <input semantic="VERTEX" source="#geom-Box001-vertices" offset="0"/>
<input semantic="NORMAL" source="#geom-Box001-normals" offset="1"/> <input semantic="NORMAL" source="#geom-Box001-normals" offset="1"/>
<input semantic="TEXCOORD" source="#geom-Box001-map1" offset="2" set="0"/> <input semantic="TEXCOORD" source="#geom-Box001-map1" offset="2" set="0"/>
<p>0 0 25 2 1 27 3 2 26 3 2 26 1 3 24 0 0 25 4 4 24 5 5 25 7 6 27 7 6 27 6 7 26 4 4 24 0 8 12 1 9 13 9 10 15 9 10 15 8 11 14 0 8 12 8 11 14 9 10 15 13 12 17 13 12 17 12 13 16 8 11 14 12 13 16 13 12 17 17 14 19 17 14 19 16 15 18 12 13 16 16 15 18 17 14 19 21 16 21 21 16 21 20 17 20 16 15 18 20 17 20 21 16 21 5 18 23 5 18 23 4 19 22 20 17 20 1 20 0 3 21 1 10 22 3 10 22 3 9 23 2 1 20 0 9 23 2 10 22 3 14 24 5 14 24 5 13 25 4 9 23 2 13 25 4 14 24 5 18 26 7 18 26 7 17 27 6 13 25 4 17 27 6 18 26 7 22 28 9 22 28 9 21 29 8 17 27 6 21 29 8 22 28 9 7 30 11 7 30 11 5 31 10 21 29 8 3 32 12 2 33 13 11 34 15 11 34 15 10 35 14 3 32 12 10 35 14 11 34 15 15 36 17 15 36 17 14 37 16 10 35 14 14 37 16 15 36 17 19 38 19 19 38 19 18 39 18 14 37 16 18 39 18 19 38 19 23 40 21 23 40 21 22 41 20 18 39 18 22 41 20 23 40 21 6 42 23 6 42 23 7 43 22 22 41 20 2 44 0 0 45 1 8 46 3 8 46 3 11 47 2 2 44 0 11 47 2 8 46 3 12 48 5 12 48 5 15 49 4 11 47 2 15 49 4 12 48 5 16 50 7 16 50 7 19 51 6 15 49 4 19 51 6 16 50 7 20 52 9 20 52 9 23 53 8 19 51 6 23 53 8 20 52 9 4 54 11 4 54 11 6 55 10 23 53 8</p> <p>0 0 0 2 1 2 3 2 3 3 2 3 1 3 1 0 0 0</p>
</triangles>
<triangles material="Material__13_1" count="2">
<input semantic="VERTEX" source="#geom-Box001-vertices" offset="0"/>
<input semantic="NORMAL" source="#geom-Box001-normals" offset="1"/>
<input semantic="TEXCOORD" source="#geom-Box001-map1" offset="2" set="0"/>
<p>4 4 4 5 5 5 7 6 7 7 6 7 6 7 6 4 4 4</p>
</triangles>
<triangles material="Material__17_1" count="10">
<input semantic="VERTEX" source="#geom-Box001-vertices" offset="0"/>
<input semantic="NORMAL" source="#geom-Box001-normals" offset="1"/>
<input semantic="TEXCOORD" source="#geom-Box001-map1" offset="2" set="0"/>
<p>0 8 8 1 9 9 9 10 11 9 10 11 8 11 10 0 8 8 8 11 10 9 10 11 13 12 13 13 12 13 12 13 12 8 11 10 12 13 12 13 12 13 17 14 15 17 14 15 16 15 14 12 13 12 16 15 14 17 14 15 21 16 17 21 16 17 20 17 16 16 15 14 20 17 16 21 16 17 5 18 19 5 18 19 4 19 18 20 17 16</p>
</triangles>
<triangles material="Material__16_1" count="10">
<input semantic="VERTEX" source="#geom-Box001-vertices" offset="0"/>
<input semantic="NORMAL" source="#geom-Box001-normals" offset="1"/>
<input semantic="TEXCOORD" source="#geom-Box001-map1" offset="2" set="0"/>
<p>1 20 20 3 21 21 10 22 23 10 22 23 9 23 22 1 20 20 9 23 22 10 22 23 14 24 25 14 24 25 13 25 24 9 23 22 13 25 24 14 24 25 18 26 27 18 26 27 17 27 26 13 25 24 17 27 26 18 26 27 22 28 29 22 28 29 21 29 28 17 27 26 21 29 28 22 28 29 7 30 31 7 30 31 5 31 30 21 29 28</p>
</triangles>
<triangles material="Material__18_1" count="10">
<input semantic="VERTEX" source="#geom-Box001-vertices" offset="0"/>
<input semantic="NORMAL" source="#geom-Box001-normals" offset="1"/>
<input semantic="TEXCOORD" source="#geom-Box001-map1" offset="2" set="0"/>
<p>3 32 32 2 33 33 11 34 35 11 34 35 10 35 34 3 32 32 10 35 34 11 34 35 15 36 37 15 36 37 14 37 36 10 35 34 14 37 36 15 36 37 19 38 39 19 38 39 18 39 38 14 37 36 18 39 38 19 38 39 23 40 41 23 40 41 22 41 40 18 39 38 22 41 40 23 40 41 6 42 43 6 42 43 7 43 42 22 41 40</p>
</triangles>
<triangles material="Material__15_1" count="10">
<input semantic="VERTEX" source="#geom-Box001-vertices" offset="0"/>
<input semantic="NORMAL" source="#geom-Box001-normals" offset="1"/>
<input semantic="TEXCOORD" source="#geom-Box001-map1" offset="2" set="0"/>
<p>2 44 44 0 45 45 8 46 47 8 46 47 11 47 46 2 44 44 11 47 46 8 46 47 12 48 49 12 48 49 15 49 48 11 47 46 15 49 48 12 48 49 16 50 51 16 50 51 19 51 50 15 49 48 19 51 50 16 50 51 20 52 53 20 52 53 23 53 52 19 51 50 23 53 52 20 52 53 4 54 55 4 54 55 6 55 54 23 53 52</p>
</triangles> </triangles>
</mesh> </mesh>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<max_box>
<length sid="length" type="float">10</length>
<width sid="width" type="float">10</width>
<height sid="height" type="float">20</height>
<widthsegments sid="widthsegments" type="int">1</widthsegments>
<lengthsegments sid="lengthsegments" type="int">1</lengthsegments>
<heightsegments sid="heightsegments" type="int">5</heightsegments>
<generateuvs sid="generateuvs" type="int">1</generateuvs>
</max_box>
</technique>
</extra>
</geometry> </geometry>
</library_geometries> </library_geometries>
<library_controllers> <library_controllers>
@ -165,7 +504,12 @@
<skeleton>#node-Bone001</skeleton> <skeleton>#node-Bone001</skeleton>
<bind_material> <bind_material>
<technique_common> <technique_common>
<instance_material symbol="ColorMaterial" target="#ColorEffectR26G177B26-material"/> <instance_material symbol="Material__16_1" target="#Material__16-material"/>
<instance_material symbol="Material__17_1" target="#Material__17-material"/>
<instance_material symbol="Material__18_1" target="#Material__18-material"/>
<instance_material symbol="Material__13_1" target="#Material__13-material"/>
<instance_material symbol="Material__14_1" target="#Material__14-material"/>
<instance_material symbol="Material__15_1" target="#Material__15-material"/>
</technique_common> </technique_common>
</bind_material> </bind_material>
</instance_controller> </instance_controller>

Binary file not shown.

View File

@ -21,6 +21,12 @@ namespace collada_scene {
ID3D10EffectMatrixVariable * g_pViewVariable = NULL; ID3D10EffectMatrixVariable * g_pViewVariable = NULL;
ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL; ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL;
ID3D10EffectVectorVariable * g_pEmissionVariable = NULL;
ID3D10EffectVectorVariable * g_pAmbientVariable = NULL;
ID3D10EffectVectorVariable * g_pDiffuseVariable = NULL;
ID3D10EffectVectorVariable * g_pSpecularVariable = NULL;
ID3D10EffectScalarVariable * g_pShininessVariable = NULL;
static inline DXGI_FORMAT dxgi_format(input_format format) static inline DXGI_FORMAT dxgi_format(input_format format)
{ {
switch (format) { switch (format) {
@ -90,7 +96,7 @@ namespace collada_scene {
bd.Usage = D3D10_USAGE_IMMUTABLE; bd.Usage = D3D10_USAGE_IMMUTABLE;
bd.ByteWidth = dwResSize; bd.ByteWidth = dwResSize;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0; bd.CPUAccessFlags = 0;
bd.MiscFlags = 0; bd.MiscFlags = 0;
initData.pSysMem = pData; initData.pSysMem = pData;
@ -188,6 +194,12 @@ namespace collada_scene {
g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix(); g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix();
g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix(); g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix();
g_pEmissionVariable = g_pEffect->GetVariableByName("Emission")->AsVector();
g_pAmbientVariable = g_pEffect->GetVariableByName("Ambient")->AsVector();
g_pDiffuseVariable = g_pEffect->GetVariableByName("Diffuse")->AsVector();
g_pSpecularVariable = g_pEffect->GetVariableByName("Specular")->AsVector();
g_pShininessVariable = g_pEffect->GetVariableByName("Shininess")->AsScalar();
return S_OK; return S_OK;
} }
@ -232,13 +244,42 @@ namespace collada_scene {
} }
} }
static inline void SetMaterial(effect const& effect)
{
switch (effect.type) {
case effect_type::BLINN:
g_pEmissionVariable->SetFloatVector((float *)&effect.blinn.emission.color.x);
g_pAmbientVariable->SetFloatVector((float *)&effect.blinn.ambient.color.x);
g_pDiffuseVariable->SetFloatVector((float *)&effect.blinn.diffuse.color.x);
g_pSpecularVariable->SetFloatVector((float *)&effect.blinn.specular.color.x);
g_pShininessVariable->SetFloat(effect.blinn.shininess);
break;
case effect_type::LAMBERT:
g_pEmissionVariable->SetFloatVector((float *)&effect.lambert.emission.color.x);
g_pAmbientVariable->SetFloatVector((float *)&effect.lambert.ambient.color.x);
g_pDiffuseVariable->SetFloatVector((float *)&effect.lambert.diffuse.color.x);
break;
case effect_type::PHONG:
g_pEmissionVariable->SetFloatVector((float *)&effect.phong.emission.color.x);
g_pAmbientVariable->SetFloatVector((float *)&effect.phong.ambient.color.x);
g_pDiffuseVariable->SetFloatVector((float *)&effect.phong.diffuse.color.x);
g_pSpecularVariable->SetFloatVector((float *)&effect.phong.specular.color.x);
g_pShininessVariable->SetFloat(effect.phong.shininess);
break;
case effect_type::CONSTANT:
g_pEmissionVariable->SetFloatVector((float *)&effect.constant.color.x);
break;
default:
break;
}
}
void RenderGeometries(scene_state const& state, void RenderGeometries(scene_state const& state,
instance_geometry const * const instance_geometries, instance_geometry const * const instance_geometries,
int const instance_geometries_count) int const instance_geometries_count)
{ {
for (int i = 0; i < instance_geometries_count; i++) { for (int i = 0; i < instance_geometries_count; i++) {
instance_geometry const &instance_geometry = instance_geometries[i]; instance_geometry const &instance_geometry = instance_geometries[i];
mesh const& mesh = instance_geometry.geometry->mesh; mesh const& mesh = instance_geometry.geometry->mesh;
UINT strides[1] = { 3 * 3 * 4 }; UINT strides[1] = { 3 * 3 * 4 };
@ -249,8 +290,10 @@ namespace collada_scene {
D3D10_TECHNIQUE_DESC techDesc; D3D10_TECHNIQUE_DESC techDesc;
g_pTechniqueBlinn->GetDesc(&techDesc); g_pTechniqueBlinn->GetDesc(&techDesc);
for (int j = 0; j < mesh.triangles_count; j++) { for (int j = 0; j < instance_geometry.instance_materials_count; j++) {
triangles const& triangles = mesh.triangles[j]; instance_material const& instance_material = instance_geometry.instance_materials[j];
triangles const& triangles = mesh.triangles[instance_material.element_index];
SetMaterial(*instance_material.material->effect);
g_pTechniqueBlinn->GetPassByIndex(0)->Apply(0); g_pTechniqueBlinn->GetPassByIndex(0)->Apply(0);
g_pd3dDevice->IASetInputLayout(state.pVertexLayouts[triangles.inputs_index]); g_pd3dDevice->IASetInputLayout(state.pVertexLayouts[triangles.inputs_index]);

View File

@ -9,6 +9,15 @@ cbuffer cbMultiplePerFrame
matrix World; matrix World;
}; };
cbuffer cbPerMaterial
{
float4 Emission;
float4 Ambient;
float4 Diffuse;
float4 Specular;
float Shininess;
};
struct VS_INPUT struct VS_INPUT
{ {
float3 Pos : POSITION; float3 Pos : POSITION;
@ -39,8 +48,12 @@ PS_INPUT VS(VS_INPUT input)
float4 PS(PS_INPUT input) : SV_Target float4 PS(PS_INPUT input) : SV_Target
{ {
float4 color = Emission + Diffuse * 1.0 + Specular * 0.0;
return float4(color.xyz, 1);
//return float4(input.Normal * 0.5 + 0.5, 1); //return float4(input.Normal * 0.5 + 0.5, 1);
return float4(input.Tex.xy, 0, 1); //return float4(input.Tex.xy, 0, 1);
} }
BlendState DisableBlending BlendState DisableBlending

View File

@ -1821,7 +1821,7 @@ void Render(float t, float dt)
g_pd3dDevice->ClearDepthStencilView(g_pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0); g_pd3dDevice->ClearDepthStencilView(g_pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0);
// render // render
RenderModel(t); //RenderModel(t);
const float ClearColorZero[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; const float ClearColorZero[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
ID3D10RenderTargetView * RenderTargets[] = { ID3D10RenderTargetView * RenderTargets[] = {
@ -1830,19 +1830,19 @@ void Render(float t, float dt)
}; };
g_pd3dDevice->OMSetRenderTargets(2, RenderTargets, g_pDepthStencilView); g_pd3dDevice->OMSetRenderTargets(2, RenderTargets, g_pDepthStencilView);
g_pd3dDevice->ClearRenderTargetView(g_pRenderTargetViewTexture[0], ClearColorZero); g_pd3dDevice->ClearRenderTargetView(g_pRenderTargetViewTexture[0], ClearColorZero);
RenderMeshStatic(cube::node_0.mesh, t); //RenderMeshStatic(cube::node_0.mesh, t);
//RenderBloom(); //RenderBloom();
//print("%f\n", t); //print("%f\n", t);
//RenderVolume(t); //RenderVolume(t);
//RenderVolumeMesh(); //RenderVolumeMesh();
RenderFont(dt);
//collada::Render(t); //collada::Render(t);
collada_scene::Render(curve_interpolation::descriptor, g_SceneState); collada_scene::Render(curve_interpolation::descriptor, g_SceneState);
RenderFont(dt);
// present // present
g_pSwapChain->Present(0, 0); g_pSwapChain->Present(0, 0);
} }