Browse Source

add PandaNode::get_fancy_bits(), remove PandaNode::has_cull_callback()

David Rose 19 years ago
parent
commit
425ada050a
45 changed files with 449 additions and 461 deletions
  1. 14 20
      panda/src/char/character.cxx
  2. 0 1
      panda/src/char/character.h
  3. 14 20
      panda/src/collide/collisionNode.cxx
  4. 0 1
      panda/src/collide/collisionNode.h
  5. 14 20
      panda/src/collide/collisionVisualizer.cxx
  6. 0 1
      panda/src/collide/collisionVisualizer.h
  7. 14 20
      panda/src/distort/projectionScreen.cxx
  8. 0 1
      panda/src/distort/projectionScreen.h
  9. 14 6
      panda/src/grutil/frameRateMeter.cxx
  10. 13 20
      panda/src/parametrics/ropeNode.cxx
  11. 0 1
      panda/src/parametrics/ropeNode.h
  12. 13 20
      panda/src/parametrics/sheetNode.cxx
  13. 0 1
      panda/src/parametrics/sheetNode.h
  14. 38 29
      panda/src/pgraph/cullTraverser.cxx
  15. 14 6
      panda/src/pgraph/fadeLodNode.cxx
  16. 1 0
      panda/src/pgraph/lodNode.I
  17. 12 20
      panda/src/pgraph/lodNode.cxx
  18. 0 1
      panda/src/pgraph/lodNode.h
  19. 69 21
      panda/src/pgraph/pandaNode.I
  20. 51 20
      panda/src/pgraph/pandaNode.cxx
  21. 20 1
      panda/src/pgraph/pandaNode.h
  22. 14 20
      panda/src/pgraph/planeNode.cxx
  23. 0 1
      panda/src/pgraph/planeNode.h
  24. 10 20
      panda/src/pgraph/portalNode.cxx
  25. 0 1
      panda/src/pgraph/portalNode.h
  26. 1 0
      panda/src/pgraph/sequenceNode.I
  27. 12 20
      panda/src/pgraph/sequenceNode.cxx
  28. 0 1
      panda/src/pgraph/sequenceNode.h
  29. 1 0
      panda/src/pgraph/switchNode.I
  30. 12 20
      panda/src/pgraph/switchNode.cxx
  31. 0 1
      panda/src/pgraph/switchNode.h
  32. 14 20
      panda/src/pgui/pgEntry.cxx
  33. 0 1
      panda/src/pgui/pgEntry.h
  34. 14 20
      panda/src/pgui/pgItem.cxx
  35. 0 1
      panda/src/pgui/pgItem.h
  36. 14 20
      panda/src/pgui/pgScrollFrame.cxx
  37. 0 1
      panda/src/pgui/pgScrollFrame.h
  38. 14 20
      panda/src/pgui/pgSliderBar.cxx
  39. 0 1
      panda/src/pgui/pgSliderBar.h
  40. 14 20
      panda/src/pgui/pgTop.cxx
  41. 0 1
      panda/src/pgui/pgTop.h
  42. 14 20
      panda/src/pgui/pgWaitBar.cxx
  43. 0 1
      panda/src/pgui/pgWaitBar.h
  44. 14 20
      panda/src/text/textNode.cxx
  45. 0 1
      panda/src/text/textNode.h

+ 14 - 20
panda/src/char/character.cxx

