Browse Source

collision traverser doesn't visit switch nodes

David Rose 23 years ago
parent
commit
44d544aeb2

+ 16 - 4
panda/src/collide/collisionTraverser.cxx

@@ -447,10 +447,22 @@ r_traverse(CollisionLevelState &level_state) {
     }
     }
   }
   }
 
 
-  int num_children = node->get_num_children();
-  for (int i = 0; i < num_children; i++) {
-    CollisionLevelState next_state(level_state, node->get_child(i));
-    r_traverse(next_state);
+  if (node->has_single_child_visibility()) {
+    // If it's a switch node or sequence node, visit just the one
+    // visible child.
+    int index = node->get_visible_child();
+    if (index >= 0 && index < node->get_num_children()) {
+      CollisionLevelState next_state(level_state, node->get_child(index));
+      r_traverse(next_state);
+    }
+
+  } else {
+    // Otherwise, visit all the children.
+    int num_children = node->get_num_children();
+    for (int i = 0; i < num_children; i++) {
+      CollisionLevelState next_state(level_state, node->get_child(i));
+      r_traverse(next_state);
+    }
   }
   }
 }
 }
 
 

+ 33 - 0
panda/src/pgraph/pandaNode.cxx

@@ -744,6 +744,39 @@ get_next_visible_child(int n) const {
   return n + 1;
   return n + 1;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNode::has_single_child_visibility
+//       Access: Public, Virtual
+//  Description: Should be overridden by derived classes to return
+//               true if this kind of node has the special property
+//               that just one of its children is visible at any given
+//               time, and furthermore that the particular visible
+//               child can be determined without reference to any
+//               external information (such as a camera).  At present,
+//               only SequenceNodes and SwitchNodes fall into this
+//               category.
+//
+//               If this function returns true, get_visible_child()
+//               can be called to return the index of the
+//               currently-visible child.
+////////////////////////////////////////////////////////////////////
+bool PandaNode::
+has_single_child_visibility() const {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaNode::get_visible_child
+//       Access: Public, Virtual
+//  Description: Returns the index number of the currently visible
+//               child of this node.  This is only meaningful if
+//               has_single_child_visibility() has returned true.
+////////////////////////////////////////////////////////////////////
+int PandaNode::
+get_visible_child() const {
+  return 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PandaNode::copy_subgraph
 //     Function: PandaNode::copy_subgraph
 //       Access: Published
 //       Access: Published

+ 2 - 0
panda/src/pgraph/pandaNode.h

@@ -91,6 +91,8 @@ public:
   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;
   virtual int get_next_visible_child(int n) const;
   virtual int get_next_visible_child(int n) const;
+  virtual bool has_single_child_visibility() const;
+  virtual int get_visible_child() const;
 
 
 PUBLISHED:
 PUBLISHED:
   PT(PandaNode) copy_subgraph() const;
   PT(PandaNode) copy_subgraph() const;

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

@@ -105,24 +105,6 @@ set_visible_child(int index) {
   }
   }
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: SequenceNode::get_visible_child
-//       Access: Published
-//  Description: Returns the index of the child that should be visible
-//               for this particular frame, if there are any children.
-////////////////////////////////////////////////////////////////////
-INLINE int SequenceNode::
-get_visible_child() const {
-  int num_children = get_num_children();
-  if (num_children == 0) {
-    return 0;
-  }
-
-  float frame = calc_frame();
-
-  return ((int)frame) % num_children;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SequenceNode::calc_frame
 //     Function: SequenceNode::calc_frame
 //       Access: Private
 //       Access: Private

+ 39 - 0
panda/src/pgraph/sequenceNode.cxx

@@ -142,6 +142,45 @@ cull_callback(CullTraverser *, CullTraverserData &) {
   return true;
   return true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: SequenceNode::has_single_child_visibility
+//       Access: Public, Virtual
+//  Description: Should be overridden by derived classes to return
+//               true if this kind of node has the special property
+//               that just one of its children is visible at any given
+//               time, and furthermore that the particular visible
+//               child can be determined without reference to any
+//               external information (such as a camera).  At present,
+//               only SequenceNodes and SwitchNodes fall into this
+//               category.
+//
+//               If this function returns true, get_visible_child()
+//               can be called to return the index of the
+//               currently-visible child.
+////////////////////////////////////////////////////////////////////
+bool SequenceNode::
+has_single_child_visibility() const {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: SequenceNode::get_visible_child
+//       Access: Published, Virtual
+//  Description: Returns the index of the child that should be visible
+//               for this particular frame, if there are any children.
+////////////////////////////////////////////////////////////////////
+int SequenceNode::
+get_visible_child() const {
+  int num_children = get_num_children();
+  if (num_children == 0) {
+    return 0;
+  }
+
+  float frame = calc_frame();
+
+  return ((int)frame) % num_children;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SequenceNode::register_with_read_factory
 //     Function: SequenceNode::register_with_read_factory
 //       Access: Public, Static
 //       Access: Public, Static

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

@@ -41,13 +41,14 @@ public:
 
 
   virtual bool has_cull_callback() 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;
 
 
 PUBLISHED:
 PUBLISHED:
   INLINE void set_cycle_rate(float cycle_rate);
   INLINE void set_cycle_rate(float cycle_rate);
   INLINE float get_cycle_rate() const;
   INLINE float get_cycle_rate() const;
 
 
   INLINE void set_visible_child(int index);
   INLINE void set_visible_child(int index);
-  INLINE int get_visible_child() const;
+  virtual int get_visible_child() const;
 
 
 private:
 private:
   INLINE float calc_frame(float now) const;
   INLINE float calc_frame(float now) const;

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

@@ -60,14 +60,3 @@ set_visible_child(int index) {
   CDWriter cdata(_cycler);
   CDWriter cdata(_cycler);
   cdata->_visible_child = index;
   cdata->_visible_child = index;
 }
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: SwitchNode::get_visible_child
-//       Access: Published
-//  Description: Returns the index of the child that should be visible.
-////////////////////////////////////////////////////////////////////
-INLINE int SwitchNode::
-get_visible_child() const {
-  CDReader cdata(_cycler);
-  return cdata->_visible_child;
-}

+ 32 - 0
panda/src/pgraph/switchNode.cxx

@@ -134,6 +134,38 @@ cull_callback(CullTraverser *, CullTraverserData &) {
   return true;
   return true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: SwitchNode::has_single_child_visibility
+//       Access: Public, Virtual
+//  Description: Should be overridden by derived classes to return
+//               true if this kind of node has the special property
+//               that just one of its children is visible at any given
+//               time, and furthermore that the particular visible
+//               child can be determined without reference to any
+//               external information (such as a camera).  At present,
+//               only SequenceNodes and SwitchNodes fall into this
+//               category.
+//
+//               If this function returns true, get_visible_child()
+//               can be called to return the index of the
+//               currently-visible child.
+////////////////////////////////////////////////////////////////////
+bool SwitchNode::
+has_single_child_visibility() const {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: SwitchNode::get_visible_child
+//       Access: Published, Virtual
+//  Description: Returns the index of the child that should be visible.
+////////////////////////////////////////////////////////////////////
+int SwitchNode::
+get_visible_child() const {
+  CDReader cdata(_cycler);
+  return cdata->_visible_child;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SwitchNode::register_with_read_factory
 //     Function: SwitchNode::register_with_read_factory
 //       Access: Public, Static
 //       Access: Public, Static

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

@@ -40,10 +40,11 @@ public:
 
 
   virtual bool has_cull_callback() 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;
 
 
 PUBLISHED:
 PUBLISHED:
   INLINE void set_visible_child(int index);
   INLINE void set_visible_child(int index);
-  INLINE int get_visible_child() const;
+  virtual int get_visible_child() const;
 
 
 private:
 private:
   class EXPCL_PANDA CData : public CycleData {
   class EXPCL_PANDA CData : public CycleData {