Panda3D
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 ////////////////////////////////////////////////////////////////////
535 CPT(RenderState) CullTraverser::
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 ////////////////////////////////////////////////////////////////////
555 CPT(RenderState) CullTraverser::
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 ////////////////////////////////////////////////////////////////////
575 CPT(RenderState) CullTraverser::
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 }
LPoint3 get_point(int n) const
Returns the nth vertex of the hexahedron.
int get_num_children() const
Returns the number of children of the node.
Definition: pandaNode.I:1163
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...
Definition: pandaNode.cxx:515
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 RenderEffects * get_effects() const
Returns the complete RenderEffects that will be applied to this node.
Definition: pandaNode.I:1742
virtual void traverse_below(CullTraverserData &data)
Traverses all the children of the indicated node, with the given data, which has been converted into ...
static BitMask< PN_uint32, nbits > all_on()
Returns a BitMask whose bits are all on.
Definition: bitMask.I:73
bool is_empty() const
Any kind of volume might be empty.
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 defines a bounding sphere, consisting of a center and a radius.
bool is_infinite() const
The other side of the empty coin is an infinite volume.
void draw_lines()
Draw all the lines in the buffer Cyan portal is the original geometry of the portal Yellow portal is ...
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 ...
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
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
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
int get_num_geoms() const
Returns the number of geoms in the node.
Definition: geomNode.I:46
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.
PandaNode * node() const
Returns the node traversed to so far.
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...
Definition: nodePath.I:77
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.
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
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: portalClipper.h:52
const RenderState * get_initial_state() const
Returns the initial state as set by a previous call to set_initial_state().
Definition: sceneSetup.I:249
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
bool has_decal() const
This function is provided as an optimization, to speed up the render-time checking for the existance ...
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. ...
Camera * get_camera_node() const
Returns the camera used to render the scene.
Definition: sceneSetup.I:144
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.
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
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.
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
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:63
void draw_bounding_volume(const BoundingVolume *vol, const TransformState *internal_transform) const
Draws an appropriate visualization of the indicated bounding volume.
PandaNode * get_child(int n) const
Returns the nth child of the node.
Definition: pandaNode.I:1174
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
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
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
virtual bool is_geom_node() const
A simple downcast check.
Definition: pandaNode.cxx:2486
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
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.