Panda3D
 All Classes Functions Variables Enumerations
cullTraverser.cxx
1 // Filename: cullTraverser.cxx
2 // Created by: drose (23eb02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "config_pgraph.h"
16 #include "cullTraverser.h"
17 #include "cullTraverserData.h"
18 #include "transformState.h"
19 #include "renderState.h"
20 #include "colorAttrib.h"
21 #include "renderModeAttrib.h"
22 #include "cullFaceAttrib.h"
23 #include "depthOffsetAttrib.h"
24 #include "cullHandler.h"
25 #include "dcast.h"
26 #include "geomNode.h"
27 #include "config_pgraph.h"
28 #include "boundingSphere.h"
29 #include "boundingBox.h"
30 #include "boundingHexahedron.h"
31 #include "portalClipper.h"
32 #include "geom.h"
33 #include "geomTristrips.h"
34 #include "geomTriangles.h"
35 #include "geomLinestrips.h"
36 #include "geomLines.h"
37 #include "geomVertexWriter.h"
38 
39 PStatCollector CullTraverser::_nodes_pcollector("Nodes");
40 PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
41 PStatCollector CullTraverser::_geoms_pcollector("Geoms");
42 PStatCollector CullTraverser::_geoms_occluded_pcollector("Geoms:Occluded");
43 
44 TypeHandle CullTraverser::_type_handle;
45 
46 ////////////////////////////////////////////////////////////////////
47 // Function: CullTraverser::Constructor
48 // Access: Published
49 // Description:
50 ////////////////////////////////////////////////////////////////////
51 CullTraverser::
52 CullTraverser() :
53  _gsg(NULL),
54  _current_thread(Thread::get_current_thread())
55 {
56  _camera_mask = DrawMask::all_on();
57  _has_tag_state_key = false;
58  _initial_state = RenderState::make_empty();
59  _cull_handler = (CullHandler *)NULL;
60  _portal_clipper = (PortalClipper *)NULL;
61  _effective_incomplete_render = true;
62 }
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function: CullTraverser::Copy Constructor
66 // Access: Published
67 // Description:
68 ////////////////////////////////////////////////////////////////////
69 CullTraverser::
70 CullTraverser(const CullTraverser &copy) :
71  _gsg(copy._gsg),
72  _current_thread(copy._current_thread),
73  _scene_setup(copy._scene_setup),
74  _camera_mask(copy._camera_mask),
75  _has_tag_state_key(copy._has_tag_state_key),
76  _tag_state_key(copy._tag_state_key),
77  _initial_state(copy._initial_state),
78  _view_frustum(copy._view_frustum),
79  _cull_handler(copy._cull_handler),
80  _portal_clipper(copy._portal_clipper),
81  _effective_incomplete_render(copy._effective_incomplete_render)
82 {
83 }
84 
85 ////////////////////////////////////////////////////////////////////
86 // Function: CullTraverser::set_scene
87 // Access: Published, Virtual
88 // Description: Sets the SceneSetup object that indicates the initial
89 // camera position, etc. This must be called before
90 // traversal begins.
91 ////////////////////////////////////////////////////////////////////
92 void CullTraverser::
94  bool dr_incomplete_render) {
95  _scene_setup = scene_setup;
96  _gsg = gsg;
97 
98  _initial_state = scene_setup->get_initial_state();
99 
100  _current_thread = Thread::get_current_thread();
101 
102  const Camera *camera = scene_setup->get_camera_node();
103  _tag_state_key = camera->get_tag_state_key();
104  _has_tag_state_key = !_tag_state_key.empty();
105  _camera_mask = camera->get_camera_mask();
106 
107  _effective_incomplete_render = _gsg->get_incomplete_render() && dr_incomplete_render;
108 }
109 
110 ////////////////////////////////////////////////////////////////////
111 // Function: CullTraverser::traverse
112 // Access: Published
113 // Description: Begins the traversal from the indicated node.
114 ////////////////////////////////////////////////////////////////////
115 void CullTraverser::
116 traverse(const NodePath &root) {
117  nassertv(_cull_handler != (CullHandler *)NULL);
118  nassertv(_scene_setup != (SceneSetup *)NULL);
119 
120  if (allow_portal_cull) {
121  // This _view_frustum is in cull_center space
122  //Erik: obsolete?
123  //PT(GeometricBoundingVolume) vf = _view_frustum;
124 
125  GeometricBoundingVolume *local_frustum = NULL;
126  PT(BoundingVolume) bv = _scene_setup->get_lens()->make_bounds();
127  if (bv != (BoundingVolume *)NULL &&
128  bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
129 
130  local_frustum = DCAST(GeometricBoundingVolume, bv);
131  }
132 
133  // This local_frustum is in camera space
134  PortalClipper portal_viewer(local_frustum, _scene_setup);
135  if (debug_portal_cull) {
136  portal_viewer.draw_camera_frustum();
137  }
138 
139  // Store this pointer in this
140  set_portal_clipper(&portal_viewer);
141 
142  CullTraverserData data(root, TransformState::make_identity(),
143  _initial_state, _view_frustum,
144  _current_thread);
145 
146  traverse(data);
147 
148  // Finally add the lines to be drawn
149  if (debug_portal_cull) {
150  portal_viewer.draw_lines();
151  }
152 
153  // Render the frustum relative to the cull center.
154  NodePath cull_center = _scene_setup->get_cull_center();
155  CPT(TransformState) transform = cull_center.get_transform(root);
156 
157  CullTraverserData my_data(data, portal_viewer._previous);
158  my_data._net_transform = my_data._net_transform->compose(transform);
159  traverse(my_data);
160 
161  } else {
162  CullTraverserData data(root, TransformState::make_identity(),
163  _initial_state, _view_frustum,
164  _current_thread);
165 
166  do_traverse(data);
167  }
168 }
169 
170 ////////////////////////////////////////////////////////////////////
171 // Function: CullTraverser::traverse
172 // Access: Published
173 // Description: Traverses from the next node with the given
174 // data, which has been constructed with the node but
175 // has not yet been converted into the node's space.
176 ////////////////////////////////////////////////////////////////////
177 void CullTraverser::
179  do_traverse(data);
180 }
181 
182 ////////////////////////////////////////////////////////////////////
183 // Function: CullTraverser::traverse_below
184 // Access: Published, Virtual
185 // Description: Traverses all the children of the indicated node,
186 // with the given data, which has been converted into
187 // the node's space.
188 ////////////////////////////////////////////////////////////////////
189 void CullTraverser::
191  _nodes_pcollector.add_level(1);
192  PandaNodePipelineReader *node_reader = data.node_reader();
193  PandaNode *node = data.node();
194 
195  if (!data.is_this_node_hidden(_camera_mask)) {
196  node->add_for_draw(this, data);
197 
198  // Check for a decal effect.
199  const RenderEffects *node_effects = node_reader->get_effects();
200  if (node_effects->has_decal()) {
201  // If we *are* implementing decals with DepthOffsetAttribs,
202  // apply it now, so that each child of this node gets offset by
203  // a tiny amount.
204  data._state = data._state->compose(get_depth_offset_state());
205 #ifndef NDEBUG
206  // This is just a sanity check message.
207  if (!node->is_geom_node()) {
208  pgraph_cat.error()
209  << "DecalEffect applied to " << *node << ", not a GeomNode.\n";
210  }
211 #endif
212  }
213  }
214 
215  // Now visit all the node's children.
216  PandaNode::Children children = node_reader->get_children();
217  node_reader->release();
218  int num_children = children.get_num_children();
219  if (node->has_selective_visibility()) {
220  int i = node->get_first_visible_child();
221  while (i < num_children) {
222  CullTraverserData next_data(data, children.get_child(i));
223  do_traverse(next_data);
224  i = node->get_next_visible_child(i);
225  }
226 
227  } else {
228  for (int i = 0; i < num_children; i++) {
229  CullTraverserData next_data(data, children.get_child(i));
230  do_traverse(next_data);
231  }
232  }
233 }
234 
235 ////////////////////////////////////////////////////////////////////
236 // Function: CullTraverser::end_traverse
237 // Access: Published, Virtual
238 // Description: Should be called when the traverser has finished
239 // traversing its scene, this gives it a chance to do
240 // any necessary finalization.
241 ////////////////////////////////////////////////////////////////////
242 void CullTraverser::
244  _cull_handler->end_traverse();
245 }
246 
247 ////////////////////////////////////////////////////////////////////
248 // Function: CullTraverser::draw_bounding_volume
249 // Access: Published
250 // Description: Draws an appropriate visualization of the indicated
251 // bounding volume.
252 ////////////////////////////////////////////////////////////////////
253 void CullTraverser::
255  const TransformState *internal_transform) const {
256  PT(Geom) bounds_viz = make_bounds_viz(vol);
257 
258  if (bounds_viz != (Geom *)NULL) {
259  _geoms_pcollector.add_level(2);
260  CullableObject *outer_viz =
261  new CullableObject(bounds_viz, get_bounds_outer_viz_state(),
262  internal_transform);
263  _cull_handler->record_object(outer_viz, this);
264 
265  CullableObject *inner_viz =
266  new CullableObject(bounds_viz, get_bounds_inner_viz_state(),
267  internal_transform);
268  _cull_handler->record_object(inner_viz, this);
269  }
270 }
271 
272 ////////////////////////////////////////////////////////////////////
273 // Function: CullTraverser::is_in_view
274 // Access: Protected, Virtual
275 // Description: Returns true if the current node is fully or
276 // partially within the viewing area and should be
277 // drawn, or false if it (and all of its children)
278 // should be pruned.
279 ////////////////////////////////////////////////////////////////////
280 bool CullTraverser::
281 is_in_view(CullTraverserData &data) {
282  return data.is_in_view(_camera_mask);
283 }
284 
285 ////////////////////////////////////////////////////////////////////
286 // Function: CullTraverser::show_bounds
287 // Access: Private
288 // Description: Draws an appropriate visualization of the node's
289 // external bounding volume.
290 ////////////////////////////////////////////////////////////////////
291 void CullTraverser::
292 show_bounds(CullTraverserData &data, bool tight) {
293  PandaNode *node = data.node();
294  CPT(TransformState) internal_transform = data.get_internal_transform(this);
295 
296  if (tight) {
297  PT(Geom) bounds_viz = make_tight_bounds_viz(node);
298 
299  if (bounds_viz != (Geom *)NULL) {
300  _geoms_pcollector.add_level(1);
301  CullableObject *outer_viz =
302  new CullableObject(bounds_viz, get_bounds_outer_viz_state(),
303  internal_transform);
304  _cull_handler->record_object(outer_viz, this);
305  }
306 
307  } else {
308  draw_bounding_volume(node->get_bounds(), internal_transform);
309 
310  if (node->is_geom_node()) {
311  // Also show the bounding volumes of included Geoms.
312  internal_transform = internal_transform->compose(node->get_transform());
313  GeomNode *gnode = DCAST(GeomNode, node);
314  int num_geoms = gnode->get_num_geoms();
315  for (int i = 0; i < num_geoms; ++i) {
316  draw_bounding_volume(gnode->get_geom(i)->get_bounds(),
317  internal_transform);
318  }
319  }
320  }
321 }
322 
323 ////////////////////////////////////////////////////////////////////
324 // Function: CullTraverser::make_bounds_viz
325 // Access: Private, Static
326 // Description: Returns an appropriate visualization of the indicated
327 // bounding volume.
328 ////////////////////////////////////////////////////////////////////
329 PT(Geom) CullTraverser::
330 make_bounds_viz(const BoundingVolume *vol) {
331  PT(Geom) geom;
332  if (vol->is_infinite() || vol->is_empty()) {
333  // No way to draw an infinite or empty bounding volume.
334 
335  } else if (vol->is_of_type(BoundingSphere::get_class_type())) {
336  const BoundingSphere *sphere = DCAST(BoundingSphere, vol);
337 
338  static const int num_slices = 16;
339  static const int num_stacks = 8;
340 
341  PT(GeomVertexData) vdata = new GeomVertexData
342  ("bounds", GeomVertexFormat::get_v3(),
343  Geom::UH_stream);
344  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
345 
346  PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_stream);
347  for (int sl = 0; sl < num_slices; ++sl) {
348  PN_stdfloat longitude0 = (PN_stdfloat)sl / (PN_stdfloat)num_slices;
349  PN_stdfloat longitude1 = (PN_stdfloat)(sl + 1) / (PN_stdfloat)num_slices;
350  vertex.add_data3(compute_point(sphere, 0.0, longitude0));
351  for (int st = 1; st < num_stacks; ++st) {
352  PN_stdfloat latitude = (PN_stdfloat)st / (PN_stdfloat)num_stacks;
353  vertex.add_data3(compute_point(sphere, latitude, longitude0));
354  vertex.add_data3(compute_point(sphere, latitude, longitude1));
355  }
356  vertex.add_data3(compute_point(sphere, 1.0, longitude0));
357 
358  strip->add_next_vertices(num_stacks * 2);
359  strip->close_primitive();
360  }
361 
362  geom = new Geom(vdata);
363  geom->add_primitive(strip);
364 
365  } else if (vol->is_of_type(BoundingHexahedron::get_class_type())) {
366  const BoundingHexahedron *fvol = DCAST(BoundingHexahedron, vol);
367 
368  PT(GeomVertexData) vdata = new GeomVertexData
369  ("bounds", GeomVertexFormat::get_v3(),
370  Geom::UH_stream);
371  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
372 
373  for (int i = 0; i < 8; ++i ) {
374  vertex.add_data3(fvol->get_point(i));
375  }
376 
377  PT(GeomLines) lines = new GeomLines(Geom::UH_stream);
378  lines->add_vertices(0, 1); lines->close_primitive();
379  lines->add_vertices(1, 2); lines->close_primitive();
380  lines->add_vertices(2, 3); lines->close_primitive();
381  lines->add_vertices(3, 0); lines->close_primitive();
382 
383  lines->add_vertices(4, 5); lines->close_primitive();
384  lines->add_vertices(5, 6); lines->close_primitive();
385  lines->add_vertices(6, 7); lines->close_primitive();
386  lines->add_vertices(7, 4); lines->close_primitive();
387 
388  lines->add_vertices(0, 4); lines->close_primitive();
389  lines->add_vertices(1, 5); lines->close_primitive();
390  lines->add_vertices(2, 6); lines->close_primitive();
391  lines->add_vertices(3, 7); lines->close_primitive();
392 
393  geom = new Geom(vdata);
394  geom->add_primitive(lines);
395 
396  } else if (vol->is_of_type(FiniteBoundingVolume::get_class_type())) {
397  const FiniteBoundingVolume *fvol = DCAST(FiniteBoundingVolume, vol);
398 
399  BoundingBox box(fvol->get_min(), fvol->get_max());
400  box.local_object();
401 
402  PT(GeomVertexData) vdata = new GeomVertexData
403  ("bounds", GeomVertexFormat::get_v3(),
404  Geom::UH_stream);
405  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
406 
407  for (int i = 0; i < 8; ++i ) {
408  vertex.add_data3(box.get_point(i));
409  }
410 
411  PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_stream);
412  tris->add_vertices(0, 4, 5);
413  tris->close_primitive();
414  tris->add_vertices(0, 5, 1);
415  tris->close_primitive();
416  tris->add_vertices(4, 6, 7);
417  tris->close_primitive();
418  tris->add_vertices(4, 7, 5);
419  tris->close_primitive();
420  tris->add_vertices(6, 2, 3);
421  tris->close_primitive();
422  tris->add_vertices(6, 3, 7);
423  tris->close_primitive();
424  tris->add_vertices(2, 0, 1);
425  tris->close_primitive();
426  tris->add_vertices(2, 1, 3);
427  tris->close_primitive();
428  tris->add_vertices(1, 5, 7);
429  tris->close_primitive();
430  tris->add_vertices(1, 7, 3);
431  tris->close_primitive();
432  tris->add_vertices(2, 6, 4);
433  tris->close_primitive();
434  tris->add_vertices(2, 4, 0);
435  tris->close_primitive();
436 
437  geom = new Geom(vdata);
438  geom->add_primitive(tris);
439 
440  } else {
441  pgraph_cat.warning()
442  << "Don't know how to draw a representation of "
443  << vol->get_class_type() << "\n";
444  }
445 
446  return geom;
447 }
448 
449 ////////////////////////////////////////////////////////////////////
450 // Function: CullTraverser::make_tight_bounds_viz
451 // Access: Private
452 // Description: Returns a bounding-box visualization of the indicated
453 // node's "tight" bounding volume.
454 ////////////////////////////////////////////////////////////////////
455 PT(Geom) CullTraverser::
456 make_tight_bounds_viz(PandaNode *node) const {
457  PT(Geom) geom;
458 
459  NodePath np = NodePath::any_path(node);
460 
461  LPoint3 n, x;
462  bool found_any = false;
463  node->calc_tight_bounds(n, x, found_any, TransformState::make_identity(),
464  _current_thread);
465  if (found_any) {
466  PT(GeomVertexData) vdata = new GeomVertexData
467  ("bounds", GeomVertexFormat::get_v3(),
468  Geom::UH_stream);
469  GeomVertexWriter vertex(vdata, InternalName::get_vertex(),
470  _current_thread);
471 
472  vertex.add_data3(n[0], n[1], n[2]);
473  vertex.add_data3(n[0], n[1], x[2]);
474  vertex.add_data3(n[0], x[1], n[2]);
475  vertex.add_data3(n[0], x[1], x[2]);
476  vertex.add_data3(x[0], n[1], n[2]);
477  vertex.add_data3(x[0], n[1], x[2]);
478  vertex.add_data3(x[0], x[1], n[2]);
479  vertex.add_data3(x[0], x[1], x[2]);
480 
481  PT(GeomLinestrips) strip = new GeomLinestrips(Geom::UH_stream);
482 
483  // We wind one long linestrip around the wireframe cube. This
484  // does require backtracking a few times here and there.
485  strip->add_vertex(0);
486  strip->add_vertex(1);
487  strip->add_vertex(3);
488  strip->add_vertex(2);
489  strip->add_vertex(0);
490  strip->add_vertex(4);
491  strip->add_vertex(5);
492  strip->add_vertex(7);
493  strip->add_vertex(6);
494  strip->add_vertex(4);
495  strip->add_vertex(6);
496  strip->add_vertex(2);
497  strip->add_vertex(3);
498  strip->add_vertex(7);
499  strip->add_vertex(5);
500  strip->add_vertex(1);
501  strip->close_primitive();
502 
503  geom = new Geom(vdata);
504  geom->add_primitive(strip);
505  }
506 
507  return geom;
508 }
509 
510 ////////////////////////////////////////////////////////////////////
511 // Function: CullTraverser::compute_point
512 // Access: Private, Static
513 // Description: Returns a point on the surface of the sphere.
514 // latitude and longitude range from 0.0 to 1.0.
515 ////////////////////////////////////////////////////////////////////
516 LVertex CullTraverser::
517 compute_point(const BoundingSphere *sphere,
518  PN_stdfloat latitude, PN_stdfloat longitude) {
519  PN_stdfloat s1, c1;
520  csincos(latitude * MathNumbers::pi, &s1, &c1);
521 
522  PN_stdfloat s2, c2;
523  csincos(longitude * 2.0 * MathNumbers::pi, &s2, &c2);
524 
525  LVertex p(s1 * c2, s1 * s2, c1);
526  return p * sphere->get_radius() + sphere->get_center();
527 }
528 
529 ////////////////////////////////////////////////////////////////////
530 // Function: CullTraverser::get_bounds_outer_viz_state
531 // Access: Private, Static
532 // Description: Returns a RenderState for rendering the outside
533 // surfaces of the bounding volume visualizations.
534 ////////////////////////////////////////////////////////////////////
536 get_bounds_outer_viz_state() {
537  // Once someone asks for this pointer, we hold its reference count
538  // and never free it.
539  static CPT(RenderState) state = (const RenderState *)NULL;
540  if (state == (const RenderState *)NULL) {
541  state = RenderState::make
542  (ColorAttrib::make_flat(LColor(0.3, 1.0f, 0.5f, 1.0f)),
543  RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
544  CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise));
545  }
546  return state;
547 }
548 
549 ////////////////////////////////////////////////////////////////////
550 // Function: CullTraverser::get_bounds_inner_viz_state
551 // Access: Private, Static
552 // Description: Returns a RenderState for rendering the inside
553 // surfaces of the bounding volume visualizations.
554 ////////////////////////////////////////////////////////////////////
556 get_bounds_inner_viz_state() {
557  // Once someone asks for this pointer, we hold its reference count
558  // and never free it.
559  static CPT(RenderState) state = (const RenderState *)NULL;
560  if (state == (const RenderState *)NULL) {
561  state = RenderState::make
562  (ColorAttrib::make_flat(LColor(0.15f, 0.5f, 0.25f, 1.0f)),
563  RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
564  CullFaceAttrib::make(CullFaceAttrib::M_cull_counter_clockwise));
565  }
566  return state;
567 }
568 
569 ////////////////////////////////////////////////////////////////////
570 // Function: CullTraverser::get_depth_offset_state
571 // Access: Private, Static
572 // Description: Returns a RenderState for increasing the DepthOffset
573 // by one.
574 ////////////////////////////////////////////////////////////////////
576 get_depth_offset_state() {
577  // Once someone asks for this pointer, we hold its reference count
578  // and never free it.
579  static CPT(RenderState) state = (const RenderState *)NULL;
580  if (state == (const RenderState *)NULL) {
581  state = RenderState::make
582  (DepthOffsetAttrib::make(1));
583  }
584  return state;
585 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void draw_camera_frustum()
Draw the current camera frustum in white color.
Definition: portalClipper.I:94
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition: boundingBox.h:31
virtual void end_traverse()
Should be called when the traverser has finished traversing its scene, this gives it a chance to do a...
const string & get_tag_state_key() const
Returns the tag key as set by a previous call to set_tag_state_key().
Definition: camera.I:250
virtual void traverse_below(CullTraverserData &data)
Traverses all the children of the indicated node, with the given data, which has been converted into ...
PandaNode::Children get_children() const
Returns an object that can be used to walk through the list of children of the node.
Definition: pandaNode.I:1908
PandaNode * get_child(int n) const
Returns the nth child of the node.
Definition: pandaNode.I:1174
static BitMask< PN_uint32, nbits > all_on()
const RenderState * get_initial_state() const
Returns the initial state as set by a previous call to set_initial_state().
Definition: sceneSetup.I:249
This defines a bounding sphere, consisting of a center and a radius.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:925
void draw_lines()
Draw all the lines in the buffer Cyan portal is the original geometry of the portal Yellow portal is ...
This collects together the pieces of data that are accumulated for each node while walking the scene ...
Defines a series of triangle strips.
Definition: geomTristrips.h:25
PandaNode * node() const
Returns the node traversed to so far.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
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...
Definition: pandaNode.cxx:530
virtual bool has_selective_visibility() const
Should be overridden by derived classes to return true if this kind of node has some restrictions on ...
Definition: pandaNode.cxx:500
Camera * get_camera_node() const
Returns the camera used to render the scene.
Definition: sceneSetup.I:144
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
void traverse(const NodePath &root)
Begins the traversal from the indicated node.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
A lightweight class that represents a single element that may be timed and/or counted via stats...
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
void set_portal_clipper(PortalClipper *portal_clipper)
Specifies _portal_clipper object pointer that subsequent traverse() or traverse_below may use...
void release()
Releases the lock on this object.
Definition: pandaNode.I:1510
This defines the abstract interface for an object that receives Geoms identified by the CullTraverser...
Definition: cullHandler.h:31
virtual void end_traverse()
This callback function is intended to be overridden by a derived class.
Definition: cullHandler.cxx:66
The smallest atom of cull.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: portalClipper.h:52
int get_num_children() const
Returns the number of children of the node.
Definition: pandaNode.I:1163
virtual void record_object(CullableObject *object, const CullTraverser *traverser)
This callback function is intended to be overridden by a derived class.
Definition: cullHandler.cxx:52
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
Definition: geom.h:58
virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data)
Adds the node&#39;s contents to the CullResult we are building up during the cull traversal, so that it will be drawn at render time.
Definition: pandaNode.cxx:591
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
bool is_in_view(const DrawMask &camera_mask)
Returns true if the current node is within the view frustum, false otherwise.
LPoint3 get_point(int n) const
Returns the nth vertex of the hexahedron.
void draw_bounding_volume(const BoundingVolume *vol, const TransformState *internal_transform) const
Draws an appropriate visualization of the indicated bounding volume.
PandaNodePipelineReader * node_reader()
Returns the PipelineReader for the node traversed to so far.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
Defines a series of disconnected line segments.
Definition: geomLines.h:25
void local_object()
This function should be called, once, immediately after creating a new instance of some ReferenceCoun...
A special kind of GeometricBoundingVolume that is known to be finite.
void add_next_vertices(int num_vertices)
Adds the next n vertices in sequence, beginning from the last vertex added to the primitive + 1...
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
const RenderEffects * get_effects() const
Returns the complete RenderEffects that will be applied to this node.
Definition: pandaNode.I:1742
DrawMask get_camera_mask() const
Returns the set of bits that represent the subset of the scene graph the camera will render...
Definition: camera.I:120
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A thread; that is, a lightweight process.
Definition: thread.h:51
Defines a series of line strips.
bool has_decal() const
This function is provided as an optimization, to speed up the render-time checking for the existance ...
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
Definition: pandaNode.h:815
Defines a series of disconnected triangles.
Definition: geomTriangles.h:25
virtual int get_first_visible_child() const
Returns the index number of the first visible child of this node, or a number &gt;= get_num_children() i...
Definition: pandaNode.cxx:515
virtual bool is_geom_node() const
A simple downcast check.
Definition: pandaNode.cxx:2486
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
This object holds the camera position, etc., and other general setup information for rendering a part...
Definition: sceneSetup.h:35
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition: camera.h:37
LPoint3 get_point(int n) const
Returns the nth vertex of the OBB.
Definition: collisionBox.I:159
bool is_this_node_hidden(const DrawMask &camera_mask) const
Returns true if this particular node is hidden, even though we might be traversing past this node to ...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
Definition: renderEffects.h:46
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: cullTraverser.h:48
virtual void set_scene(SceneSetup *scene_setup, GraphicsStateGuardianBase *gsg, bool dr_incomplete_render)
Sets the SceneSetup object that indicates the initial camera position, etc.
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:37
This defines a bounding convex hexahedron.
int get_num_geoms() const
Returns the number of geoms in the node.
Definition: geomNode.I:46