diff --git a/panda/src/collide/collisionTraverser.cxx b/panda/src/collide/collisionTraverser.cxx index b93164e1a1..bf3eb009d4 100644 --- a/panda/src/collide/collisionTraverser.cxx +++ b/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); + } } } diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index ad551f8b76..94acef9aec 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -744,6 +744,39 @@ get_next_visible_child(int n) const { 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 // Access: Published diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index eaa983681a..c3fa421bc0 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -91,6 +91,8 @@ public: virtual bool has_selective_visibility() const; virtual int get_first_visible_child() const; virtual int get_next_visible_child(int n) const; + virtual bool has_single_child_visibility() const; + virtual int get_visible_child() const; PUBLISHED: PT(PandaNode) copy_subgraph() const; diff --git a/panda/src/pgraph/sequenceNode.I b/panda/src/pgraph/sequenceNode.I index 5d08c297e7..0706d46370 100644 --- a/panda/src/pgraph/sequenceNode.I +++ b/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 // Access: Private diff --git a/panda/src/pgraph/sequenceNode.cxx b/panda/src/pgraph/sequenceNode.cxx index f4b4e296df..dbb09d827f 100644 --- a/panda/src/pgraph/sequenceNode.cxx +++ b/panda/src/pgraph/sequenceNode.cxx @@ -142,6 +142,45 @@ cull_callback(CullTraverser *, CullTraverserData &) { 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 // Access: Public, Static diff --git a/panda/src/pgraph/sequenceNode.h b/panda/src/pgraph/sequenceNode.h index 7ffbf48a4a..7289f6f46e 100644 --- a/panda/src/pgraph/sequenceNode.h +++ b/panda/src/pgraph/sequenceNode.h @@ -41,13 +41,14 @@ public: virtual bool has_cull_callback() const; virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); + virtual bool has_single_child_visibility() const; PUBLISHED: INLINE void set_cycle_rate(float cycle_rate); INLINE float get_cycle_rate() const; INLINE void set_visible_child(int index); - INLINE int get_visible_child() const; + virtual int get_visible_child() const; private: INLINE float calc_frame(float now) const; diff --git a/panda/src/pgraph/switchNode.I b/panda/src/pgraph/switchNode.I index c8f0cfc1bc..430db8c73e 100644 --- a/panda/src/pgraph/switchNode.I +++ b/panda/src/pgraph/switchNode.I @@ -60,14 +60,3 @@ set_visible_child(int index) { CDWriter cdata(_cycler); 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; -} diff --git a/panda/src/pgraph/switchNode.cxx b/panda/src/pgraph/switchNode.cxx index 71c1d0cb91..b1cc0c6539 100644 --- a/panda/src/pgraph/switchNode.cxx +++ b/panda/src/pgraph/switchNode.cxx @@ -134,6 +134,38 @@ cull_callback(CullTraverser *, CullTraverserData &) { 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 // Access: Public, Static diff --git a/panda/src/pgraph/switchNode.h b/panda/src/pgraph/switchNode.h index e8c0d3f039..633dbc2a53 100644 --- a/panda/src/pgraph/switchNode.h +++ b/panda/src/pgraph/switchNode.h @@ -40,10 +40,11 @@ public: virtual bool has_cull_callback() const; virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); + virtual bool has_single_child_visibility() const; PUBLISHED: INLINE void set_visible_child(int index); - INLINE int get_visible_child() const; + virtual int get_visible_child() const; private: class EXPCL_PANDA CData : public CycleData {