Panda3D
portalNode.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 portalNode.cxx
10  * @author drose
11  * @date 2002-03-16
12  */
13 
14 #include "portalNode.h"
15 
16 #include "geomNode.h"
17 #include "cullTraverserData.h"
18 #include "cullTraverser.h"
19 #include "renderState.h"
20 #include "portalClipper.h"
21 #include "transformState.h"
22 #include "clipPlaneAttrib.h"
23 #include "colorScaleAttrib.h"
24 #include "transparencyAttrib.h"
25 #include "datagram.h"
26 #include "datagramIterator.h"
27 #include "bamReader.h"
28 #include "bamWriter.h"
29 #include "boundingSphere.h"
30 
31 #include "plane.h"
32 
33 using std::endl;
34 
35 TypeHandle PortalNode::_type_handle;
36 
37 
38 /**
39  * Default constructor, just an empty node, no geo This is used to read portal
40  * from model. You can also use this from python to create an empty portal.
41  * Then you can set the vertices yourself, with addVertex.
42  */
44 PortalNode(const std::string &name) :
45  PandaNode(name),
46  _from_portal_mask(PortalMask::all_on()),
47  _into_portal_mask(PortalMask::all_on()),
48  _flags(0)
49 {
50  set_cull_callback();
51 
52  _visible = false;
53  _open = true;
54  _clip_plane = false;
55  _max_depth = 10;
56 }
57 
58 /**
59  * Create a default rectangle as portal. Use this to create an arbitrary
60  * portal and setup from Python
61  */
63 PortalNode(const std::string &name, LPoint3 pos, PN_stdfloat scale) :
64  PandaNode(name),
65  _from_portal_mask(PortalMask::all_on()),
66  _into_portal_mask(PortalMask::all_on()),
67  _flags(0)
68 {
69  set_cull_callback();
70 
71  add_vertex(LPoint3(pos[0]-1.0*scale, pos[1], pos[2]-1.0*scale));
72  add_vertex(LPoint3(pos[0]+1.0*scale, pos[1], pos[2]-1.0*scale));
73  add_vertex(LPoint3(pos[0]+1.0*scale, pos[1], pos[2]+1.0*scale));
74  add_vertex(LPoint3(pos[0]-1.0*scale, pos[1], pos[2]+1.0*scale));
75 
76  _visible = false;
77  _open = true;
78  _clip_plane = false;
79  _max_depth = 10;
80 }
81 
82 /**
83  *
84  */
86 PortalNode(const PortalNode &copy) :
87  PandaNode(copy),
88  _from_portal_mask(copy._from_portal_mask),
89  _into_portal_mask(copy._into_portal_mask),
90  _flags(copy._flags),
91  _vertices(copy._vertices),
92  _cell_in(copy._cell_in),
93  _cell_out(copy._cell_out),
94  _clip_plane(copy._clip_plane),
95  _visible(copy._visible),
96  _open(copy._open),
97  _max_depth(copy._max_depth)
98 {
99 }
100 
101 /**
102  *
103  */
104 PortalNode::
105 ~PortalNode() {
106 }
107 
108 /**
109  * Returns a newly-allocated Node that is a shallow copy of this one. It will
110  * be a different Node pointer, but its internal data may or may not be shared
111  * with that of the original Node.
112  */
114 make_copy() const {
115  return new PortalNode(*this);
116 }
117 
118 /**
119  * Returns true if the node's name has extrinsic meaning and must be preserved
120  * across a flatten operation, false otherwise.
121  */
122 bool PortalNode::
123 preserve_name() const {
124  return true;
125 }
126 
127 /**
128  * initialize the clipping planes and renderstate
129  */
130 void PortalNode::
132  _top_plane_node = new PlaneNode("top");
133  NodePath top_plane_np = NodePath(this).attach_new_node(_top_plane_node);
134 
135  _bottom_plane_node = new PlaneNode("bottom");
136  NodePath bottom_plane_np = NodePath(this).attach_new_node(_bottom_plane_node);
137 
138  _left_plane_node = new PlaneNode("left");
139  NodePath left_plane_np = NodePath(this).attach_new_node(_left_plane_node);
140 
141  _right_plane_node = new PlaneNode("right");
142  NodePath right_plane_np = NodePath(this).attach_new_node(_right_plane_node);
143 
144  CPT(RenderAttrib) plane_attrib = ClipPlaneAttrib::make();
145  plane_attrib = DCAST(ClipPlaneAttrib, plane_attrib)->add_on_plane(NodePath(top_plane_np));
146  plane_attrib = DCAST(ClipPlaneAttrib, plane_attrib)->add_on_plane(NodePath(bottom_plane_np));
147  plane_attrib = DCAST(ClipPlaneAttrib, plane_attrib)->add_on_plane(NodePath(left_plane_np));
148  plane_attrib = DCAST(ClipPlaneAttrib, plane_attrib)->add_on_plane(NodePath(right_plane_np));
149 
150  _clip_state = RenderState::make(plane_attrib);
151 }
152 
153 /**
154  * Transforms the contents of this node by the indicated matrix, if it means
155  * anything to do so. For most kinds of nodes, this does nothing.
156  */
157 void PortalNode::
158 xform(const LMatrix4 &mat) {
159  nassertv(!mat.is_nan());
160 
161 }
162 
163 /**
164  * Collapses this node with the other node, if possible, and returns a pointer
165  * to the combined node, or NULL if the two nodes cannot safely be combined.
166  *
167  * The return value may be this, other, or a new node altogether.
168  *
169  * This function is called from GraphReducer::flatten(), and need not deal
170  * with children; its job is just to decide whether to collapse the two nodes
171  * and what the collapsed node should look like.
172  */
175  if (is_exact_type(get_class_type()) &&
176  other->is_exact_type(get_class_type())) {
177  // Two PortalNodes can combine, but only if they have the same name,
178  // because the name is often meaningful.
179  PortalNode *cother = DCAST(PortalNode, other);
180  if (get_name() == cother->get_name()) {
181  return this;
182  }
183 
184  // Two PortalNodes with different names can't combine.
185  return nullptr;
186  }
187 
188  return PandaNode::combine_with(other);
189 }
190 
191 /**
192  * This function will be called during the cull traversal to perform reduced
193  * frustum culling. Basically, once the scenegraph comes across a portal
194  * node, it calculates a CulltraverserData with which cell, this portal leads
195  * out to and the new frustum. Then it traverses that child
196  *
197  * The return value is true if this node should be visible, or false if it
198  * should be culled.
199  */
200 bool PortalNode::
202  Thread *current_thread = trav->get_current_thread();
203 
204  PortalClipper *portal_viewer = trav->get_portal_clipper();
205  set_visible(false);
206  if (is_open() && !_cell_out.is_empty() && portal_viewer && data._portal_depth <= _max_depth) {
207  portal_cat.debug() << "checking portal node " << *this << endl;
208  portal_cat.debug() << "portal_depth is " << data._portal_depth << endl;
209  PT(GeometricBoundingVolume) vf = trav->get_view_frustum();
210  PT(BoundingVolume) reduced_frustum;
211 
212  // remember old viewport and frustum, so we can restore them for the
213  // siblings. (it gets changed by the prepare_portal call)
214  LPoint2 old_reduced_viewport_min, old_reduced_viewport_max;
215  portal_viewer->get_reduced_viewport(old_reduced_viewport_min, old_reduced_viewport_max);
216  PT(BoundingHexahedron) old_bh = portal_viewer->get_reduced_frustum();
217 
218  if (portal_viewer->prepare_portal(data.get_node_path())) {
219  if ((reduced_frustum = portal_viewer->get_reduced_frustum())) {
220  // remember current clip state, we might change it
221  CPT(RenderState) old_clip_state = portal_viewer->get_clip_state();
222 
223  set_visible(true);
224  // The frustum is in camera space
225  vf = DCAST(GeometricBoundingVolume, reduced_frustum);
226 
227  // create a copy of this reduced frustum, we'll transform it from
228  // camera space to the cell_out space
229  PT(BoundingHexahedron) new_bh = DCAST(BoundingHexahedron, vf->make_copy());
230 
231  // Get the net trasform of the _cell_out as seen from the camera.
232  CPT(TransformState) cell_transform = _cell_out.get_net_transform();
233  CPT(TransformState) frustum_transform = cell_transform ->invert_compose(portal_viewer->_scene_setup->get_cull_center().get_net_transform());
234 
235  // transform to _cell_out space
236  new_bh->xform(frustum_transform->get_mat());
237 
238  CPT(RenderState) next_state = data._state;
239 
240  // set clipping planes, if desired..
241  if (_clip_plane) {
242  // create a copy of this reduced frustum, we'll transform it from
243  // camera space to this portal node's space (because the clip planes
244  // are attached to this node)
245  PT(BoundingHexahedron) temp_bh = DCAST(BoundingHexahedron, vf->make_copy());
246  CPT(TransformState) temp_frustum_transform = data.get_node_path().get_net_transform()->invert_compose(portal_viewer->_scene_setup->get_cull_center().get_net_transform());
247 
248  portal_cat.spam() << "clipping plane frustum transform " << *temp_frustum_transform << endl;
249  portal_cat.spam() << "frustum before transform " << *temp_bh << endl;
250  // transform to portalNode space
251  temp_bh->xform(temp_frustum_transform->get_mat());
252 
253  portal_cat.spam() << "frustum after transform " << *temp_bh << endl;
254 
255  _left_plane_node->set_plane(-temp_bh->get_plane(4)); // left plane of bh
256  _right_plane_node->set_plane(-temp_bh->get_plane(2));// right plane of bh
257  _top_plane_node->set_plane(-temp_bh->get_plane(3)); // top plane of bh
258  _bottom_plane_node->set_plane(-temp_bh->get_plane(1));// bottom plane of bh
259 
260  portal_cat.spam() << "left plane " << *_left_plane_node << endl;
261  portal_cat.spam() << "right plane " << *_right_plane_node << endl;
262  portal_cat.spam() << "top plane " << *_top_plane_node << endl;
263  portal_cat.spam() << "bottom plane " << *_bottom_plane_node << endl;
264 
265  // remember the clip state we just generated
266  portal_viewer->set_clip_state(_clip_state);
267 
268  if (old_clip_state) {
269  portal_cat.spam() << "parent clip state " << *old_clip_state << endl;
270  } else {
271  portal_cat.spam() << "parent clip state None" << endl;
272  }
273  portal_cat.spam() << "own clip state " << *_clip_state << endl;
274  portal_cat.spam() << "next state " << *next_state << endl;
275 
276  // undo parent clip state and compose our new clip state ito the new
277  // state
278  if (old_clip_state != nullptr) {
279  next_state = old_clip_state->invert_compose(next_state);
280  portal_cat.spam() << "next state after removing parent state " << *next_state << endl;
281  }
282  next_state = next_state->compose(_clip_state);
283  portal_cat.spam() << "next state after composition " << *next_state << endl;
284  }
285 
286  CullTraverserData next_data(_cell_out,
287  cell_transform,
288  next_state, new_bh,
289  current_thread);
290  next_data._portal_depth = data._portal_depth + 1;
291 
292  portal_viewer->set_reduced_frustum(new_bh);
293  portal_cat.spam() << "cull_callback: before traversing " << _cell_out.get_name() << endl;
294  trav->traverse_below(next_data);
295  portal_cat.spam() << "cull_callback: after traversing " << _cell_out.get_name() << endl;
296 
297  // restore clip state
298  portal_viewer->set_clip_state(old_clip_state);
299  }
300  }
301  // reset portal viewer frustum for the siblings;
302  portal_viewer->set_reduced_frustum(old_bh);
303  // reset portal viewer viewport for the siblings;
304  portal_viewer->set_reduced_viewport(old_reduced_viewport_min, old_reduced_viewport_max);
305  }
306  // Now carry on to render our child nodes.
307  return true;
308 }
309 
310 /**
311  * Returns true if there is some value to visiting this particular node during
312  * the cull traversal for any camera, false otherwise. This will be used to
313  * optimize the result of get_net_draw_show_mask(), so that any subtrees that
314  * contain only nodes for which is_renderable() is false need not be visited.
315  */
316 bool PortalNode::
317 is_renderable() const {
318  return true;
319 }
320 
321 
322 /**
323  * Writes a brief description of the node to the indicated output stream.
324  * This is invoked by the << operator. It may be overridden in derived
325  * classes to include some information relevant to the class.
326  */
327 void PortalNode::
328 output(std::ostream &out) const {
329  PandaNode::output(out);
330 }
331 
332 /**
333  * Draws the vertices of this portal rectangle to the screen with a line
334  */
335 /*
336 void PortalNode::
337 draw() const {
338  move_to(get_vertex(0));
339  draw_to(get_vertex(1));
340  draw_to(get_vertex(2));
341  draw_to(get_vertex(3));
342 }
343 */
344 
345 /**
346  * Called when needed to recompute the node's _internal_bound object. Nodes
347  * that contain anything of substance should redefine this to do the right
348  * thing.
349  */
350 void PortalNode::
351 compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
352  int &internal_vertices,
353  int pipeline_stage,
354  Thread *current_thread) const {
355  // First, get ourselves a fresh, empty bounding volume.
356  PT(BoundingVolume) bound = new BoundingSphere;
358 
359  // Now actually compute the bounding volume by putting it around all of our
360  // vertices.
361 
362  const LPoint3 *vertices_begin = &_vertices[0];
363  const LPoint3 *vertices_end = vertices_begin + _vertices.size();
364 
365  // Now actually compute the bounding volume by putting it around all
366  gbv->around(vertices_begin, vertices_end);
367 
368  internal_bounds = bound;
369  internal_vertices = 0;
370 }
371 
372 /**
373  * Returns a RenderState for rendering the ghosted portal rectangle that
374  * represents the previous frame's position, for those collision nodes that
375  * indicate a velocity.
376  */
377 CPT(RenderState) PortalNode::
378 get_last_pos_state() {
379  // Once someone asks for this pointer, we hold its reference count and never
380  // free it.
381  static CPT(RenderState) state = nullptr;
382  if (state == nullptr) {
383  state = RenderState::make
384  (ColorScaleAttrib::make(LVecBase4(1.0f, 1.0f, 1.0f, 0.5f)),
385  TransparencyAttrib::make(TransparencyAttrib::M_alpha));
386  }
387 
388  return state;
389 }
390 
391 
392 /**
393  * Tells the BamReader how to create objects of type PortalNode.
394  */
395 void PortalNode::
397  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
398 }
399 
400 /**
401  * Writes the contents of this object to the datagram for shipping out to a
402  * Bam file.
403  */
404 void PortalNode::
406  PandaNode::write_datagram(manager, dg);
407 
408  dg.add_uint16(_vertices.size());
409  for (Vertices::const_iterator vi = _vertices.begin();
410  vi != _vertices.end();
411  ++vi) {
412  (*vi).write_datagram(dg);
413  }
414 }
415 
416 /**
417  * Receives an array of pointers, one for each time manager->read_pointer()
418  * was called in fillin(). Returns the number of pointers processed.
419  */
420 int PortalNode::
422  int pi = PandaNode::complete_pointers(p_list, manager);
423 
424  return pi;
425 }
426 
427 /**
428  * This function is called by the BamReader's factory when a new object of
429  * type PortalNode is encountered in the Bam file. It should create the
430  * PortalNode and extract its information from the file.
431  */
432 TypedWritable *PortalNode::
433 make_from_bam(const FactoryParams &params) {
434  PortalNode *node = new PortalNode("");
435  DatagramIterator scan;
436  BamReader *manager;
437 
438  parse_params(params, scan, manager);
439  node->fillin(scan, manager);
440 
441  return node;
442 }
443 
444 /**
445  * This internal function is called by make_from_bam to read in all of the
446  * relevant data from the BamFile for the new PortalNode.
447  */
448 void PortalNode::
449 fillin(DatagramIterator &scan, BamReader *manager) {
450  PandaNode::fillin(scan, manager);
451 
452  int num_vertices = scan.get_uint16();
453  _vertices.reserve(num_vertices);
454  for (int i = 0; i < num_vertices; i++) {
455  LPoint3 vertex;
456  vertex.read_datagram(scan);
457  _vertices.push_back(vertex);
458  }
459 
460  /*
461  _from_portal_mask.set_word(scan.get_uint32());
462  _into_portal_mask.set_word(scan.get_uint32());
463  _flags = scan.get_uint8();
464  */
465 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
const RenderState * get_clip_state() const
Returns the stored clip state.
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
Definition: typedObject.I:38
Indicates a coordinate-system transform on vertices.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
bool prepare_portal(const NodePath &node_path)
Given the portal draw the frustum with line segs for now.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: pandaNode.cxx:3589
CPT(RenderState) PortalNode
Returns a RenderState for rendering the ghosted portal rectangle that represents the previous frame's...
Definition: portalNode.cxx:377
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 ...
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so.
Definition: portalNode.cxx:158
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
virtual PandaNode * combine_with(PandaNode *other)
Collapses this PandaNode with the other PandaNode, if possible, and returns a pointer to the combined...
Definition: pandaNode.cxx:325
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
Thread * get_current_thread() const
Returns the currently-executing thread object, as passed to the CullTraverser constructor.
Definition: cullTraverser.I:27
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This defines a bounding sphere, consisting of a center and a radius.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
This collects together the pieces of data that are accumulated for each node while walking the scene ...
void set_reduced_frustum(BoundingHexahedron *bh)
Set the current view frustum that is being calculated by the portal clipper.
Definition: portalClipper.I:85
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
Definition: portalNode.cxx:421
This functions similarly to a LightAttrib.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
PortalNode(const std::string &name)
Default constructor, just an empty node, no geo This is used to read portal from model.
Definition: portalNode.cxx:44
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
Definition: portalNode.cxx:317
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingHexahedron * get_reduced_frustum() const
Return the reduced frustum.
Definition: portalClipper.I:93
is_open
Is this portal open from current camera zone.
Definition: portalNode.h:98
static void register_with_read_factory()
Tells the BamReader how to create objects of type PortalNode.
Definition: portalNode.cxx:396
void get_reduced_viewport(LPoint2 &min, LPoint2 &max) const
Return the reduced viewport.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_clip_state(const RenderState *clip_state)
Set the clip state of the current portal node This is done to remember the state for the child portal...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
PortalClipper * get_portal_clipper() const
Returns the _portal_clipper pointer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
set_visible
this is set if the portal is facing camera
Definition: portalNode.h:96
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
A node in the scene graph that can hold a Portal Polygon, which is a rectangle.
Definition: portalNode.h:30
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:85
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: portalClipper.h:49
NodePath attach_new_node(PandaNode *node, int sort=0, Thread *current_thread=Thread::get_current_thread()) const
Attaches a new node, with or without existing parents, to the scene graph below the referenced node o...
Definition: nodePath.cxx:563
get_name
Returns the name of the referenced node.
Definition: nodePath.h:946
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
virtual void output(std::ostream &out) const
Writes a brief description of the node to the indicated output stream.
Definition: portalNode.cxx:328
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
virtual PandaNode * combine_with(PandaNode *other)
Collapses this node with the other node, if possible, and returns a pointer to the combined node,...
Definition: portalNode.cxx:174
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform reduced frustum culling.
Definition: portalNode.cxx:201
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
const NodePath & get_cull_center() const
Returns the point from which the culling operations will be performed.
Definition: sceneSetup.I:161
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition: portalNode.cxx:114
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: portalNode.cxx:405
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
Definition: thread.h:46
GeometricBoundingVolume * get_view_frustum() const
Returns the bounding volume that corresponds to the view frustum, or NULL if the view frustum is not ...
virtual bool preserve_name() const
Returns true if the node's name has extrinsic meaning and must be preserved across a flatten operatio...
Definition: portalNode.cxx:123
A class to retrieve the individual data elements previously stored in a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
void set_reduced_viewport(const LPoint2 &min, const LPoint2 &max)
Set the current viewport that is being used by the portal clipper.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
virtual void enable_clipping_planes()
initialize the clipping planes and renderstate
Definition: portalNode.cxx:131
void add_vertex(const LPoint3 &vertex)
Adds a new vertex to the portal polygon.
Definition: portalNode.I:109
bool around(const GeometricBoundingVolume **first, const GeometricBoundingVolume **last)
Resets the volume to enclose only the volumes indicated.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that contains a plane.
Definition: planeNode.h:36
This defines a bounding convex hexahedron.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.