@@ -46,6 +46,8 @@ Character(const Character &copy) :
   _joints_pcollector(copy._joints_pcollector),
   _joints_pcollector(copy._joints_pcollector),
   _skinning_pcollector(copy._skinning_pcollector)
   _skinning_pcollector(copy._skinning_pcollector)
 {
 {
+  set_cull_callback();
+
   // Now make a copy of the joint/slider hierarchy.  We could just use
   // Now make a copy of the joint/slider hierarchy.  We could just use
   // the copy_subgraph feature of the PartBundleNode's copy
   // the copy_subgraph feature of the PartBundleNode's copy
   // constructor, but if we do it ourselves we can simultaneously
   // constructor, but if we do it ourselves we can simultaneously
@@ -118,29 +120,21 @@ safe_to_flatten_below() const {
   return false;
   return false;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: Character::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool Character::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Character::cull_callback
 //     Function: Character::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/char/character.h

@@ -54,7 +54,6 @@ public:
 
 
   virtual bool safe_to_transform() const;
   virtual bool safe_to_transform() const;
   virtual bool safe_to_flatten_below() const;
   virtual bool safe_to_flatten_below() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
 
 
   virtual CPT(TransformState)
   virtual CPT(TransformState)

+ 14 - 20
panda/src/collide/collisionNode.cxx

@@ -46,6 +46,8 @@ CollisionNode(const string &name) :
   _from_collide_mask(get_default_collide_mask()),
   _from_collide_mask(get_default_collide_mask()),
   _collide_geom(false)
   _collide_geom(false)
 {
 {
+  set_cull_callback();
+
   // CollisionNodes are hidden by default.
   // CollisionNodes are hidden by default.
   set_overall_hidden(true);
   set_overall_hidden(true);
 
 
@@ -184,29 +186,21 @@ get_legal_collide_mask() const {
   return CollideMask::all_on();
   return CollideMask::all_on();
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: CollisionNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool CollisionNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionNode::cull_callback
 //     Function: CollisionNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/collide/collisionNode.h

@@ -49,7 +49,6 @@ public:
   virtual PandaNode *combine_with(PandaNode *other); 
   virtual PandaNode *combine_with(PandaNode *other); 
   virtual CollideMask get_legal_collide_mask() const;
   virtual CollideMask get_legal_collide_mask() const;
 
 
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool is_renderable() const;
   virtual bool is_renderable() const;
 
 

+ 14 - 20
panda/src/collide/collisionVisualizer.cxx

@@ -49,6 +49,8 @@ TypeHandle CollisionVisualizer::_type_handle;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 CollisionVisualizer::
 CollisionVisualizer::
 CollisionVisualizer(const string &name) : PandaNode(name) {
 CollisionVisualizer(const string &name) : PandaNode(name) {
+  set_cull_callback();
+
   // We always want to render the CollisionVisualizer node itself
   // We always want to render the CollisionVisualizer node itself
   // (even if it doesn't appear to have any geometry within it).
   // (even if it doesn't appear to have any geometry within it).
   set_internal_bounds(new OmniBoundingVolume());
   set_internal_bounds(new OmniBoundingVolume());
@@ -89,29 +91,21 @@ make_copy() const {
   return new CollisionVisualizer(*this);
   return new CollisionVisualizer(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: CollisionVisualizer::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool CollisionVisualizer::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionVisualizer::cull_callback
 //     Function: CollisionVisualizer::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/collide/collisionVisualizer.h

@@ -54,7 +54,6 @@ PUBLISHED:
 public:
 public:
   // from parent class PandaNode.
   // from parent class PandaNode.
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual void output(ostream &out) const;
   virtual void output(ostream &out) const;
 
 

+ 14 - 20
panda/src/distort/projectionScreen.cxx

@@ -39,6 +39,8 @@ TypeHandle ProjectionScreen::_type_handle;
 ProjectionScreen::
 ProjectionScreen::
 ProjectionScreen(const string &name) : PandaNode(name)
 ProjectionScreen(const string &name) : PandaNode(name)
 {
 {
+  set_cull_callback();
+
   _texcoord_name = InternalName::get_texcoord();
   _texcoord_name = InternalName::get_texcoord();
 
 
   _invert_uvs = project_invert_uvs;
   _invert_uvs = project_invert_uvs;
@@ -90,29 +92,21 @@ make_copy() const {
   return new ProjectionScreen(*this);
   return new ProjectionScreen(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: ProjectionScreen::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool ProjectionScreen::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ProjectionScreen::cull_callback
 //     Function: ProjectionScreen::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/distort/projectionScreen.h

@@ -65,7 +65,6 @@ protected:
 
 
 public:
 public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
 
 
 PUBLISHED:
 PUBLISHED:

+ 14 - 6
panda/src/grutil/frameRateMeter.cxx

@@ -38,6 +38,8 @@ TypeHandle FrameRateMeter::_type_handle;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 FrameRateMeter::
 FrameRateMeter::
 FrameRateMeter(const string &name) : TextNode(name) {
 FrameRateMeter(const string &name) : TextNode(name) {
+  set_cull_callback();
+
   Thread *current_thread = Thread::get_current_thread();
   Thread *current_thread = Thread::get_current_thread();
 
 
   _update_interval = frame_rate_meter_update_interval;
   _update_interval = frame_rate_meter_update_interval;
@@ -130,12 +132,18 @@ clear_window() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: FrameRateMeter::cull_callback
 //     Function: FrameRateMeter::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 13 - 20
panda/src/parametrics/ropeNode.cxx

@@ -82,6 +82,7 @@ RopeNode::
 RopeNode(const string &name) :
 RopeNode(const string &name) :
   PandaNode(name)
   PandaNode(name)
 {
 {
+  set_cull_callback();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -122,29 +123,21 @@ safe_to_transform() const {
   return false;
   return false;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: RopeNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool RopeNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: RopeNode::cull_callback
 //     Function: RopeNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/parametrics/ropeNode.h

@@ -52,7 +52,6 @@ public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
 
 
   virtual bool safe_to_transform() const;
   virtual bool safe_to_transform() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
 
 
 PUBLISHED:
 PUBLISHED:

+ 13 - 20
panda/src/parametrics/sheetNode.cxx

@@ -80,6 +80,7 @@ SheetNode::
 SheetNode(const string &name) :
 SheetNode(const string &name) :
   PandaNode(name)
   PandaNode(name)
 {
 {
+  set_cull_callback();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -120,29 +121,21 @@ safe_to_transform() const {
   return false;
   return false;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: SheetNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool SheetNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SheetNode::cull_callback
 //     Function: SheetNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/parametrics/sheetNode.h

@@ -50,7 +50,6 @@ public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
 
 
   virtual bool safe_to_transform() const;
   virtual bool safe_to_transform() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
 
 
 PUBLISHED:
 PUBLISHED:

+ 38 - 29
panda/src/pgraph/cullTraverser.cxx

@@ -148,11 +148,6 @@ traverse(const NodePath &root, bool python_cull_control) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CullTraverser::
 void CullTraverser::
 traverse(CullTraverserData &data) {
 traverse(CullTraverserData &data) {
-  // Most nodes will have no transform or state, and will not
-  // contain decals or require a special cull callback.  As an
-  // optimization, we should tag nodes with these properties as
-  // being "fancy", and skip this processing for non-fancy nodes.
-  
   if (data.is_in_view(_camera_mask)) {
   if (data.is_in_view(_camera_mask)) {
     if (pgraph_cat.is_spam()) {
     if (pgraph_cat.is_spam()) {
       pgraph_cat.spam() 
       pgraph_cat.spam() 
@@ -161,33 +156,47 @@ traverse(CullTraverserData &data) {
     }
     }
 
 
     PandaNodePipelineReader *node_reader = data.node_reader();
     PandaNodePipelineReader *node_reader = data.node_reader();
-    PandaNode *node = data.node();
-
-    const RenderEffects *node_effects = node_reader->get_effects();
-    if (node_effects->has_show_bounds()) {
-      // If we should show the bounding volume for this node, make it
-      // up now.
-      show_bounds(data, node_effects->has_show_tight_bounds());
-    }
-
-    data.apply_transform_and_state(this);
+    int fancy_bits = node_reader->get_fancy_bits();
+
+    if ((fancy_bits & (PandaNode::FB_transform |
+                       PandaNode::FB_state |
+                       PandaNode::FB_effects |
+                       PandaNode::FB_tag |
+                       PandaNode::FB_draw_mask |
+                       PandaNode::FB_cull_callback)) == 0 &&
+        data._cull_planes->is_empty()) {
+      // Nothing interesting in this node; just move on.
+      traverse_below(data);
 
 
-    const FogAttrib *fog = node_reader->get_state()->get_fog();
-    if (fog != (const FogAttrib *)NULL && fog->get_fog() != (Fog *)NULL) {
-      // If we just introduced a FogAttrib here, call adjust_to_camera()
-      // now.  This maybe isn't the perfect time to call it, but it's
-      // good enough; and at this time we have all the information we
-      // need for it.
-      fog->get_fog()->adjust_to_camera(get_camera_transform());
-    }
-
-    if (node->has_cull_callback()) {
-      if (!node->cull_callback(this, data)) {
-        return;
+    } else {
+      // Something in this node is worth taking a closer look.
+      const RenderEffects *node_effects = node_reader->get_effects();
+      if (node_effects->has_show_bounds()) {
+        // If we should show the bounding volume for this node, make it
+        // up now.
+        show_bounds(data, node_effects->has_show_tight_bounds());
+      }
+      
+      data.apply_transform_and_state(this);
+      
+      const FogAttrib *fog = node_reader->get_state()->get_fog();
+      if (fog != (const FogAttrib *)NULL && fog->get_fog() != (Fog *)NULL) {
+        // If we just introduced a FogAttrib here, call adjust_to_camera()
+        // now.  This maybe isn't the perfect time to call it, but it's
+        // good enough; and at this time we have all the information we
+        // need for it.
+        fog->get_fog()->adjust_to_camera(get_camera_transform());
+      }
+      
+      if (fancy_bits & PandaNode::FB_cull_callback) {
+        PandaNode *node = data.node();
+        if (!node->cull_callback(this, data)) {
+          return;
+        }
       }
       }
-    }
 
 
-    traverse_below(data);
+      traverse_below(data);
+    }
   }
   }
 }
 }
 
 

+ 14 - 6
panda/src/pgraph/fadeLodNode.cxx

@@ -36,6 +36,8 @@ FadeLODNode::
 FadeLODNode(const string &name) :
 FadeLODNode(const string &name) :
   LODNode(name) 
   LODNode(name) 
 {
 {
+  set_cull_callback();
+
   _fade_time = lod_fade_time;
   _fade_time = lod_fade_time;
 }
 }
 
 
@@ -55,12 +57,18 @@ make_copy() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: FadeLODNode::cull_callback
 //     Function: FadeLODNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 1 - 0
panda/src/pgraph/lodNode.I

@@ -27,6 +27,7 @@ INLINE LODNode::
 LODNode(const string &name) :
 LODNode(const string &name) :
   PandaNode(name)
   PandaNode(name)
 {
 {
+  set_cull_callback();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 12 - 20
panda/src/pgraph/lodNode.cxx

@@ -95,29 +95,21 @@ xform(const LMatrix4f &mat) {
   }
   }
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: LODNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool LODNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: LODNode::cull_callback
 //     Function: LODNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgraph/lodNode.h

@@ -42,7 +42,6 @@ public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
   virtual bool safe_to_combine() const;
   virtual bool safe_to_combine() const;
   virtual void xform(const LMatrix4f &mat);
   virtual void xform(const LMatrix4f &mat);
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
 
 
   virtual void output(ostream &out) const;
   virtual void output(ostream &out) const;

+ 69 - 21
panda/src/pgraph/pandaNode.I

@@ -617,6 +617,22 @@ is_final(Thread *current_thread) const {
   return cdata->_final_bounds;
   return cdata->_final_bounds;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNode::get_fancy_bits
+//       Access: Published
+//  Description: Returns the union of all of the enum FancyBits values
+//               corresponding to the various "fancy" attributes that
+//               are set on the node.  If this returns 0, the node has
+//               nothing interesting about it.  This is intended to
+//               speed traversal by quickly skipping past nodes that
+//               don't particularly affect the render state.
+////////////////////////////////////////////////////////////////////
+INLINE int PandaNode::
+get_fancy_bits(Thread *current_thread) const {
+  CDReader cdata(_cycler, current_thread);
+  return cdata->_fancy_bits;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNode::get_user_bounds
 //     Function: PandaNode::get_user_bounds
 //       Access: Protected
 //       Access: Protected
@@ -871,6 +887,22 @@ get_parent() const {
   return _parent;
   return _parent;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNode::CData::set_fancy_bit
+//       Access: Public
+//  Description: Internal function to set (if value is true) or clear
+//               (if value is false) the indicated bit(s) in the
+//               _fancy_bits member.
+////////////////////////////////////////////////////////////////////
+INLINE void PandaNode::CData::
+set_fancy_bit(int bits, bool value) {
+  if (value) {
+    _fancy_bits |= bits;
+  } else {
+    _fancy_bits &= ~bits;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNode::CData::get_down
 //     Function: PandaNode::CData::get_down
 //       Access: Public
 //       Access: Public
@@ -1350,7 +1382,7 @@ compare_draw_mask(DrawMask running_draw_mask, DrawMask camera_mask) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_num_parents
 //     Function: PandaNodePipelineReader::get_num_parents
-//       Access: Published
+//       Access: Public
 //  Description: Returns the number of parent nodes this node has.  If
 //  Description: Returns the number of parent nodes this node has.  If
 //               this number is greater than 1, the node has been
 //               this number is greater than 1, the node has been
 //               multiply instanced.  The order of the parent nodes is
 //               multiply instanced.  The order of the parent nodes is
@@ -1364,7 +1396,7 @@ get_num_parents() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_parent
 //     Function: PandaNodePipelineReader::get_parent
-//       Access: Published
+//       Access: Public
 //  Description: Returns the nth parent node of this node.  See
 //  Description: Returns the nth parent node of this node.  See
 //               get_num_parents().  Also see get_parents(), if your
 //               get_num_parents().  Also see get_parents(), if your
 //               intention is to iterate through the complete list of
 //               intention is to iterate through the complete list of
@@ -1379,7 +1411,7 @@ get_parent(int n) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::find_parent
 //     Function: PandaNodePipelineReader::find_parent
-//       Access: Published
+//       Access: Public
 //  Description: Returns the index of the indicated parent node, if it
 //  Description: Returns the index of the indicated parent node, if it
 //               is a parent, or -1 if it is not.
 //               is a parent, or -1 if it is not.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1390,7 +1422,7 @@ find_parent(PandaNode *node) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_num_children
 //     Function: PandaNodePipelineReader::get_num_children
-//       Access: Published
+//       Access: Public
 //  Description: Returns the number of child nodes this node has.  The
 //  Description: Returns the number of child nodes this node has.  The
 //               order of the child nodes *is* meaningful and is based
 //               order of the child nodes *is* meaningful and is based
 //               on the sort number that was passed to add_child(),
 //               on the sort number that was passed to add_child(),
@@ -1403,7 +1435,7 @@ get_num_children() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_child
 //     Function: PandaNodePipelineReader::get_child
-//       Access: Published
+//       Access: Public
 //  Description: Returns the nth child node of this node.  See
 //  Description: Returns the nth child node of this node.  See
 //               get_num_children().  Also see get_children(), if your
 //               get_num_children().  Also see get_children(), if your
 //               intention is to iterate through the complete list of
 //               intention is to iterate through the complete list of
@@ -1418,7 +1450,7 @@ get_child(int n) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_child_sort
 //     Function: PandaNodePipelineReader::get_child_sort
-//       Access: Published
+//       Access: Public
 //  Description: Returns the sort index of the nth child node of this
 //  Description: Returns the sort index of the nth child node of this
 //               node (that is, the number that was passed to
 //               node (that is, the number that was passed to
 //               add_child()).  See get_num_children().
 //               add_child()).  See get_num_children().
@@ -1432,7 +1464,7 @@ get_child_sort(int n) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::find_child
 //     Function: PandaNodePipelineReader::find_child
-//       Access: Published
+//       Access: Public
 //  Description: Returns the index of the indicated child node, if it
 //  Description: Returns the index of the indicated child node, if it
 //               is a child, or -1 if it is not.
 //               is a child, or -1 if it is not.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1443,7 +1475,7 @@ find_child(PandaNode *node) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_num_stashed
 //     Function: PandaNodePipelineReader::get_num_stashed
-//       Access: Published
+//       Access: Public
 //  Description: Returns the number of stashed nodes this node has.
 //  Description: Returns the number of stashed nodes this node has.
 //               These are former children of the node that have been
 //               These are former children of the node that have been
 //               moved to the special stashed list via stash_child().
 //               moved to the special stashed list via stash_child().
@@ -1455,7 +1487,7 @@ get_num_stashed() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_stashed
 //     Function: PandaNodePipelineReader::get_stashed
-//       Access: Published
+//       Access: Public
 //  Description: Returns the nth stashed child of this node.  See
 //  Description: Returns the nth stashed child of this node.  See
 //               get_num_stashed().  Also see get_stashed(), if your
 //               get_num_stashed().  Also see get_stashed(), if your
 //               intention is to iterate through the complete list of
 //               intention is to iterate through the complete list of
@@ -1471,7 +1503,7 @@ get_stashed(int n) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_stashed_sort
 //     Function: PandaNodePipelineReader::get_stashed_sort
-//       Access: Published
+//       Access: Public
 //  Description: Returns the sort index of the nth stashed node of this
 //  Description: Returns the sort index of the nth stashed node of this
 //               node (that is, the number that was passed to
 //               node (that is, the number that was passed to
 //               add_child()).  See get_num_stashed().
 //               add_child()).  See get_num_stashed().
@@ -1485,7 +1517,7 @@ get_stashed_sort(int n) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::find_stashed
 //     Function: PandaNodePipelineReader::find_stashed
-//       Access: Published
+//       Access: Public
 //  Description: Returns the index of the indicated stashed node, if
 //  Description: Returns the index of the indicated stashed node, if
 //               it is a stashed child, or -1 if it is not.
 //               it is a stashed child, or -1 if it is not.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1496,7 +1528,7 @@ find_stashed(PandaNode *node) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_state
 //     Function: PandaNodePipelineReader::get_state
-//       Access: Published
+//       Access: Public
 //  Description: Returns the complete RenderState that will be applied
 //  Description: Returns the complete RenderState that will be applied
 //               to all nodes at this level and below, as set on this
 //               to all nodes at this level and below, as set on this
 //               node.  This returns only the RenderState set on this
 //               node.  This returns only the RenderState set on this
@@ -1510,7 +1542,7 @@ get_state() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_effects
 //     Function: PandaNodePipelineReader::get_effects
-//       Access: Published
+//       Access: Public
 //  Description: Returns the complete RenderEffects that will be
 //  Description: Returns the complete RenderEffects that will be
 //               applied to this node.
 //               applied to this node.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1521,7 +1553,7 @@ get_effects() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_transform
 //     Function: PandaNodePipelineReader::get_transform
-//       Access: Published
+//       Access: Public
 //  Description: Returns the transform that has been set on this
 //  Description: Returns the transform that has been set on this
 //               particular node.  This is not the net transform from
 //               particular node.  This is not the net transform from
 //               the root, but simply the transform on this particular
 //               the root, but simply the transform on this particular
@@ -1534,7 +1566,7 @@ get_transform() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_prev_transform
 //     Function: PandaNodePipelineReader::get_prev_transform
-//       Access: Published
+//       Access: Public
 //  Description: Returns the transform that has been set as this
 //  Description: Returns the transform that has been set as this
 //               node's "previous" position.  See
 //               node's "previous" position.  See
 //               set_prev_transform().
 //               set_prev_transform().
@@ -1546,7 +1578,7 @@ get_prev_transform() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_tag
 //     Function: PandaNodePipelineReader::get_tag
-//       Access: Published
+//       Access: Public
 //  Description: Retrieves the user-defined value that was previously
 //  Description: Retrieves the user-defined value that was previously
 //               set on this node for the particular key, if any.  If
 //               set on this node for the particular key, if any.  If
 //               no value has been previously set, returns the empty
 //               no value has been previously set, returns the empty
@@ -1564,7 +1596,7 @@ get_tag(const string &key) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::has_tag
 //     Function: PandaNodePipelineReader::has_tag
-//       Access: Published
+//       Access: Public
 //  Description: Returns true if a value has been defined on this node
 //  Description: Returns true if a value has been defined on this node
 //               for the particular key (even if that value is the
 //               for the particular key (even if that value is the
 //               empty string), or false if no value has been set.
 //               empty string), or false if no value has been set.
@@ -1578,7 +1610,7 @@ has_tag(const string &key) const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_net_collide_mask
 //     Function: PandaNodePipelineReader::get_net_collide_mask
-//       Access: Published
+//       Access: Public
 //  Description: Returns the union of all into_collide_mask() values
 //  Description: Returns the union of all into_collide_mask() values
 //               set at CollisionNodes at this level and below.
 //               set at CollisionNodes at this level and below.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1590,7 +1622,7 @@ get_net_collide_mask() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_off_clip_planes
 //     Function: PandaNodePipelineReader::get_off_clip_planes
-//       Access: Published
+//       Access: Public
 //  Description: Returns a ClipPlaneAttrib which represents the union
 //  Description: Returns a ClipPlaneAttrib which represents the union
 //               of all of the clip planes that have been turned *off*
 //               of all of the clip planes that have been turned *off*
 //               at this level and below.
 //               at this level and below.
@@ -1603,7 +1635,7 @@ get_off_clip_planes() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_bounds
 //     Function: PandaNodePipelineReader::get_bounds
-//       Access: Published
+//       Access: Public
 //  Description: Returns the external bounding volume of this node: a
 //  Description: Returns the external bounding volume of this node: a
 //               bounding volume that contains the user bounding
 //               bounding volume that contains the user bounding
 //               volume, the internal bounding volume, and all of the
 //               volume, the internal bounding volume, and all of the
@@ -1617,7 +1649,7 @@ get_bounds() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::is_final
 //     Function: PandaNodePipelineReader::is_final
-//       Access: Published
+//       Access: Public
 //  Description: Returns the current state of the "final" flag.
 //  Description: Returns the current state of the "final" flag.
 //               Initially, this flag is off (false), but it may be
 //               Initially, this flag is off (false), but it may be
 //               changed by an explicit call to set_final().  See
 //               changed by an explicit call to set_final().  See
@@ -1628,6 +1660,22 @@ is_final() const {
   return _cdata->_final_bounds;
   return _cdata->_final_bounds;
 }
 }
 
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNodePipelineReader::get_fancy_bits
+//       Access: Public
+//  Description: Returns the union of all of the enum FancyBits values
+//               corresponding to the various "fancy" attributes that
+//               are set on the node.  If this returns 0, the node has
+//               nothing interesting about it.  This is intended to
+//               speed traversal by quickly skipping past nodes that
+//               don't particularly affect the render state.
+////////////////////////////////////////////////////////////////////
+INLINE int PandaNodePipelineReader::
+get_fancy_bits() const {
+  return _cdata->_fancy_bits;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNodePipelineReader::get_children
 //     Function: PandaNodePipelineReader::get_children
 //       Access: Public
 //       Access: Public

+ 51 - 20
panda/src/pgraph/pandaNode.cxx

@@ -157,6 +157,7 @@ PandaNode(const PandaNode &copy) :
     cdata->_internal_bounds = NULL;
     cdata->_internal_bounds = NULL;
     cdata->_internal_bounds_stale = true;
     cdata->_internal_bounds_stale = true;
     cdata->_final_bounds = copy_cdata->_final_bounds;
     cdata->_final_bounds = copy_cdata->_final_bounds;
+    cdata->_fancy_bits = copy_cdata->_fancy_bits;
     
     
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
     // Copy and increment all of the Python objects held by the other
     // Copy and increment all of the Python objects held by the other
@@ -403,29 +404,21 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any,
   return next_transform;
   return next_transform;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PandaNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PandaNode::
-has_cull_callback() const {
-  return false;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNode::cull_callback
 //     Function: PandaNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the
@@ -994,6 +987,7 @@ set_attrib(const RenderAttrib *attrib, int override) {
     CPT(RenderState) new_state = cdata->_state->add_attrib(attrib, override);
     CPT(RenderState) new_state = cdata->_state->add_attrib(attrib, override);
     if (cdata->_state != new_state) {
     if (cdata->_state != new_state) {
       cdata->_state = new_state;
       cdata->_state = new_state;
+      cdata->set_fancy_bit(FB_state, true);
       any_changed = true;
       any_changed = true;
     }
     }
   }
   }
@@ -1025,6 +1019,7 @@ clear_attrib(TypeHandle type) {
     CPT(RenderState) new_state = cdata->_state->remove_attrib(type);
     CPT(RenderState) new_state = cdata->_state->remove_attrib(type);
     if (cdata->_state != new_state) {
     if (cdata->_state != new_state) {
       cdata->_state = new_state;
       cdata->_state = new_state;
+      cdata->set_fancy_bit(FB_state, !new_state->is_empty());
       any_changed = true;
       any_changed = true;
     }
     }
   }
   }
@@ -1053,6 +1048,7 @@ set_effect(const RenderEffect *effect) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     cdata->_effects = cdata->_effects->add_effect(effect);
     cdata->_effects = cdata->_effects->add_effect(effect);
+    cdata->set_fancy_bit(FB_effects, true);
   }
   }
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
 }
 }
@@ -1069,6 +1065,7 @@ clear_effect(TypeHandle type) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     cdata->_effects = cdata->_effects->remove_effect(type);
     cdata->_effects = cdata->_effects->remove_effect(type);
+    cdata->set_fancy_bit(FB_effects, !cdata->_effects->is_empty());
   }
   }
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
 }
 }
@@ -1092,6 +1089,7 @@ set_state(const RenderState *state, Thread *current_thread) {
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     if (cdata->_state != state) {
     if (cdata->_state != state) {
       cdata->_state = state;
       cdata->_state = state;
+      cdata->set_fancy_bit(FB_state, !state->is_empty());
       any_changed = true;
       any_changed = true;
     }
     }
   }
   }
@@ -1119,6 +1117,7 @@ set_effects(const RenderEffects *effects, Thread *current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     cdata->_effects = effects;
     cdata->_effects = effects;
+    cdata->set_fancy_bit(FB_effects, !effects->is_empty());
   }
   }
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
 }
 }
@@ -1139,6 +1138,7 @@ set_transform(const TransformState *transform, Thread *current_thread) {
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     if (cdata->_transform != transform) {
     if (cdata->_transform != transform) {
       cdata->_transform = transform;
       cdata->_transform = transform;
+      cdata->set_fancy_bit(FB_transform, !transform->is_identity());
       any_changed = true;
       any_changed = true;
 
 
       if (pipeline_stage == 0) {
       if (pipeline_stage == 0) {
@@ -1259,6 +1259,7 @@ set_tag(const string &key, const string &value, Thread *current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     cdata->_tag_data[key] = value;
     cdata->_tag_data[key] = value;
+    cdata->set_fancy_bit(FB_tag, true);
   }
   }
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
 }
 }
@@ -1275,6 +1276,7 @@ clear_tag(const string &key, Thread *current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
     cdata->_tag_data.erase(key);
     cdata->_tag_data.erase(key);
+    cdata->set_fancy_bit(FB_tag, !cdata->_tag_data.empty());
   }
   }
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
 }
 }
@@ -1412,6 +1414,7 @@ copy_tags(PandaNode *other) {
          ++ti) {
          ++ti) {
       cdataw->_tag_data[(*ti).first] = (*ti).second;
       cdataw->_tag_data[(*ti).first] = (*ti).second;
     }
     }
+    cdataw->set_fancy_bit(FB_tag, !cdataw->_tag_data.empty());
     
     
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
     PythonTagData::const_iterator pti;
     PythonTagData::const_iterator pti;
@@ -1539,6 +1542,7 @@ adjust_draw_mask(DrawMask show_mask, DrawMask hide_mask, DrawMask clear_mask) {
       cdata->_draw_show_mask = draw_show_mask;
       cdata->_draw_show_mask = draw_show_mask;
       any_changed = true;
       any_changed = true;
     }
     }
+    cdata->set_fancy_bit(FB_draw_mask, !draw_control_mask.is_zero());
   }
   }
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
 
 
@@ -2186,6 +2190,24 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map,
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNode::set_cull_callback
+//       Access: Protected
+//  Description: Intended to be called in the constructor by any
+//               subclass that defines cull_callback(), this sets up
+//               the flags to indicate that the cullback needs to be
+//               called.
+////////////////////////////////////////////////////////////////////
+void PandaNode::
+set_cull_callback() {
+  Thread *current_thread = Thread::get_current_thread();
+  OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
+    CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
+    cdata->set_fancy_bit(FB_cull_callback, true);
+  }
+  CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNode::do_find_child
 //     Function: PandaNode::do_find_child
 //       Access: Private
 //       Access: Private
@@ -3254,6 +3276,7 @@ CData() {
   _internal_bounds = NULL;
   _internal_bounds = NULL;
   _internal_bounds_stale = true;
   _internal_bounds_stale = true;
   _final_bounds = false;
   _final_bounds = false;
+  _fancy_bits = 0;
 
 
   _net_collide_mask = CollideMask::all_off();
   _net_collide_mask = CollideMask::all_off();
   _net_draw_control_mask = DrawMask::all_off();
   _net_draw_control_mask = DrawMask::all_off();
@@ -3285,6 +3308,7 @@ CData(const PandaNode::CData &copy) :
   _internal_bounds(copy._internal_bounds),
   _internal_bounds(copy._internal_bounds),
   _internal_bounds_stale(copy._internal_bounds_stale),
   _internal_bounds_stale(copy._internal_bounds_stale),
   _final_bounds(copy._final_bounds),
   _final_bounds(copy._final_bounds),
+  _fancy_bits(copy._fancy_bits),
 
 
   _net_collide_mask(copy._net_collide_mask),
   _net_collide_mask(copy._net_collide_mask),
   _net_draw_control_mask(copy._net_draw_control_mask),
   _net_draw_control_mask(copy._net_draw_control_mask),
@@ -3414,6 +3438,13 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
   pi += complete_down_list(*modify_down(), p_list + pi, manager);
   pi += complete_down_list(*modify_down(), p_list + pi, manager);
   pi += complete_down_list(*modify_stashed(), p_list + pi, manager);
   pi += complete_down_list(*modify_stashed(), p_list + pi, manager);
 
 
+  // Since the _effects and _states members have been finalized by
+  // now, this should be safe.
+  set_fancy_bit(FB_transform, !_transform->is_identity());
+  set_fancy_bit(FB_state, !_state->is_empty());
+  set_fancy_bit(FB_effects, !_effects->is_empty());
+  set_fancy_bit(FB_tag, !_tag_data.empty());
+
   return pi;
   return pi;
 }
 }
 
 

+ 20 - 1
panda/src/pgraph/pandaNode.h

@@ -102,7 +102,6 @@ public:
                       const TransformState *transform,
                       const TransformState *transform,
                       Thread *current_thread) const;
                       Thread *current_thread) const;
   
   
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool has_selective_visibility() const;
   virtual bool has_selective_visibility() const;
   virtual int get_first_visible_child() const;
   virtual int get_first_visible_child() const;
@@ -253,6 +252,16 @@ PUBLISHED:
   virtual bool is_lod_node() const;
   virtual bool is_lod_node() const;
   virtual Light *as_light();
   virtual Light *as_light();
 
 
+  enum FancyBits {
+    FB_transform            = 0x0001,
+    FB_state                = 0x0002,
+    FB_effects              = 0x0004,
+    FB_tag                  = 0x0010,
+    FB_draw_mask            = 0x0020,
+    FB_cull_callback        = 0x0040,
+  };
+  INLINE int get_fancy_bits(Thread *current_thread = Thread::get_current_thread()) const;
+
 protected:
 protected:
   INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage, Thread *current_thread) const;
   INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage, Thread *current_thread) const;
   CPT(BoundingVolume) get_internal_bounds(int pipeline_stage, Thread *current_thread) const;
   CPT(BoundingVolume) get_internal_bounds(int pipeline_stage, Thread *current_thread) const;
@@ -276,6 +285,8 @@ protected:
   virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map,
   virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map,
                                Thread *current_thread);
                                Thread *current_thread);
 
 
+  void set_cull_callback();
+
 private:
 private:
   class CData;
   class CData;
 
 
@@ -409,6 +420,8 @@ private:
   public:
   public:
     // This section contains the heavierweight parts of the node that
     // This section contains the heavierweight parts of the node that
     // are less likely to change as often: tags, collide mask.
     // are less likely to change as often: tags, collide mask.
+
+    INLINE void set_fancy_bit(int bits, bool value);
     
     
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
     void inc_py_refs();
     void inc_py_refs();
@@ -447,6 +460,11 @@ private:
     // deemed "final".  See set_final().
     // deemed "final".  See set_final().
     bool _final_bounds;
     bool _final_bounds;
 
 
+    // This bitmask is maintained automatically by the internal
+    // PandaNode code; it contains a 1 for each "fancy" attribute that
+    // is set on the node.  See enum FancyBits, above.
+    int _fancy_bits;
+
   public:
   public:
     // This section contains the data that is accumulated upward from
     // This section contains the data that is accumulated upward from
     // the node's children: that is, the external bounding volume, and
     // the node's children: that is, the external bounding volume, and
@@ -667,6 +685,7 @@ public:
   INLINE CPT(RenderAttrib) get_off_clip_planes() const;
   INLINE CPT(RenderAttrib) get_off_clip_planes() const;
   INLINE CPT(BoundingVolume) get_bounds() const;
   INLINE CPT(BoundingVolume) get_bounds() const;
   INLINE bool is_final() const;
   INLINE bool is_final() const;
+  INLINE int get_fancy_bits() const;
 
 
   INLINE PandaNode::Children get_children() const;
   INLINE PandaNode::Children get_children() const;
   INLINE PandaNode::Stashed get_stashed() const;
   INLINE PandaNode::Stashed get_stashed() const;

+ 14 - 20
panda/src/pgraph/planeNode.cxx

@@ -77,6 +77,8 @@ PlaneNode(const string &name, const Planef &plane) :
   PandaNode(name),
   PandaNode(name),
   _priority(0)
   _priority(0)
 {
 {
+  set_cull_callback();
+
   // PlaneNodes are hidden by default.
   // PlaneNodes are hidden by default.
   set_overall_hidden(true);
   set_overall_hidden(true);
 
 
@@ -136,29 +138,21 @@ xform(const LMatrix4f &mat) {
   cdata->_back_viz = NULL;
   cdata->_back_viz = NULL;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PlaneNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PlaneNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PlaneNode::cull_callback
 //     Function: PlaneNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgraph/planeNode.h

@@ -52,7 +52,6 @@ public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
   virtual void xform(const LMatrix4f &mat);
   virtual void xform(const LMatrix4f &mat);
 
 
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool is_renderable() const;
   virtual bool is_renderable() const;
 
 

+ 10 - 20
panda/src/pgraph/portalNode.cxx

@@ -57,6 +57,8 @@ PortalNode(const string &name) :
   _into_portal_mask(PortalMask::all_on()),
   _into_portal_mask(PortalMask::all_on()),
   _flags(0)
   _flags(0)
 {
 {
+  set_cull_callback();
+
   _visible = false;
   _visible = false;
   _open = true;
   _open = true;
   _clip_plane = false;
   _clip_plane = false;
@@ -75,6 +77,8 @@ PortalNode(const string &name, LPoint3f pos, float scale) :
   _into_portal_mask(PortalMask::all_on()),
   _into_portal_mask(PortalMask::all_on()),
   _flags(0)
   _flags(0)
 {
 {
+  set_cull_callback();
+
   add_vertex(LPoint3f(pos[0]-1.0*scale, pos[1], pos[2]-1.0*scale));
   add_vertex(LPoint3f(pos[0]-1.0*scale, pos[1], pos[2]-1.0*scale));
   add_vertex(LPoint3f(pos[0]+1.0*scale, pos[1], pos[2]-1.0*scale));
   add_vertex(LPoint3f(pos[0]+1.0*scale, pos[1], pos[2]-1.0*scale));
   add_vertex(LPoint3f(pos[0]+1.0*scale, pos[1], pos[2]+1.0*scale));
   add_vertex(LPoint3f(pos[0]+1.0*scale, pos[1], pos[2]+1.0*scale));
@@ -224,29 +228,15 @@ combine_with(PandaNode *other) {
   return PandaNode::combine_with(other);
   return PandaNode::combine_with(other);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PortalNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PortalNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PortalNode::cull_callback
 //     Function: PortalNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               reduced frustum culling. Basically, once the scenegraph
-//               comes across a portal node, it calculates a CulltraverserData
-//               with which cell, this portal leads out to and the new frustum.
-//               Then it traverses that child
+//  Description: This function will be called during the cull
+//               traversal to perform reduced frustum
+//               culling. Basically, once the scenegraph comes across
+//               a portal node, it calculates a CulltraverserData with
+//               which cell, this portal leads out to and the new
+//               frustum.  Then it traverses that child
 //
 //
 //               The return value is true if this node should be
 //               The return value is true if this node should be
 //               visible, or false if it should be culled.
 //               visible, or false if it should be culled.

+ 0 - 1
panda/src/pgraph/portalNode.h

@@ -58,7 +58,6 @@ public:
 
 
   virtual void enable_clipping_planes();
   virtual void enable_clipping_planes();
 
 
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool is_renderable() const;
   virtual bool is_renderable() const;
 
 

+ 1 - 0
panda/src/pgraph/sequenceNode.I

@@ -26,6 +26,7 @@ INLINE SequenceNode::
 SequenceNode(const string &name) :
 SequenceNode(const string &name) :
   SelectiveChildNode(name)
   SelectiveChildNode(name)
 {
 {
+  set_cull_callback();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 12 - 20
panda/src/pgraph/sequenceNode.cxx

@@ -77,29 +77,21 @@ make_copy() const {
   return new SequenceNode(*this);
   return new SequenceNode(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: SequenceNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool SequenceNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SequenceNode::cull_callback
 //     Function: SequenceNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgraph/sequenceNode.h

@@ -45,7 +45,6 @@ public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
   virtual bool safe_to_combine() const;
   virtual bool safe_to_combine() const;
 
 
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool has_single_child_visibility() const;
   virtual bool has_single_child_visibility() const;
 
 

+ 1 - 0
panda/src/pgraph/switchNode.I

@@ -47,6 +47,7 @@ INLINE SwitchNode::
 SwitchNode(const string &name) :
 SwitchNode(const string &name) :
   SelectiveChildNode(name)
   SelectiveChildNode(name)
 {
 {
+  set_cull_callback();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 12 - 20
panda/src/pgraph/switchNode.cxx

@@ -95,29 +95,21 @@ make_copy() const {
   return new SwitchNode(*this);
   return new SwitchNode(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: SwitchNode::has_cull_callback
-//       Access: Public, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool SwitchNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SwitchNode::cull_callback
 //     Function: SwitchNode::cull_callback
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgraph/switchNode.h

@@ -38,7 +38,6 @@ public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
   virtual bool safe_to_combine() const;
   virtual bool safe_to_combine() const;
 
 
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool has_single_child_visibility() const;
   virtual bool has_single_child_visibility() const;
 
 

+ 14 - 20
panda/src/pgui/pgEntry.cxx

@@ -43,6 +43,8 @@ PGEntry::
 PGEntry(const string &name) : 
 PGEntry(const string &name) : 
   PGItem(name)
   PGItem(name)
 {
 {
+  set_cull_callback();
+
   _cursor_position = 0;
   _cursor_position = 0;
   _cursor_stale = true;
   _cursor_stale = true;
   _candidate_highlight_start = 0;
   _candidate_highlight_start = 0;
@@ -120,29 +122,21 @@ make_copy() const {
   return new PGEntry(*this);
   return new PGEntry(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PGEntry::has_cull_callback
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PGEntry::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PGEntry::cull_callback
 //     Function: PGEntry::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgui/pgEntry.h

@@ -52,7 +52,6 @@ protected:
 
 
 public:
 public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
 
 
   virtual void press(const MouseWatcherParameter &param, bool background);
   virtual void press(const MouseWatcherParameter &param, bool background);

+ 14 - 20
panda/src/pgui/pgItem.cxx

@@ -60,6 +60,8 @@ PGItem::
 PGItem(const string &name) : 
 PGItem(const string &name) : 
   PandaNode(name)
   PandaNode(name)
 {
 {
+  set_cull_callback();
+
   _notify = NULL;
   _notify = NULL;
   _has_frame = false;
   _has_frame = false;
   _frame.set(0, 0, 0, 0);
   _frame.set(0, 0, 0, 0);
@@ -173,29 +175,21 @@ draw_mask_changed() {
   }
   }
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PGItem::has_cull_callback
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PGItem::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PGItem::cull_callback
 //     Function: PGItem::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgui/pgItem.h

@@ -65,7 +65,6 @@ protected:
   virtual void transform_changed();
   virtual void transform_changed();
   virtual void draw_mask_changed();
   virtual void draw_mask_changed();
 
 
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool is_renderable() const;
   virtual bool is_renderable() const;
 
 

+ 14 - 20
panda/src/pgui/pgScrollFrame.cxx

@@ -28,6 +28,8 @@ TypeHandle PGScrollFrame::_type_handle;
 PGScrollFrame::
 PGScrollFrame::
 PGScrollFrame(const string &name) : PGVirtualFrame(name)
 PGScrollFrame(const string &name) : PGVirtualFrame(name)
 {
 {
+  set_cull_callback();
+
   _needs_remanage = false;
   _needs_remanage = false;
   _needs_recompute_canvas = false;
   _needs_recompute_canvas = false;
   _needs_recompute_clip = false;
   _needs_recompute_clip = false;
@@ -81,29 +83,21 @@ make_copy() const {
   return new PGScrollFrame(*this);
   return new PGScrollFrame(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PGScrollFrame::has_cull_callback
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PGScrollFrame::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PGScrollFrame::cull_callback
 //     Function: PGScrollFrame::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgui/pgScrollFrame.h

@@ -50,7 +50,6 @@ protected:
 
 
 public:
 public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual void xform(const LMatrix4f &mat);
   virtual void xform(const LMatrix4f &mat);
 
 

+ 14 - 20
panda/src/pgui/pgSliderBar.cxx

@@ -36,6 +36,8 @@ PGSliderBar::
 PGSliderBar(const string &name) 
 PGSliderBar(const string &name) 
   : PGItem(name)
   : PGItem(name)
 {
 {
+  set_cull_callback();
+
   _min_value = 0.0f;
   _min_value = 0.0f;
   _max_value = 1.0f;
   _max_value = 1.0f;
   set_scroll_size(0.01f);
   set_scroll_size(0.01f);
@@ -168,29 +170,21 @@ move(const MouseWatcherParameter &param) {
   }
   }
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PGSliderBar::has_cull_callback
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PGSliderBar::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PGSliderBar::cull_callback
 //     Function: PGSliderBar::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgui/pgSliderBar.h

@@ -45,7 +45,6 @@ protected:
 
 
 public:
 public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual void xform(const LMatrix4f &mat);
   virtual void xform(const LMatrix4f &mat);
 
 

+ 14 - 20
panda/src/pgui/pgTop.cxx

@@ -34,6 +34,8 @@ PGTop::
 PGTop(const string &name) : 
 PGTop(const string &name) : 
   PandaNode(name)
   PandaNode(name)
 {
 {
+  set_cull_callback();
+
   _start_sort = 0;
   _start_sort = 0;
 
 
   // A PGTop node normally has an infinite bounding volume.  Screw
   // A PGTop node normally has an infinite bounding volume.  Screw
@@ -71,29 +73,21 @@ make_copy() const {
   return new PGTop(*this);
   return new PGTop(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PGTop::has_cull_callback
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PGTop::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PGTop::cull_callback
 //     Function: PGTop::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgui/pgTop.h

@@ -54,7 +54,6 @@ protected:
 
 
 public:
 public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool is_renderable() const;
   virtual bool is_renderable() const;
 
 

+ 14 - 20
panda/src/pgui/pgWaitBar.cxx

@@ -31,6 +31,8 @@ TypeHandle PGWaitBar::_type_handle;
 PGWaitBar::
 PGWaitBar::
 PGWaitBar(const string &name) : PGItem(name)
 PGWaitBar(const string &name) : PGItem(name)
 {
 {
+  set_cull_callback();
+
   _range = 100.0;
   _range = 100.0;
   _value = 0.0;
   _value = 0.0;
   _bar_state = -1;
   _bar_state = -1;
@@ -72,29 +74,21 @@ make_copy() const {
   return new PGWaitBar(*this);
   return new PGWaitBar(*this);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: PGWaitBar::has_cull_callback
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool PGWaitBar::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PGWaitBar::cull_callback
 //     Function: PGWaitBar::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/pgui/pgWaitBar.h

@@ -40,7 +40,6 @@ protected:
 
 
 public:
 public:
   virtual PandaNode *make_copy() const;
   virtual PandaNode *make_copy() const;
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
 
 
 PUBLISHED:
 PUBLISHED:

+ 14 - 20
panda/src/text/textNode.cxx

@@ -64,6 +64,8 @@ static PStatCollector text_generate_collector("*:Generate Text");
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 TextNode::
 TextNode::
 TextNode(const string &name) : PandaNode(name), _assembler(this) {
 TextNode(const string &name) : PandaNode(name), _assembler(this) {
+  set_cull_callback();
+
   _flags = 0;
   _flags = 0;
   _max_rows = 0;
   _max_rows = 0;
 
 
@@ -553,29 +555,21 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any,
   return next_transform;
   return next_transform;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: TextNode::has_cull_callback
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to return
-//               true if cull_callback() has been defined.  Otherwise,
-//               returns false to indicate cull_callback() does not
-//               need to be called for this node during the cull
-//               traversal.
-////////////////////////////////////////////////////////////////////
-bool TextNode::
-has_cull_callback() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextNode::cull_callback
 //     Function: TextNode::cull_callback
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
-//  Description: If has_cull_callback() returns true, this function
-//               will be called during the cull traversal to perform
-//               any additional operations that should be performed at
-//               cull time.  This may include additional manipulation
-//               of render state or additional visible/invisible
-//               decisions, or any other arbitrary operation.
+//  Description: This function will be called during the cull
+//               traversal to perform any additional operations that
+//               should be performed at cull time.  This may include
+//               additional manipulation of render state or additional
+//               visible/invisible decisions, or any other arbitrary
+//               operation.
+//
+//               Note that this function will *not* be called unless
+//               set_cull_callback() is called in the constructor of
+//               the derived class.  It is necessary to call
+//               set_cull_callback() to indicated that we require
+//               cull_callback() to be called.
 //
 //
 //               By the time this function is called, the node has
 //               By the time this function is called, the node has
 //               already passed the bounding-volume test for the
 //               already passed the bounding-volume test for the

+ 0 - 1
panda/src/text/textNode.h

@@ -240,7 +240,6 @@ public:
                       const TransformState *transform,
                       const TransformState *transform,
                       Thread *current_thread) const;
                       Thread *current_thread) const;
 
 
-  virtual bool has_cull_callback() const;
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
   virtual bool is_renderable() const;
   virtual bool is_renderable() const;