26 PStatCollector SceneGraphReducer::_flatten_collector(
"*:Flatten:flatten");
27 PStatCollector SceneGraphReducer::_apply_collector(
"*:Flatten:apply");
28 PStatCollector SceneGraphReducer::_remove_column_collector(
"*:Flatten:remove column");
29 PStatCollector SceneGraphReducer::_compatible_state_collector(
"*:Flatten:compatible colors");
30 PStatCollector SceneGraphReducer::_collect_collector(
"*:Flatten:collect");
31 PStatCollector SceneGraphReducer::_make_nonindexed_collector(
"*:Flatten:make nonindexed");
32 PStatCollector SceneGraphReducer::_unify_collector(
"*:Flatten:unify");
33 PStatCollector SceneGraphReducer::_remove_unused_collector(
"*:Flatten:remove unused vertices");
34 PStatCollector SceneGraphReducer::_premunge_collector(
"*:Premunge");
51 int max_vertices = max_collect_vertices;
53 if (_gsg !=
nullptr) {
54 max_vertices = std::min(max_vertices, _gsg->get_max_vertices_per_array());
89 int num_total_nodes = 0;
101 for (
int i = 0; i < num_children; i++) {
103 num_pass_nodes += r_flatten(root, child_node, combine_siblings_bits);
106 if (combine_siblings_bits != 0 &&
109 num_pass_nodes += flatten_siblings(root, combine_siblings_bits);
112 num_total_nodes += num_pass_nodes;
117 }
while ((combine_siblings_bits & CS_recurse) != 0 && num_pass_nodes != 0);
119 return num_total_nodes;
131 int count = r_remove_column(root, column, _transformer);
146 PStatTimer timer(_compatible_state_collector);
147 int count = r_make_compatible_state(root, _transformer);
166 if (!preserve_triangle_strips) {
182 int max_indices = max_collect_indices;
183 if (_gsg !=
nullptr) {
184 max_indices = std::min(max_indices, _gsg->get_max_vertices_per_primitive());
186 r_unify(root, max_indices, preserve_order);
200 r_register_vertices(root, _transformer);
217 if (allow_live_flatten) {
232 void SceneGraphReducer::
235 if (pgraph_cat.is_spam()) {
237 <<
"r_apply_attribs(" << *node <<
"), node's attribs are:\n";
238 node->get_transform()->write(pgraph_cat.spam(
false), 2);
239 node->get_state()->write(pgraph_cat.spam(
false), 2);
240 node->get_effects()->write(pgraph_cat.spam(
false), 2);
244 next_attribs.collect(node, attrib_types);
246 if (pgraph_cat.is_spam()) {
248 <<
"Got attribs from " << *node <<
"\n"
249 <<
"Accumulated attribs are:\n";
250 next_attribs.write(pgraph_cat.spam(
false), attrib_types, 2);
256 if (pgraph_cat.is_spam()) {
258 <<
"Not applying further; " << *node
259 <<
" doesn't allow flattening below itself.\n";
261 next_attribs.apply_to_node(node, attrib_types);
269 if (pgraph_cat.is_spam()) {
272 <<
" contains a non-transformable effect; leaving transform here.\n";
274 next_attribs._transform = effects->prepare_flatten_transform(next_attribs._transform);
275 apply_types |= TT_transform;
278 if (pgraph_cat.is_spam()) {
280 <<
"Cannot safely transform nodes of type " << node->get_type()
281 <<
"; leaving a transform here but carrying on otherwise.\n";
283 apply_types |= TT_transform;
291 if ((apply_types & TT_transform) == 0) {
292 bool children_transform_friendly =
true;
293 for (i = 0; i < num_children && children_transform_friendly; i++) {
298 if (!children_transform_friendly) {
299 if (pgraph_cat.is_spam()) {
302 <<
" has a child that cannot modify its transform; leaving transform here.\n";
304 apply_types |= TT_transform;
309 next_attribs.apply_to_node(node, attrib_types & apply_types);
315 bool resist_copy =
false;
316 for (i = 0; i < num_children; i++) {
321 if (pgraph_cat.is_spam()) {
323 <<
"Cannot duplicate nodes of type " << child_node->get_type()
330 if (new_node->get_type() != child_node->get_type()) {
332 <<
"Don't know how to copy nodes of type "
333 << child_node->get_type() <<
"\n";
335 if (no_unsupported_copy) {
336 nassert_raise(
"unsupported copy");
342 if (pgraph_cat.is_spam()) {
344 <<
"Duplicated " << *child_node <<
"\n";
349 child_node = new_node;
358 next_attribs.apply_to_node(node, attrib_types);
363 for (i = 0; i < num_children; i++) {
365 r_apply_attribs(child_node, next_attribs, attrib_types, transformer);
374 int SceneGraphReducer::
376 int combine_siblings_bits) {
377 if (pgraph_cat.is_spam()) {
379 <<
"SceneGraphReducer::r_flatten(" << *grandparent_node <<
", "
380 << *parent_node <<
", " << std::hex << combine_siblings_bits << std::dec
384 if ((combine_siblings_bits & (CS_geom_node | CS_other | CS_recurse)) != 0) {
387 combine_siblings_bits &= ~CS_within_radius;
393 if (pgraph_cat.is_spam()) {
395 <<
"Not traversing further; " << *parent_node
396 <<
" doesn't allow flattening below itself.\n";
400 if ((combine_siblings_bits & CS_within_radius) != 0) {
402 if (bv->is_of_type(BoundingSphere::get_class_type())) {
404 if (pgraph_cat.is_spam()) {
406 <<
"considering radius of " << *parent_node
407 <<
": " << *bs <<
" vs. " << _combine_radius <<
"\n";
412 if (pgraph_cat.is_spam()) {
414 <<
"node fits within radius; flattening tighter.\n";
416 combine_siblings_bits &= ~CS_within_radius;
417 combine_siblings_bits |= (CS_geom_node | CS_other | CS_recurse);
426 for (
int i = 0; i < num_children; i++) {
428 num_nodes += r_flatten(parent_node, child_node, combine_siblings_bits);
439 if ((combine_siblings_bits & CS_recurse) != 0 &&
442 num_nodes += flatten_siblings(parent_node, combine_siblings_bits);
450 if (consider_child(grandparent_node, parent_node, child_node)) {
454 if (do_flatten_child(grandparent_node, parent_node, child_node)) {
459 parent_node->add_child(child_node, child_sort);
464 if ((combine_siblings_bits & CS_recurse) == 0 &&
465 (combine_siblings_bits & ~CS_recurse) != 0 &&
468 num_nodes += flatten_siblings(parent_node, combine_siblings_bits);
476 if (child_node->
is_exact_type(PandaNode::get_class_type()) &&
478 child_node->get_transform()->is_identity() &&
479 child_node->get_effects()->is_empty()) {
496 INLINE
bool SortByState::
498 if (node1->get_transform() != node2->get_transform()) {
499 return node1->get_transform() < node2->get_transform();
501 if (node1->get_state() != node2->get_state()) {
502 return node1->get_state() < node2->get_state();
504 if (node1->get_effects() != node2->get_effects()) {
505 return node1->get_effects() < node2->get_effects();
526 int SceneGraphReducer::
527 flatten_siblings(
PandaNode *parent_node,
int combine_siblings_bits) {
540 for (
int i = 0; i < num_children; i++) {
543 if (safe_to_combine) {
545 safe_to_combine = (combine_siblings_bits & CS_geom_node) != 0;
547 safe_to_combine = (combine_siblings_bits & CS_other) != 0;
551 if (safe_to_combine) {
552 collected[child_node].push_back(child_node);
561 Collected::iterator ci;
562 for (ci = collected.begin(); ci != collected.end(); ++ci) {
564 if (effects->safe_to_combine()) {
565 NodeList &nodes = (*ci).second;
567 NodeList::iterator ai1;
569 while (ai1 != nodes.end()) {
570 NodeList::iterator ai1_hold = ai1;
573 NodeList::iterator ai2 = ai1;
574 while (ai2 != nodes.end()) {
575 NodeList::iterator ai2_hold = ai2;
579 if (consider_siblings(parent_node, child1, child2)) {
581 do_flatten_siblings(parent_node, child1, child2);
582 if (new_node !=
nullptr) {
584 (*ai1_hold) = new_node;
585 nodes.erase(ai2_hold);
604 bool SceneGraphReducer::
613 if (parent_node->get_transform() != child_node->get_transform() ||
614 parent_node->get_state() != child_node->get_state() ||
615 parent_node->get_effects() != child_node->get_effects() ||
623 if (!parent_node->get_effects()->safe_to_combine()) {
636 bool SceneGraphReducer::
650 bool SceneGraphReducer::
653 if (pgraph_cat.is_spam()) {
655 <<
"Collapsing " << *parent_node <<
" and " << *child_node <<
"\n";
658 PT(
PandaNode) new_parent = collapse_nodes(parent_node, child_node,
false);
659 if (new_parent ==
nullptr) {
660 if (pgraph_cat.is_spam()) {
662 <<
"Decided not to collapse " << *parent_node
663 <<
" and " << *child_node <<
"\n";
668 choose_name(new_parent, parent_node, child_node);
670 new_parent->replace_node(child_node);
671 new_parent->replace_node(parent_node);
687 if (pgraph_cat.is_spam()) {
689 <<
"Collapsing " << *child1 <<
" and " << *child2 <<
"\n";
692 PT(
PandaNode) new_child = collapse_nodes(child2, child1,
true);
693 if (new_child ==
nullptr) {
694 if (pgraph_cat.is_spam()) {
696 <<
"Decided not to collapse " << *child1 <<
" and " << *child2 <<
"\n";
701 choose_name(new_child, child2, child1);
706 new_child->replace_node(child1);
721 if (result ==
nullptr) {
732 void SceneGraphReducer::
735 bool got_name =
false;
737 name = source1->get_name();
741 name = source2->get_name();
746 preserve->set_name(name);
753 int SceneGraphReducer::
766 for (
int i = 0; i < num_children; ++i) {
768 r_remove_column(children.
get_child(i), column, transformer);
777 int SceneGraphReducer::
789 for (
int i = 0; i < num_children; ++i) {
791 r_make_compatible_state(children.
get_child(i), transformer);
800 int SceneGraphReducer::
801 r_collect_vertex_data(
PandaNode *node,
int collect_bits,
803 int num_adjusted = 0;
805 int this_node_bits = 0;
806 if (node->
is_of_type(ModelNode::get_class_type())) {
807 this_node_bits |= CVD_model;
809 if (!node->get_transform()->is_identity()) {
810 this_node_bits |= CVD_transform;
813 this_node_bits |= CVD_one_node_only;
816 if ((collect_bits & this_node_bits) != 0) {
822 num_adjusted += new_transformer.collect_vertex_data(DCAST(
GeomNode, node), collect_bits, format_only);
827 for (
int i = 0; i < num_children; ++i) {
829 r_collect_vertex_data(children.
get_child(i), collect_bits, new_transformer, format_only);
832 num_adjusted += new_transformer.finish_collect(format_only);
843 for (
int i = 0; i < num_children; ++i) {
845 r_collect_vertex_data(children.
get_child(i), collect_bits, transformer, format_only);
856 int SceneGraphReducer::
857 r_make_nonindexed(
PandaNode *node,
int nonindexed_bits) {
863 for (
int i = 0; i < num_geoms; ++i) {
864 const Geom *geom = geom_node->get_geom(i);
869 int this_geom_bits = 0;
870 if (data->get_format()->get_animation().get_animation_type() !=
872 this_geom_bits |= MN_avoid_animated;
874 if (data->get_usage_hint() != Geom::UH_static ||
876 this_geom_bits |= MN_avoid_dynamic;
879 if ((nonindexed_bits & this_geom_bits) == 0) {
882 PT(
Geom) mgeom = geom_node->modify_geom(i);
883 num_changed += mgeom->make_nonindexed((nonindexed_bits & MN_composite_only) != 0);
890 for (
int i = 0; i < num_children; ++i) {
892 r_make_nonindexed(children.
get_child(i), nonindexed_bits);
901 void SceneGraphReducer::
902 r_unify(
PandaNode *node,
int max_indices,
bool preserve_order) {
905 geom_node->
unify(max_indices, preserve_order);
910 for (
int i = 0; i < num_children; ++i) {
911 r_unify(children.
get_child(i), max_indices, preserve_order);
920 void SceneGraphReducer::
929 for (
int i = 0; i < num_children; ++i) {
930 r_register_vertices(children.
get_child(i), transformer);
937 void SceneGraphReducer::
946 for (
int i = 0; i < num_children; ++i) {
954 void SceneGraphReducer::
956 CPT(
RenderState) next_state = state->compose(node->get_state());
960 geom_node->
do_premunge(_gsg, next_state, _transformer);
966 for (i = 0; i < num_children; ++i) {
967 r_premunge(children.
get_child(i), next_state);
972 for (i = 0; i < num_stashed; ++i) {