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