39 PStatCollector CullTraverser::_geom_nodes_pcollector(
"Nodes:GeomNodes");
41 PStatCollector CullTraverser::_geoms_occluded_pcollector(
"Geoms:Occluded");
51 _current_thread(
Thread::get_current_thread())
54 _has_tag_state_key =
false;
55 _initial_state = RenderState::make_empty();
56 _cull_handler =
nullptr;
57 _portal_clipper =
nullptr;
58 _effective_incomplete_render =
true;
67 _current_thread(copy._current_thread),
68 _scene_setup(copy._scene_setup),
69 _camera_mask(copy._camera_mask),
70 _has_tag_state_key(copy._has_tag_state_key),
71 _tag_state_key(copy._tag_state_key),
72 _initial_state(copy._initial_state),
73 _view_frustum(copy._view_frustum),
74 _cull_handler(copy._cull_handler),
75 _portal_clipper(copy._portal_clipper),
76 _effective_incomplete_render(copy._effective_incomplete_render)
86 bool dr_incomplete_render) {
87 _scene_setup = scene_setup;
96 _has_tag_state_key = !_tag_state_key.empty();
99 _effective_incomplete_render = _gsg->get_incomplete_render() && dr_incomplete_render;
107 nassertv(_cull_handler !=
nullptr);
108 nassertv(_scene_setup !=
nullptr);
110 if (allow_portal_cull) {
122 if (debug_portal_cull) {
130 _initial_state, _view_frustum,
136 if (debug_portal_cull) {
141 NodePath cull_center = _scene_setup->get_cull_center();
145 my_data._net_transform = my_data._net_transform->compose(transform);
150 _initial_state, _view_frustum,
173 _nodes_pcollector.add_level(1);
177 if (!data.is_this_node_hidden(_camera_mask)) {
185 data._state = data._state->compose(get_depth_offset_state());
190 <<
"DecalEffect applied to " << *node <<
", not a GeomNode.\n";
201 for (
int i = 0; i < num_children; ++i) {
203 do_traverse(next_data);
207 while (i < num_children) {
209 do_traverse(next_data);
230 PT(
Geom) bounds_viz = make_bounds_viz(vol);
232 if (bounds_viz !=
nullptr) {
233 _geoms_pcollector.add_level(2);
240 new CullableObject(std::move(bounds_viz), get_bounds_inner_viz_state(),
253 return data.is_in_view(_camera_mask);
262 CPT(
TransformState) internal_transform = data.get_internal_transform(
this);
265 PT(
Geom) bounds_viz = make_tight_bounds_viz(node);
267 if (bounds_viz !=
nullptr) {
268 _geoms_pcollector.add_level(1);
270 new CullableObject(std::move(bounds_viz), get_bounds_outer_viz_state(),
280 internal_transform = internal_transform->compose(node->get_transform());
283 for (
int i = 0; i < num_geoms; ++i) {
300 }
else if (vol->
is_of_type(BoundingSphere::get_class_type())) {
303 static const int num_slices = 16;
304 static const int num_stacks = 8;
312 for (
int sl = 0; sl < num_slices; ++sl) {
313 PN_stdfloat longitude0 = (PN_stdfloat)sl / (PN_stdfloat)num_slices;
314 PN_stdfloat longitude1 = (PN_stdfloat)(sl + 1) / (PN_stdfloat)num_slices;
315 vertex.
add_data3(compute_point(sphere, 0.0, longitude0));
316 for (
int st = 1; st < num_stacks; ++st) {
317 PN_stdfloat latitude = (PN_stdfloat)st / (PN_stdfloat)num_stacks;
318 vertex.
add_data3(compute_point(sphere, latitude, longitude0));
319 vertex.
add_data3(compute_point(sphere, latitude, longitude1));
321 vertex.
add_data3(compute_point(sphere, 1.0, longitude0));
323 strip->add_next_vertices(num_stacks * 2);
324 strip->close_primitive();
327 geom =
new Geom(vdata);
328 geom->add_primitive(strip);
330 }
else if (vol->
is_of_type(BoundingHexahedron::get_class_type())) {
335 vdata->unclean_set_num_rows(8);
339 for (
int i = 0; i < 8; ++i) {
345 lines->add_vertices(0, 1);
346 lines->add_vertices(1, 2);
347 lines->add_vertices(2, 3);
348 lines->add_vertices(3, 0);
350 lines->add_vertices(4, 5);
351 lines->add_vertices(5, 6);
352 lines->add_vertices(6, 7);
353 lines->add_vertices(7, 4);
355 lines->add_vertices(0, 4);
356 lines->add_vertices(1, 5);
357 lines->add_vertices(2, 6);
358 lines->add_vertices(3, 7);
360 geom =
new Geom(vdata);
361 geom->add_primitive(lines);
363 }
else if (vol->
is_of_type(FiniteBoundingVolume::get_class_type())) {
371 vdata->unclean_set_num_rows(8);
375 for (
int i = 0; i < 8; ++i) {
381 tris->add_vertices(0, 4, 5);
382 tris->add_vertices(0, 5, 1);
383 tris->add_vertices(4, 6, 7);
384 tris->add_vertices(4, 7, 5);
385 tris->add_vertices(6, 2, 3);
386 tris->add_vertices(6, 3, 7);
387 tris->add_vertices(2, 0, 1);
388 tris->add_vertices(2, 1, 3);
389 tris->add_vertices(1, 5, 7);
390 tris->add_vertices(1, 7, 3);
391 tris->add_vertices(2, 6, 4);
392 tris->add_vertices(2, 4, 0);
394 geom =
new Geom(vdata);
395 geom->add_primitive(tris);
399 <<
"Don't know how to draw a representation of "
400 << vol->get_class_type() <<
"\n";
411 make_tight_bounds_viz(
PandaNode *node)
const {
417 bool found_any =
false;
418 node->calc_tight_bounds(n, x, found_any, TransformState::make_identity(),
423 vdata->unclean_set_num_rows(8);
428 vertex.set_data3(n[0], n[1], n[2]);
429 vertex.set_data3(n[0], n[1], x[2]);
430 vertex.set_data3(n[0], x[1], n[2]);
431 vertex.set_data3(n[0], x[1], x[2]);
432 vertex.set_data3(x[0], n[1], n[2]);
433 vertex.set_data3(x[0], n[1], x[2]);
434 vertex.set_data3(x[0], x[1], n[2]);
435 vertex.set_data3(x[0], x[1], x[2]);
442 strip->add_vertex(0);
443 strip->add_vertex(1);
444 strip->add_vertex(3);
445 strip->add_vertex(2);
446 strip->add_vertex(0);
447 strip->add_vertex(4);
448 strip->add_vertex(5);
449 strip->add_vertex(7);
450 strip->add_vertex(6);
451 strip->add_vertex(4);
452 strip->add_vertex(6);
453 strip->add_vertex(2);
454 strip->add_vertex(3);
455 strip->add_vertex(7);
456 strip->add_vertex(5);
457 strip->add_vertex(1);
458 strip->close_primitive();
460 geom =
new Geom(vdata);
461 geom->add_primitive(strip);
471 LVertex CullTraverser::
473 PN_stdfloat latitude, PN_stdfloat longitude) {
475 csincos(latitude * MathNumbers::pi, &s1, &c1);
478 csincos(longitude * 2.0 * MathNumbers::pi, &s2, &c2);
480 LVertex p(s1 * c2, s1 * s2, c1);
481 return p * sphere->get_radius() + sphere->get_center();
489 get_bounds_outer_viz_state() {
493 if (state ==
nullptr) {
494 state = RenderState::make
495 (ColorAttrib::make_flat(LColor(0.3, 1.0f, 0.5f, 1.0f)),
496 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
497 CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise));
507 get_bounds_inner_viz_state() {
511 if (state ==
nullptr) {
512 state = RenderState::make
513 (ColorAttrib::make_flat(LColor(0.15f, 0.5f, 0.25f, 1.0f)),
514 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
515 CullFaceAttrib::make(CullFaceAttrib::M_cull_counter_clockwise));
524 get_depth_offset_state() {
528 if (state ==
nullptr) {
529 state = RenderState::make
530 (DepthOffsetAttrib::make(1));