collada/header: precalculate fully linearized node list
This commit is contained in:
parent
2860311f8a
commit
e4bb6c2616
@ -41,6 +41,10 @@ class State:
|
||||
# channel nodes: node_id to list of sanitized target names
|
||||
node_animation_channels: Dict[str, set]
|
||||
|
||||
# linearized_nodes
|
||||
linearized_nodes: List[types.Node]
|
||||
node_parents: Dict[int, int]
|
||||
|
||||
def __init__(self):
|
||||
self.vertex_buffer = BytesIO()
|
||||
self.index_buffer = BytesIO()
|
||||
@ -50,6 +54,8 @@ class State:
|
||||
self.symbol_names = {}
|
||||
self.emitted_input_elements_arrays = {}
|
||||
self.node_animation_channels = defaultdict(set)
|
||||
self.linearized_nodes = []
|
||||
self.node_parents = {}
|
||||
|
||||
def sanitize_name(state, name, value, *, allow_slash=False):
|
||||
assert name is not None, value
|
||||
@ -284,13 +290,13 @@ def get_node_name_id(node):
|
||||
assert name is not None, node
|
||||
return name
|
||||
|
||||
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_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:
|
||||
@ -304,14 +310,10 @@ def render_node_channels(state, collada, node, node_name):
|
||||
yield f"&node_channel_{target_name},"
|
||||
yield "};"
|
||||
|
||||
def render_node(state, collada, node):
|
||||
# render children first
|
||||
for child_node in node.nodes:
|
||||
yield from render_node(state, collada, child_node)
|
||||
|
||||
def render_node(state, collada, node, node_index):
|
||||
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_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)
|
||||
@ -322,6 +324,8 @@ def render_node(state, collada, node):
|
||||
}[node.type]
|
||||
|
||||
yield f"node const node_{node_name} = {{"
|
||||
yield f".parent_index = {state.node_parents[node_index]},"
|
||||
yield ""
|
||||
yield f".type = node_type::{type},"
|
||||
yield ""
|
||||
yield f".transforms = transforms_{node_name},"
|
||||
@ -332,22 +336,34 @@ def render_node(state, collada, node):
|
||||
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 f".nodes = node_children_{node_name},"
|
||||
#yield f".nodes_count = {len(node.nodes)},"
|
||||
yield "};"
|
||||
|
||||
def linear_nodes(collada):
|
||||
def traverse_node(state, parent_node_index, node):
|
||||
assert parent_node_index < len(state.linearized_nodes)
|
||||
node_index = len(state.linearized_nodes)
|
||||
state.linearized_nodes.append(node)
|
||||
assert node_index not in state.node_parents
|
||||
state.node_parents[node_index] = parent_node_index
|
||||
for child_node in node.nodes:
|
||||
traverse_node(state, node_index, child_node)
|
||||
|
||||
def linearize_nodes(state, collada):
|
||||
for library_visual_scenes in collada.library_visual_scenes:
|
||||
for visual_scene in library_visual_scenes.visual_scenes:
|
||||
for node in visual_scene.nodes:
|
||||
yield node
|
||||
traverse_node(state, -1, node)
|
||||
|
||||
def render_library_visual_scenes(state, collada):
|
||||
for node in linear_nodes(collada):
|
||||
yield from render_node(state, collada, node)
|
||||
linearize_nodes(state, collada)
|
||||
|
||||
for node_index, node in enumerate(state.linearized_nodes):
|
||||
yield from render_node(state, collada, node, node_index)
|
||||
|
||||
yield "node const * const nodes[] = {"
|
||||
for node in linear_nodes(collada):
|
||||
for node_index, node in enumerate(state.linearized_nodes):
|
||||
node_name_id = get_node_name_id(node)
|
||||
node_name = sanitize_name(state, node_name_id, node)
|
||||
yield f"&node_{node_name},"
|
||||
|
||||
@ -43,17 +43,9 @@ namespace collada_scene {
|
||||
HRESULT load_scene(collada::descriptor const * const descriptor);
|
||||
void render();
|
||||
|
||||
typedef void (collada_scene::scene_state::* const apply_node_func_t)(collada::node const * const node,
|
||||
node_instance * node_instance);
|
||||
|
||||
private:
|
||||
HRESULT load_layouts();
|
||||
void allocate_node_instances();
|
||||
node_instance * apply_node_instances1(collada::node const * const node,
|
||||
node_instance * node_instance,
|
||||
apply_node_func_t func);
|
||||
void apply_node_instances(apply_node_func_t func);
|
||||
|
||||
void allocate_node_instance(collada::node const * const node,
|
||||
node_instance * node_instance);
|
||||
|
||||
|
||||
@ -277,6 +277,8 @@ namespace collada {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct node {
|
||||
int const parent_index;
|
||||
|
||||
node_type const type;
|
||||
|
||||
transform const * const transforms;
|
||||
@ -288,8 +290,8 @@ namespace collada {
|
||||
channel const * const * const channels;
|
||||
int const channels_count;
|
||||
|
||||
node const * const * const nodes;
|
||||
int const nodes_count;
|
||||
//node const * const * const nodes;
|
||||
//int const nodes_count;
|
||||
};
|
||||
|
||||
struct descriptor {
|
||||
|
||||
@ -510,9 +510,6 @@ geometry const * const geometries[] = {
|
||||
&geometry_geom_plane001,
|
||||
};
|
||||
|
||||
node const * const node_children_node_environmentambientlight[] = {
|
||||
};
|
||||
|
||||
transform const transforms_node_environmentambientlight[] = {
|
||||
};
|
||||
|
||||
@ -532,12 +529,6 @@ node const node_node_environmentambientlight = {
|
||||
|
||||
.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[] = {
|
||||
@ -583,8 +574,8 @@ instance_geometry const instance_geometries_node_cube[] = {
|
||||
};
|
||||
|
||||
channel const * const node_channels_node_cube[] = {
|
||||
&node_channel_node_cube_translation_y,
|
||||
&node_channel_node_cube_translation_x,
|
||||
&node_channel_node_cube_translation_y,
|
||||
};
|
||||
|
||||
node const node_node_cube = {
|
||||
@ -598,12 +589,6 @@ node const node_node_cube = {
|
||||
|
||||
.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[] = {
|
||||
@ -638,12 +623,6 @@ node const node_node_cylinder001 = {
|
||||
|
||||
.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[] = {
|
||||
@ -686,9 +665,6 @@ node const node_node_plane001 = {
|
||||
|
||||
.channels = node_channels_node_plane001,
|
||||
.channels_count = 0,
|
||||
|
||||
.nodes = node_children_node_plane001,
|
||||
.nodes_count = 0,
|
||||
};
|
||||
|
||||
node const * const nodes[] = {
|
||||
|
||||
@ -67,15 +67,6 @@ namespace collada_scene {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static int count_nodes(node const * const node)
|
||||
{
|
||||
int count = 1;
|
||||
for (int i = 0; i < node->nodes_count; i++) {
|
||||
count += count_nodes(node->nodes[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void initialize_node_transforms(node const * const node,
|
||||
node_instance * node_instance)
|
||||
{
|
||||
@ -113,38 +104,13 @@ namespace collada_scene {
|
||||
initialize_node_transforms(node, node_instance);
|
||||
}
|
||||
|
||||
node_instance * scene_state::apply_node_instances1(node const * const node,
|
||||
node_instance * node_instance,
|
||||
apply_node_func_t func)
|
||||
{
|
||||
(this->*func)(node, node_instance);
|
||||
node_instance = &node_instance[1];
|
||||
|
||||
for (int i = 0; i < node->nodes_count; i++) {
|
||||
node_instance = apply_node_instances1(node->nodes[i], node_instance, func);
|
||||
}
|
||||
|
||||
return node_instance;
|
||||
}
|
||||
|
||||
void scene_state::apply_node_instances(apply_node_func_t func)
|
||||
{
|
||||
node_instance * node_instance = m_nodeInstances;
|
||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||
node_instance = apply_node_instances1(m_descriptor->nodes[i], node_instance, func);
|
||||
}
|
||||
}
|
||||
|
||||
void scene_state::allocate_node_instances()
|
||||
{
|
||||
int count = 0;
|
||||
m_nodeInstances = New<node_instance>(m_descriptor->nodes_count);
|
||||
|
||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||
count += count_nodes(m_descriptor->nodes[i]);
|
||||
allocate_node_instance(m_descriptor->nodes[i], &m_nodeInstances[i]);
|
||||
}
|
||||
|
||||
m_nodeInstances = New<node_instance>(count);
|
||||
|
||||
apply_node_instances(&scene_state::allocate_node_instance);
|
||||
}
|
||||
|
||||
HRESULT scene_state::load_scene(collada::descriptor const * const descriptor)
|
||||
@ -383,7 +349,6 @@ namespace collada_scene {
|
||||
|
||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||
node const& node = *m_descriptor->nodes[i];
|
||||
assert(node.nodes_count == 0);
|
||||
if (node.type != node_type::NODE)
|
||||
continue;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user