traverse to all children of LOD node

This commit is contained in:
David Rose 2006-02-27 18:49:46 +00:00
parent a30470be19
commit 43bbca86fb
4 changed files with 55 additions and 5 deletions

View File

@ -25,7 +25,8 @@
INLINE CollisionLevelState::
CollisionLevelState(const NodePath &node_path) :
_node_path(node_path),
_current(0)
_current(0),
_include_mask(CollideMask::all_on())
{
}
@ -40,6 +41,7 @@ CollisionLevelState(const CollisionLevelState &parent, PandaNode *child) :
_node_path(parent._node_path, child),
_colliders(parent._colliders),
_current(parent._current),
_include_mask(parent._include_mask),
_local_bounds(parent._local_bounds)
{
}
@ -54,6 +56,7 @@ CollisionLevelState(const CollisionLevelState &copy) :
_node_path(copy._node_path),
_colliders(copy._colliders),
_current(copy._current),
_include_mask(copy._include_mask),
_local_bounds(copy._local_bounds),
_parent_bounds(copy._parent_bounds)
{
@ -69,6 +72,7 @@ operator = (const CollisionLevelState &copy) {
_node_path = copy._node_path;
_colliders = copy._colliders;
_current = copy._current;
_include_mask = copy._include_mask;
_local_bounds = copy._local_bounds;
_parent_bounds = copy._parent_bounds;
}
@ -232,6 +236,39 @@ omit_collider(int n) {
_current &= ~get_mask(n);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::set_include_mask
// Access: Public
// Description: Specifies the mask that is applied to the into
// CollideMask of nodes in the scene graph before
// testing for bits in common with the from CollideMask
// of colliders. This is normally all bits on, but you
// may set it to some other mask to restrict certain
// bits from consideration.
//
// This is used by the CollisionTraverser to restrict
// collision with geometry except under the lowest level
// of LOD.
////////////////////////////////////////////////////////////////////
INLINE void CollisionLevelState::
set_include_mask(CollideMask include_mask) {
_include_mask = include_mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_include_mask
// Access: Public
// Description: Returns the mask that is applied to the into
// CollideMask of nodes in the scene graph before
// testing for bits in common with the from CollideMask
// of colliders. See set_include_mask().
////////////////////////////////////////////////////////////////////
INLINE CollideMask CollisionLevelState::
get_include_mask() const {
return _include_mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_mask
// Access: Private

View File

@ -132,7 +132,7 @@ any_in_bounds() {
// Don't even bother testing the bounding volume if there are
// no collide bits in common between our collider and this
// node.
CollideMask from_mask = cnode->get_from_collide_mask();
CollideMask from_mask = cnode->get_from_collide_mask() & _include_mask;
if (cnode->get_collide_geom() ||
(from_mask & node()->get_net_collide_mask()) != 0) {
// There are bits in common, so go ahead and try the

View File

@ -77,6 +77,9 @@ public:
INLINE void omit_collider(int n);
INLINE void set_include_mask(CollideMask include_mask);
INLINE CollideMask get_include_mask() const;
private:
// CurrentMask here is a locally-defined value that simply serves
// to keep track of the colliders that are still interested in the
@ -92,6 +95,7 @@ private:
typedef PTA(ColliderDef) Colliders;
Colliders _colliders;
CurrentMask _current;
CollideMask _include_mask;
typedef PTA(CPT(GeometricBoundingVolume)) BoundingVolumes;
BoundingVolumes _local_bounds;

View File

@ -602,10 +602,19 @@ r_traverse(CollisionLevelState &level_state) {
}
} else if (node->is_lod_node()) {
// If it's an LODNode, visit the lowest level of detail.
// If it's an LODNode, visit the lowest level of detail with all
// bits, allowing collision with geometry under the lowest level
// of default; and visit all other levels without
// GeomNode::get_default_collide_mask(), allowing only collision
// with CollisionNodes and special geometry under higher levels of
// detail.
int index = DCAST(LODNode, node)->get_lowest_switch();
if (index >= 0 && index < node->get_num_children()) {
CollisionLevelState next_state(level_state, node->get_child(index));
int num_children = node->get_num_children();
for (int i = 0; i < num_children; ++i) {
CollisionLevelState next_state(level_state, node->get_child(i));
if (i != index) {
next_state.set_include_mask(next_state.get_include_mask() & ~GeomNode::get_default_collide_mask());
}
r_traverse(next_state);
}