Panda3D
cullTraverser.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file cullTraverser.cxx
10  * @author drose
11  * @date 2002-02-23
12  */
13 
14 #include "config_pgraph.h"
15 #include "cullTraverser.h"
16 #include "cullTraverserData.h"
17 #include "transformState.h"
18 #include "renderState.h"
19 #include "colorAttrib.h"
20 #include "renderModeAttrib.h"
21 #include "cullFaceAttrib.h"
22 #include "depthOffsetAttrib.h"
23 #include "cullHandler.h"
24 #include "dcast.h"
25 #include "geomNode.h"
26 #include "config_pgraph.h"
27 #include "boundingSphere.h"
28 #include "boundingBox.h"
29 #include "boundingHexahedron.h"
30 #include "portalClipper.h"
31 #include "geom.h"
32 #include "geomTristrips.h"
33 #include "geomTriangles.h"
34 #include "geomLinestrips.h"
35 #include "geomLines.h"
36 #include "geomVertexWriter.h"
37 
38 PStatCollector CullTraverser::_nodes_pcollector("Nodes");
39 PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
40 PStatCollector CullTraverser::_geoms_pcollector("Geoms");
41 PStatCollector CullTraverser::_geoms_occluded_pcollector("Geoms:Occluded");
42 
43 TypeHandle CullTraverser::_type_handle;
44 
45 /**
46  *
47  */
48 CullTraverser::
49 CullTraverser() :
50  _gsg(nullptr),
51  _current_thread(Thread::get_current_thread())
52 {
53  _camera_mask = DrawMask::all_on();
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;
59 }
60 
61 /**
62  *
63  */
64 CullTraverser::
65 CullTraverser(const CullTraverser &copy) :
66  _gsg(copy._gsg),
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)
77 {
78 }
79 
80 /**
81  * Sets the SceneSetup object that indicates the initial camera position, etc.
82  * This must be called before traversal begins.
83  */
84 void CullTraverser::
86  bool dr_incomplete_render) {
87  _scene_setup = scene_setup;
88  _gsg = gsg;
89 
90  _initial_state = scene_setup->get_initial_state();
91 
92  _current_thread = Thread::get_current_thread();
93 
94  const Camera *camera = scene_setup->get_camera_node();
95  _tag_state_key = camera->get_tag_state_key();
96  _has_tag_state_key = !_tag_state_key.empty();
97  _camera_mask = camera->get_camera_mask();
98 
99  _effective_incomplete_render = _gsg->get_incomplete_render() && dr_incomplete_render;
100 }
101 
102 /**
103  * Begins the traversal from the indicated node.
104  */
105 void CullTraverser::
106 traverse(const NodePath &root) {
107  nassertv(_cull_handler != nullptr);
108  nassertv(_scene_setup != nullptr);
109 
110  if (allow_portal_cull) {
111  // This _view_frustum is in cull_center space Erik: obsolete?
112  // PT(GeometricBoundingVolume) vf = _view_frustum;
113 
114  GeometricBoundingVolume *local_frustum = nullptr;
115  PT(BoundingVolume) bv = _scene_setup->get_lens()->make_bounds();
116  if (bv != nullptr) {
117  local_frustum = bv->as_geometric_bounding_volume();
118  }
119 
120  // This local_frustum is in camera space
121  PortalClipper portal_viewer(local_frustum, _scene_setup);
122  if (debug_portal_cull) {
123  portal_viewer.draw_camera_frustum();
124  }
125 
126  // Store this pointer in this
127  set_portal_clipper(&portal_viewer);
128 
129  CullTraverserData data(root, TransformState::make_identity(),
130  _initial_state, _view_frustum,
131  _current_thread);
132 
133  traverse(data);
134 
135  // Finally add the lines to be drawn
136  if (debug_portal_cull) {
137  portal_viewer.draw_lines();
138  }
139 
140  // Render the frustum relative to the cull center.
141  NodePath cull_center = _scene_setup->get_cull_center();
142  CPT(TransformState) transform = cull_center.get_transform(root);
143 
144  CullTraverserData my_data(data, portal_viewer._previous);
145  my_data._net_transform = my_data._net_transform->compose(transform);
146  traverse(my_data);
147 
148  } else {
149  CullTraverserData data(root, TransformState::make_identity(),
150  _initial_state, _view_frustum,
151  _current_thread);
152 
153  do_traverse(data);
154  }
155 }
156 
157 /**
158  * Traverses from the next node with the given data, which has been
159  * constructed with the node but has not yet been converted into the node's
160  * space.
161  */
162 void CullTraverser::
164  do_traverse(data);
165 }
166 
167 /**
168  * Traverses all the children of the indicated node, with the given data,
169  * which has been converted into the node's space.
170  */
171 void CullTraverser::
173  _nodes_pcollector.add_level(1);
174  PandaNodePipelineReader *node_reader = data.node_reader();
175  PandaNode *node = data.node();
176 
177  if (!data.is_this_node_hidden(_camera_mask)) {
178  node->add_for_draw(this, data);
179 
180  // Check for a decal effect.
181  const RenderEffects *node_effects = node_reader->get_effects();
182  if (node_effects->has_decal()) {
183  // If we *are* implementing decals with DepthOffsetAttribs, apply it
184  // now, so that each child of this node gets offset by a tiny amount.
185  data._state = data._state->compose(get_depth_offset_state());
186 #ifndef NDEBUG
187  // This is just a sanity check message.
188  if (!node->is_geom_node()) {
189  pgraph_cat.error()
190  << "DecalEffect applied to " << *node << ", not a GeomNode.\n";
191  }
192 #endif
193  }
194  }
195 
196  // Now visit all the node's children.
197  PandaNode::Children children = node_reader->get_children();
198  node_reader->release();
199  int num_children = children.get_num_children();
200  if (!node->has_selective_visibility()) {
201  for (int i = 0; i < num_children; ++i) {
202  CullTraverserData next_data(data, children.get_child(i));
203  do_traverse(next_data);
204  }
205  } else {
206  int i = node->get_first_visible_child();
207  while (i < num_children) {
208  CullTraverserData next_data(data, children.get_child(i));
209  do_traverse(next_data);
210  i = node->get_next_visible_child(i);
211  }
212  }
213 }
214 
215 /**
216  * Should be called when the traverser has finished traversing its scene, this
217  * gives it a chance to do any necessary finalization.
218  */
219 void CullTraverser::
221  _cull_handler->end_traverse();
222 }
223 
224 /**
225  * Draws an appropriate visualization of the indicated bounding volume.
226  */
227 void CullTraverser::
229  const TransformState *internal_transform) const {
230  PT(Geom) bounds_viz = make_bounds_viz(vol);
231 
232  if (bounds_viz != nullptr) {
233  _geoms_pcollector.add_level(2);
234  CullableObject *outer_viz =
235  new CullableObject(bounds_viz, get_bounds_outer_viz_state(),
236  internal_transform);
237  _cull_handler->record_object(outer_viz, this);
238 
239  CullableObject *inner_viz =
240  new CullableObject(std::move(bounds_viz), get_bounds_inner_viz_state(),
241  internal_transform);
242  _cull_handler->record_object(inner_viz, this);
243  }
244 }
245 
246 /**
247  * Returns true if the current node is fully or partially within the viewing
248  * area and should be drawn, or false if it (and all of its children) should
249  * be pruned.
250  */
251 bool CullTraverser::
252 is_in_view(CullTraverserData &data) {
253  return data.is_in_view(_camera_mask);
254 }
255 
256 /**
257  * Draws an appropriate visualization of the node's external bounding volume.
258  */
259 void CullTraverser::
260 show_bounds(CullTraverserData &data, bool tight) {
261  PandaNode *node = data.node();
262  CPT(TransformState) internal_transform = data.get_internal_transform(this);
263 
264  if (tight) {
265  PT(Geom) bounds_viz = make_tight_bounds_viz(node);
266 
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(),
271  internal_transform);
272  _cull_handler->record_object(outer_viz, this);
273  }
274 
275  } else {
276  draw_bounding_volume(node->get_bounds(), internal_transform);
277 
278  if (node->is_geom_node()) {
279  // Also show the bounding volumes of included Geoms.
280  internal_transform = internal_transform->compose(node->get_transform());
281  GeomNode *gnode = (GeomNode *)node;
282  int num_geoms = gnode->get_num_geoms();
283  for (int i = 0; i < num_geoms; ++i) {
284  draw_bounding_volume(gnode->get_geom(i)->get_bounds(),
285  internal_transform);
286  }
287  }
288  }
289 }
290 
291 /**
292  * Returns an appropriate visualization of the indicated bounding volume.
293  */
294 PT(Geom) CullTraverser::
295 make_bounds_viz(const BoundingVolume *vol) {
296  PT(Geom) geom;
297  if (vol->is_infinite() || vol->is_empty()) {
298  // No way to draw an infinite or empty bounding volume.
299 
300  } else if (vol->is_of_type(BoundingSphere::get_class_type())) {
301  const BoundingSphere *sphere = DCAST(BoundingSphere, vol);
302 
303  static const int num_slices = 16;
304  static const int num_stacks = 8;
305 
306  PT(GeomVertexData) vdata = new GeomVertexData
307  ("bounds", GeomVertexFormat::get_v3(),
308  Geom::UH_stream);
309  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
310 
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));
320  }
321  vertex.add_data3(compute_point(sphere, 1.0, longitude0));
322 
323  strip->add_next_vertices(num_stacks * 2);
324  strip->close_primitive();
325  }
326 
327  geom = new Geom(vdata);
328  geom->add_primitive(strip);
329 
330  } else if (vol->is_of_type(BoundingHexahedron::get_class_type())) {
331  const BoundingHexahedron *fvol = DCAST(BoundingHexahedron, vol);
332 
333  PT(GeomVertexData) vdata = new GeomVertexData
334  ("bounds", GeomVertexFormat::get_v3(), Geom::UH_stream);
335  vdata->unclean_set_num_rows(8);
336 
337  {
338  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
339  for (int i = 0; i < 8; ++i) {
340  vertex.set_data3(fvol->get_point(i));
341  }
342  }
343 
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);
349 
350  lines->add_vertices(4, 5);
351  lines->add_vertices(5, 6);
352  lines->add_vertices(6, 7);
353  lines->add_vertices(7, 4);
354 
355  lines->add_vertices(0, 4);
356  lines->add_vertices(1, 5);
357  lines->add_vertices(2, 6);
358  lines->add_vertices(3, 7);
359 
360  geom = new Geom(vdata);
361  geom->add_primitive(lines);
362 
363  } else if (vol->is_of_type(FiniteBoundingVolume::get_class_type())) {
364  const FiniteBoundingVolume *fvol = DCAST(FiniteBoundingVolume, vol);
365 
366  BoundingBox box(fvol->get_min(), fvol->get_max());
367  box.local_object();
368 
369  PT(GeomVertexData) vdata = new GeomVertexData
370  ("bounds", GeomVertexFormat::get_v3(), Geom::UH_stream);
371  vdata->unclean_set_num_rows(8);
372 
373  {
374  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
375  for (int i = 0; i < 8; ++i) {
376  vertex.set_data3(box.get_point(i));
377  }
378  }
379 
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);
393 
394  geom = new Geom(vdata);
395  geom->add_primitive(tris);
396 
397  } else {
398  pgraph_cat.warning()
399  << "Don't know how to draw a representation of "
400  << vol->get_class_type() << "\n";
401  }
402 
403  return geom;
404 }
405 
406 /**
407  * Returns a bounding-box visualization of the indicated node's "tight"
408  * bounding volume.
409  */
410 PT(Geom) CullTraverser::
411 make_tight_bounds_viz(PandaNode *node) const {
412  PT(Geom) geom;
413 
414  NodePath np = NodePath::any_path(node);
415 
416  LPoint3 n, x;
417  bool found_any = false;
418  node->calc_tight_bounds(n, x, found_any, TransformState::make_identity(),
419  _current_thread);
420  if (found_any) {
421  PT(GeomVertexData) vdata = new GeomVertexData
422  ("bounds", GeomVertexFormat::get_v3(), Geom::UH_stream);
423  vdata->unclean_set_num_rows(8);
424 
425  {
426  GeomVertexWriter vertex(vdata, InternalName::get_vertex(),
427  _current_thread);
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]);
436  }
437 
438  PT(GeomLinestrips) strip = new GeomLinestrips(Geom::UH_stream);
439 
440  // We wind one long linestrip around the wireframe cube. This does
441  // require backtracking a few times here and there.
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();
459 
460  geom = new Geom(vdata);
461  geom->add_primitive(strip);
462  }
463 
464  return geom;
465 }
466 
467 /**
468  * Returns a point on the surface of the sphere. latitude and longitude range
469  * from 0.0 to 1.0.
470  */
471 LVertex CullTraverser::
472 compute_point(const BoundingSphere *sphere,
473  PN_stdfloat latitude, PN_stdfloat longitude) {
474  PN_stdfloat s1, c1;
475  csincos(latitude * MathNumbers::pi, &s1, &c1);
476 
477  PN_stdfloat s2, c2;
478  csincos(longitude * 2.0 * MathNumbers::pi, &s2, &c2);
479 
480  LVertex p(s1 * c2, s1 * s2, c1);
481  return p * sphere->get_radius() + sphere->get_center();
482 }
483 
484 /**
485  * Returns a RenderState for rendering the outside surfaces of the bounding
486  * volume visualizations.
487  */
488 CPT(RenderState) CullTraverser::
489 get_bounds_outer_viz_state() {
490  // Once someone asks for this pointer, we hold its reference count and never
491  // free it.
492  static CPT(RenderState) state = nullptr;
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));
498  }
499  return state;
500 }
501 
502 /**
503  * Returns a RenderState for rendering the inside surfaces of the bounding
504  * volume visualizations.
505  */
506 CPT(RenderState) CullTraverser::
507 get_bounds_inner_viz_state() {
508  // Once someone asks for this pointer, we hold its reference count and never
509  // free it.
510  static CPT(RenderState) state = nullptr;
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));
516  }
517  return state;
518 }
519 
520 /**
521  * Returns a RenderState for increasing the DepthOffset by one.
522  */
523 CPT(RenderState) CullTraverser::
524 get_depth_offset_state() {
525  // Once someone asks for this pointer, we hold its reference count and never
526  // free it.
527  static CPT(RenderState) state = nullptr;
528  if (state == nullptr) {
529  state = RenderState::make
530  (DepthOffsetAttrib::make(1));
531  }
532  return state;
533 }
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:421
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
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:75
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition: boundingBox.h:29
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Indicates a coordinate-system transform on vertices.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void end_traverse()
Should be called when the traverser has finished traversing its scene, this gives it a chance to do a...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const RenderEffects * get_effects() const
Returns the complete RenderEffects that will be applied to this node.
Definition: pandaNode.I:1431
virtual GeometricBoundingVolume * as_geometric_bounding_volume() final
Virtual downcast method.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void traverse_below(CullTraverserData &data)
Traverses all the children of the indicated node, with the given data, which has been converted into ...
void set_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.
PandaNode * get_child(size_t n) const
Returns the nth child of the node.
Definition: pandaNode.I:962
get_tag_state_key
Returns the tag key as set by a previous call to set_tag_state_key().
Definition: camera.h:83
static BitMask< uint32_t, nbits > all_on()
Returns a BitMask whose bits are all on.
Definition: bitMask.I:32
bool is_empty() const
Any kind of volume might be empty.
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 ...
get_camera_mask
Returns the set of bits that represent the subset of the scene graph the camera will render.
Definition: camera.h:63
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:409
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:23
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:1561
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void traverse(const NodePath &root)
Begins the traversal from the indicated node.
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:62
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void release()
Releases the lock on this object.
Definition: pandaNode.I:1242
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void end_traverse()
This callback function is intended to be overridden by a derived class.
Definition: cullHandler.cxx:54
The smallest atom of cull.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: portalClipper.h:49
const RenderState * get_initial_state() const
Returns the initial state as set by a previous call to set_initial_state().
Definition: sceneSetup.I:198
virtual void record_object(CullableObject *object, const CullTraverser *traverser)
This callback function is intended to be overridden by a derived class.
Definition: cullHandler.cxx:43
size_t get_num_children() const
Returns the number of children of the node.
Definition: pandaNode.I:953
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
Definition: geom.h:54
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,...
Definition: pandaNode.cxx:478
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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:115
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
Defines a series of disconnected line segments.
Definition: geomLines.h:23
PT(Geom) CullTraverser
Returns an appropriate visualization of the indicated bounding volume.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_num_geoms
Returns the number of geoms in the node.
Definition: geomNode.h:71
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
Definition: thread.h:46
Defines a series of line strips.
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
Definition: pandaNode.h:842
Defines a series of disconnected triangles.
Definition: geomTriangles.h:23
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CPT(RenderState) CullTraverser
Returns a RenderState for rendering the outside surfaces of the bounding volume visualizations.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
get_point
Returns the nth vertex of the hexahedron.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void draw_bounding_volume(const BoundingVolume *vol, const TransformState *internal_transform) const
Draws an appropriate visualization of the indicated bounding volume.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:758
This object holds the camera position, etc., and other general setup information for rendering a part...
Definition: sceneSetup.h:32
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
Definition: camera.h:35
virtual bool is_geom_node() const
A simple downcast check.
Definition: pandaNode.cxx:2068
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:432
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
static const GeomVertexFormat * get_v3()
Returns a standard vertex format with just a 3-component vertex position.
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
Definition: renderEffects.h:41
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
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:34
This defines a bounding convex hexahedron.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.