39PStatCollector CullTraverser::_geom_nodes_pcollector(
"Nodes:GeomNodes");
41PStatCollector 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);
221 _cull_handler->end_traverse();
230 PT(
Geom) bounds_viz = make_bounds_viz(vol);
232 if (bounds_viz !=
nullptr) {
233 _geoms_pcollector.add_level(2);
237 _cull_handler->record_object(outer_viz,
this);
240 new CullableObject(std::move(bounds_viz), get_bounds_inner_viz_state(),
242 _cull_handler->record_object(inner_viz,
this);
253 return data.is_in_view(_camera_mask);
261 PandaNode *node = data.node();
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);
269 CullableObject *outer_viz =
270 new CullableObject(std::move(bounds_viz), get_bounds_outer_viz_state(),
272 _cull_handler->record_object(outer_viz,
this);
280 internal_transform = internal_transform->compose(node->get_transform());
281 GeomNode *gnode = (GeomNode *)node;
283 for (
int i = 0; i < num_geoms; ++i) {
294PT(
Geom) CullTraverser::
300 }
else if (vol->
is_of_type(BoundingSphere::get_class_type())) {
301 const BoundingSphere *sphere = DCAST(BoundingSphere, vol);
303 static const int num_slices = 16;
304 static const int num_stacks = 8;
306 PT(GeomVertexData) vdata =
new GeomVertexData
309 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
311 PT(GeomTristrips) strip =
new GeomTristrips(Geom::UH_stream);
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())) {
331 const BoundingHexahedron *fvol = DCAST(BoundingHexahedron, vol);
333 PT(GeomVertexData) vdata =
new GeomVertexData
335 vdata->unclean_set_num_rows(8);
338 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
339 for (
int i = 0; i < 8; ++i) {
344 PT(GeomLines) lines =
new GeomLines(Geom::UH_stream);
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())) {
364 const FiniteBoundingVolume *fvol = DCAST(FiniteBoundingVolume, vol);
366 BoundingBox box(fvol->get_min(), fvol->get_max());
369 PT(GeomVertexData) vdata =
new GeomVertexData
371 vdata->unclean_set_num_rows(8);
374 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
375 for (
int i = 0; i < 8; ++i) {
376 vertex.set_data3(box.get_point(i));
380 PT(GeomTriangles) tris =
new GeomTriangles(Geom::UH_stream);
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";
410PT(
Geom) CullTraverser::
411make_tight_bounds_viz(
PandaNode *node)
const {
417 bool found_any =
false;
421 PT(GeomVertexData) vdata =
new GeomVertexData
423 vdata->unclean_set_num_rows(8);
426 GeomVertexWriter vertex(vdata, InternalName::get_vertex(),
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]);
438 PT(GeomLinestrips) strip =
new GeomLinestrips(Geom::UH_stream);
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);
471LVertex 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();
489get_bounds_outer_viz_state() {
492 static CPT(RenderState) state =
nullptr;
493 if (state ==
nullptr) {
507get_bounds_inner_viz_state() {
510 static CPT(RenderState) state =
nullptr;
511 if (state ==
nullptr) {
524get_depth_offset_state() {
527 static CPT(RenderState) state =
nullptr;
528 if (state ==
nullptr) {
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static BitMask< uint32_t, nbits > all_on()
get_point
Returns the nth vertex of the hexahedron.
This defines a bounding sphere, consisting of a center and a radius.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
bool is_empty() const
Any kind of volume might be empty.
bool is_infinite() const
The other side of the empty coin is an infinite volume.
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
get_camera_mask
Returns the set of bits that represent the subset of the scene graph the camera will render.
get_tag_state_key
Returns the tag key as set by a previous call to set_tag_state_key().
static ConstPointerTo< RenderAttrib > make_flat(const LColor &color)
Constructs a new ColorAttrib object that indicates geometry should be rendered in the indicated color...
static ConstPointerTo< RenderAttrib > make(Mode mode=M_cull_clockwise)
Constructs a new CullFaceAttrib object that specifies how to cull geometry.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
virtual void end_traverse()
Should be called when the traverser has finished traversing its scene, this gives it a chance to do a...
virtual void set_scene(SceneSetup *scene_setup, GraphicsStateGuardianBase *gsg, bool dr_incomplete_render)
Sets the SceneSetup object that indicates the initial camera position, etc.
void set_portal_clipper(PortalClipper *portal_clipper)
Specifies _portal_clipper object pointer that subsequent traverse() or traverse_below may use.
void draw_bounding_volume(const BoundingVolume *vol, const TransformState *internal_transform) const
Draws an appropriate visualization of the indicated bounding volume.
virtual void traverse_below(CullTraverserData &data)
Traverses all the children of the indicated node, with the given data, which has been converted into ...
void traverse(const NodePath &root)
Begins the traversal from the indicated node.
The smallest atom of cull.
static ConstPointerTo< RenderAttrib > make(int offset=1)
Constructs a new DepthOffsetAttrib object that indicates the relative amount of bias to write to the ...
get_num_geoms
Returns the number of geoms in the node.
A container for geometry primitives.
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
virtual GeometricBoundingVolume * as_geometric_bounding_volume() final
Virtual downcast method.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
A lightweight class that represents a single element that may be timed and/or counted via stats.
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
void release()
Releases the lock on this object.
const RenderEffects * get_effects() const
Returns the complete RenderEffects that will be applied to this node.
PandaNode::Children get_children() const
Returns an object that can be used to walk through the list of children of the node.
PandaNode * get_child(size_t n) const
Returns the nth child of the node.
size_t get_num_children() const
Returns the number of children of the node.
A basic node of the scene graph or data graph.
virtual bool is_geom_node() const
A simple downcast check.
virtual int get_next_visible_child(int n) const
Returns the index number of the next visible child of this node following the indicated child,...
virtual int get_first_visible_child() const
Returns the index number of the first visible child of this node, or a number >= get_num_children() i...
ConstPointerTo< BoundingVolume > get_bounds(Thread *current_thread=Thread::get_current_thread()) const
Returns the external bounding volume of this node: a bounding volume that contains the user bounding ...
virtual bool has_selective_visibility() const
Should be overridden by derived classes to return true if this kind of node has some restrictions on ...
virtual ConstPointerTo< TransformState > calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any, const TransformState *transform, Thread *current_thread=Thread::get_current_thread()) const
This is used to support NodePath::calc_tight_bounds().
virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data)
Adds the node's contents to the CullResult we are building up during the cull traversal,...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
void draw_lines()
Draw all the lines in the buffer Cyan portal is the original geometry of the portal Yellow portal is ...
void draw_camera_frustum()
Draw the current camera frustum in white color.
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
bool has_decal() const
This function is provided as an optimization, to speed up the render-time checking for the existance ...
static ConstPointerTo< RenderAttrib > make(Mode mode, PN_stdfloat thickness=1.0f, bool perspective=false, const LColor &wireframe_color=LColor::zero())
Constructs a new RenderModeAttrib object that specifies whether to draw polygons in the normal,...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
static ConstPointerTo< RenderState > make(const RenderAttrib *attrib, int override=0)
Returns a RenderState with one attribute set.
This object holds the camera position, etc., and other general setup information for rendering a part...
const RenderState * get_initial_state() const
Returns the initial state as set by a previous call to set_initial_state().
Camera * get_camera_node() const
Returns the camera used to render the scene.
A thread; that is, a lightweight process.
get_current_thread
Returns a pointer to the currently-executing Thread object.
TypeHandle is the identifier used to differentiate C++ class types.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.