all nodes now have a CollideMask

This commit is contained in:
David Rose 2004-09-23 19:51:54 +00:00
parent 47a6d4716f
commit 0369f07074
18 changed files with 338 additions and 168 deletions

View File

@ -39,7 +39,6 @@ CollisionLevelState(const CollisionLevelState &parent, PandaNode *child) :
_node_path(parent._node_path, child),
_colliders(parent._colliders),
_current(parent._current),
_colliders_with_geom(parent._colliders_with_geom),
_local_bounds(parent._local_bounds)
{
}
@ -88,19 +87,6 @@ has_collider(int n) const {
return (_current & get_mask(n)) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::has_collider_with_geom
// Access: Public
// Description: Returns true if the nth collider in the LevelState is
// still part of the level, and it has the
// "collide_geom" flag set.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionLevelState::
has_collider_with_geom(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), false);
return (_current & _colliders_with_geom & get_mask(n)) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::has_any_collider
// Access: Public
@ -111,31 +97,6 @@ has_any_collider() const {
return _current != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::has_any_collide_geom
// Access: Public
// Description: Returns true if any Collider in the level state has
// the "collide_geom" flag set, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool CollisionLevelState::
has_any_collide_geom() const {
return (_current & _colliders_with_geom) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::reached_collision_node
// Access: Public
// Description: Called by the traverser when we reach a CollisionNode
// in the traversal. At this point, we zero out our set
// of colliders with the "collide_geom" flag set,
// because no colliders will test against geometry
// parented beneath a CollisionNode.
////////////////////////////////////////////////////////////////////
INLINE void CollisionLevelState::
reached_collision_node() {
_colliders_with_geom = 0;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_collider
// Access: Public

View File

@ -31,7 +31,6 @@ clear() {
_local_bounds.clear();
_parent_bounds.clear();
_current = 0;
_colliders_with_geom = 0;
}
////////////////////////////////////////////////////////////////////
@ -89,9 +88,6 @@ prepare_collider(const ColliderDef &def) {
_current |= get_mask(index);
if (def._node->get_collide_geom()) {
_colliders_with_geom |= get_mask(index);
}
_parent_bounds = _local_bounds;
}

View File

@ -63,11 +63,7 @@ public:
INLINE int get_num_colliders() const;
INLINE bool has_collider(int n) const;
INLINE bool has_collider_with_geom(int n) const;
INLINE bool has_any_collider() const;
INLINE bool has_any_collide_geom() const;
INLINE void reached_collision_node();
INLINE CollisionSolid *get_collider(int n) const;
INLINE CollisionNode *get_collider_node(int n) const;
@ -92,7 +88,6 @@ private:
typedef PTA(ColliderDef) Colliders;
Colliders _colliders;
ColliderMask _current;
ColliderMask _colliders_with_geom;
typedef PTA(CPT(GeometricBoundingVolume)) BoundingVolumes;
BoundingVolumes _local_bounds;

View File

@ -29,20 +29,6 @@ set_collide_mask(CollideMask mask) {
set_into_collide_mask(mask);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_from_collide_mask
// Access: Published
// Description: Sets the "from" CollideMask. In order for a
// collision to be detected from this object into
// another object, the intersection of this object's
// "from" mask and the other object's "into" mask must
// be nonzero.
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
set_from_collide_mask(CollideMask mask) {
_from_collide_mask = mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_into_collide_mask
// Access: Published
@ -54,12 +40,8 @@ set_from_collide_mask(CollideMask mask) {
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
set_into_collide_mask(CollideMask mask) {
_into_collide_mask = mask;
// We mark the bound stale when this changes, not because the actual
// bounding volume changes, but rather because we piggyback the
// computing of the _net_collide_mask on the bounding volume.
mark_bound_stale();
// This is now inherited from the PandaNode base class.
PandaNode::set_into_collide_mask(mask);
}
////////////////////////////////////////////////////////////////////
@ -87,42 +69,8 @@ get_from_collide_mask() const {
////////////////////////////////////////////////////////////////////
INLINE CollideMask CollisionNode::
get_into_collide_mask() const {
return _into_collide_mask;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_collide_geom
// Access: Published
// Description: Sets the state of the "collide geom" flag for this
// CollisionNode. Normally, this is false; when this is
// set true, the CollisionSolids in this node will test
// for collisions with actual renderable geometry, in
// addition to whatever CollisionSolids may be indicated
// by the from_collide_mask.
//
// Setting this to true causes this to test *all*
// GeomNodes for collisions. It is an all-or-none
// thing; there is no way to collide with only some
// GeomNodes, as GeomNodes have no into_collide_mask.
////////////////////////////////////////////////////////////////////
INLINE void CollisionNode::
set_collide_geom(bool flag) {
if (flag) {
_flags |= F_collide_geom;
} else {
_flags &= ~F_collide_geom;
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_collide_geom
// Access: Published
// Description: Returns the current state of the collide_geom flag.
// See set_collide_geom().
////////////////////////////////////////////////////////////////////
INLINE bool CollisionNode::
get_collide_geom() const {
return (_flags & F_collide_geom) != 0;
// This is now inherited from the PandaNode base class.
return PandaNode::get_into_collide_mask();
}
////////////////////////////////////////////////////////////////////
@ -195,3 +143,14 @@ add_solid(CollisionSolid *solid) {
mark_bound_stale();
return _solids.size() - 1;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_default_collide_mask
// Access: Published, Static
// Description: Returns the default into_collide_mask assigned to new
// CollisionNodes.
////////////////////////////////////////////////////////////////////
INLINE CollideMask CollisionNode::
get_default_collide_mask() {
return default_collision_node_collide_mask;
}

View File

@ -30,6 +30,7 @@
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "clockObject.h"
TypeHandle CollisionNode::_type_handle;
@ -42,12 +43,14 @@ TypeHandle CollisionNode::_type_handle;
CollisionNode::
CollisionNode(const string &name) :
PandaNode(name),
_from_collide_mask(CollideMask::all_on()),
_into_collide_mask(CollideMask::all_on()),
_flags(0)
_from_collide_mask(get_default_collide_mask()),
_collide_geom(false)
{
// CollisionNodes are hidden by default.
set_draw_mask(DrawMask::all_off());
// CollisionNodes have a certain set of bits on by default.
set_into_collide_mask(get_default_collide_mask());
}
////////////////////////////////////////////////////////////////////
@ -59,8 +62,6 @@ CollisionNode::
CollisionNode(const CollisionNode &copy) :
PandaNode(copy),
_from_collide_mask(copy._from_collide_mask),
_into_collide_mask(copy._into_collide_mask),
_flags(copy._flags),
_solids(copy._solids)
{
}
@ -167,6 +168,22 @@ combine_with(PandaNode *other) {
return PandaNode::combine_with(other);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_legal_collide_mask
// Access: Published, Virtual
// Description: Returns the subset of CollideMask bits that may be
// set for this particular type of PandaNode. For most
// nodes, this is 0; it doesn't make sense to set a
// CollideMask for most kinds of nodes.
//
// For nodes that can be collided with, such as GeomNode
// and CollisionNode, this returns all bits on.
////////////////////////////////////////////////////////////////////
CollideMask CollisionNode::
get_legal_collide_mask() const {
return CollideMask::all_on();
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::has_cull_callback
// Access: Public, Virtual
@ -260,22 +277,74 @@ output(ostream &out) const {
out << " (" << _solids.size() << " solids)";
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::set_from_collide_mask
// Access: Published
// Description: Sets the "from" CollideMask. In order for a
// collision to be detected from this object into
// another object, the intersection of this object's
// "from" mask and the other object's "into" mask must
// be nonzero.
////////////////////////////////////////////////////////////////////
void CollisionNode::
set_from_collide_mask(CollideMask mask) {
_from_collide_mask = mask;
if (_collide_geom) {
_from_collide_mask |= GeomNode::get_default_collide_mask();
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::recompute_bound
// Access: Protected, Virtual
// Description: Recomputes the dynamic bounding volume for this
// object. This is the bounding volume for the node and
// all of its children, and normally does not need to be
// specialized beyond PandaNode; we specialize this
// function just so we can piggyback on it the
// setting the _net_collide_mask bits.
// Function: CollisionNode::set_collide_geom
// Access: Published
// Description: Sets the state of the "collide geom" flag for this
// CollisionNode.
//
// This flag is now deprecated, now that GeomNodes have
// their own into_collide_mask, just like CollisionNodes
// do. Instead of using set_collide_geom(), you should
// use the from_collide_mask to control which GeomNodes
// each CollisionNode will intersect with.
//
// In particular, you may be interested in setting
// from_collide_mask to the value returned by
// GeomNode::get_default_collide_mask(), which is the
// default into_collide_mask that all GeomNodes will be
// given (unless they are explicitly given some other
// mask).
////////////////////////////////////////////////////////////////////
BoundingVolume *CollisionNode::
recompute_bound() {
BoundingVolume *result = PandaNode::recompute_bound();
add_net_collide_mask(get_into_collide_mask());
return result;
void CollisionNode::
set_collide_geom(bool flag) {
// Only repeat this warning every five seconds or so--no need to be
// completely spammy.
static double last_warning = -10.0;
double now = ClockObject::get_global_clock()->get_frame_time();
double elapsed = now - last_warning;
if (elapsed > 5.0) {
last_warning = now;
collide_cat.warning()
<< "Using deprecated set_collide_geom(). Replace this with an appropriate call to set_from_collide_mask(), e.g. set_from_collide_mask(GeomNode::get_default_collide_mask()).\n";
}
_collide_geom = flag;
if (_collide_geom) {
_from_collide_mask |= GeomNode::get_default_collide_mask();
} else {
_from_collide_mask &= ~GeomNode::get_default_collide_mask();
}
}
////////////////////////////////////////////////////////////////////
// Function: CollisionNode::get_collide_geom
// Access: Published
// Description: Returns the current state of the collide_geom flag.
// See set_collide_geom().
////////////////////////////////////////////////////////////////////
bool CollisionNode::
get_collide_geom() const {
return _collide_geom;
}
////////////////////////////////////////////////////////////////////
@ -373,8 +442,6 @@ write_datagram(BamWriter *manager, Datagram &dg) {
}
dg.add_uint32(_from_collide_mask.get_word());
dg.add_uint32(_into_collide_mask.get_word());
dg.add_uint8(_flags);
}
////////////////////////////////////////////////////////////////////
@ -438,6 +505,24 @@ fillin(DatagramIterator &scan, BamReader *manager) {
}
_from_collide_mask.set_word(scan.get_uint32());
_into_collide_mask.set_word(scan.get_uint32());
_flags = scan.get_uint8();
if (manager->get_file_minor_ver() < 12) {
// Bam files prior to 4.12 stored the into_collide_mask here.
// (4.12 and later store this in the PandaNode base class
// instead.)
CollideMask into_collide_mask;
into_collide_mask.set_word(scan.get_uint32());
// We also introduced the concept of the CollisionNode-reserved
// bits and the GeomNode-reserved bits with version 4.12. Prior
// to that, CollisionNodes tended to have all bits set. Assume
// they only meant to have the CollisionNode bits set.
into_collide_mask &= get_default_collide_mask();
_from_collide_mask &= get_default_collide_mask();
set_into_collide_mask(into_collide_mask);
// Bam files prior to 4.12 also had a _flags member, which is no
// longer supported.
scan.get_uint8();
}
}

View File

@ -47,6 +47,7 @@ public:
virtual bool preserve_name() const;
virtual void xform(const LMatrix4f &mat);
virtual PandaNode *combine_with(PandaNode *other);
virtual CollideMask get_legal_collide_mask() const;
virtual bool has_cull_callback() const;
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
@ -55,13 +56,13 @@ public:
PUBLISHED:
INLINE void set_collide_mask(CollideMask mask);
INLINE void set_from_collide_mask(CollideMask mask);
void set_from_collide_mask(CollideMask mask);
INLINE void set_into_collide_mask(CollideMask mask);
INLINE CollideMask get_from_collide_mask() const;
INLINE CollideMask get_into_collide_mask() const;
INLINE void set_collide_geom(bool flag);
INLINE bool get_collide_geom() const;
void set_collide_geom(bool flag);
bool get_collide_geom() const;
INLINE void clear_solids();
INLINE int get_num_solids() const;
@ -70,8 +71,9 @@ PUBLISHED:
INLINE void remove_solid(int n);
INLINE int add_solid(CollisionSolid *solid);
INLINE static CollideMask get_default_collide_mask();
protected:
virtual BoundingVolume *recompute_bound();
virtual BoundingVolume *recompute_internal_bound();
private:
@ -81,13 +83,7 @@ private:
// traversal will take place in App only. Perhaps we will revisit
// this later.
CollideMask _from_collide_mask;
CollideMask _into_collide_mask;
enum Flags {
F_collide_geom = 0x0001,
// Presently only 8 bits are written to the bam file.
};
int _flags;
bool _collide_geom;
typedef pvector< PT(CollisionSolid) > Solids;
Solids _solids;

View File

@ -513,8 +513,6 @@ r_traverse(CollisionLevelState &level_state) {
PandaNode *node = level_state.node();
if (node->is_exact_type(CollisionNode::get_class_type())) {
level_state.reached_collision_node();
CollisionNode *cnode;
DCAST_INTO_V(cnode, node);
const BoundingVolume &node_bv = cnode->get_bound();
@ -548,7 +546,7 @@ r_traverse(CollisionLevelState &level_state) {
}
}
} else if (node->is_geom_node() && level_state.has_any_collide_geom()) {
} else if (node->is_geom_node()) {
#ifndef NDEBUG
if (collide_cat.is_spam()) {
collide_cat.spam()
@ -573,15 +571,19 @@ r_traverse(CollisionLevelState &level_state) {
int num_colliders = level_state.get_num_colliders();
for (int c = 0; c < num_colliders; c++) {
if (level_state.has_collider_with_geom(c)) {
if (level_state.has_collider(c)) {
entry._from_node = level_state.get_collider_node(c);
entry._from_node_path = level_state.get_collider_node_path(c);
entry._from = level_state.get_collider(c);
compare_collider_to_geom_node(entry,
level_state.get_parent_bound(c),
level_state.get_local_bound(c),
node_gbv);
if ((entry._from_node->get_from_collide_mask() &
gnode->get_into_collide_mask()) != 0) {
entry._from_node_path = level_state.get_collider_node_path(c);
entry._from = level_state.get_collider(c);
compare_collider_to_geom_node(entry,
level_state.get_parent_bound(c),
level_state.get_local_bound(c),
node_gbv);
}
}
}
}

View File

@ -167,3 +167,14 @@ remove_all_geoms() {
cdata->_geoms.clear();
mark_bound_stale();
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::get_default_collide_mask
// Access: Published, Static
// Description: Returns the default into_collide_mask assigned to new
// GeomNodes.
////////////////////////////////////////////////////////////////////
INLINE CollideMask GeomNode::
get_default_collide_mask() {
return default_geom_node_collide_mask;
}

View File

@ -124,6 +124,8 @@ GeomNode::
GeomNode(const string &name) :
PandaNode(name)
{
// GeomNodes have a certain set of bits on by default.
set_into_collide_mask(get_default_collide_mask());
}
////////////////////////////////////////////////////////////////////
@ -316,6 +318,22 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any,
return next_transform;
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::get_legal_collide_mask
// Access: Published, Virtual
// Description: Returns the subset of CollideMask bits that may be
// set for this particular type of PandaNode. For most
// nodes, this is 0; it doesn't make sense to set a
// CollideMask for most kinds of nodes.
//
// For nodes that can be collided with, such as GeomNode
// and CollisionNode, this returns all bits on.
////////////////////////////////////////////////////////////////////
CollideMask GeomNode::
get_legal_collide_mask() const {
return CollideMask::all_on();
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::add_geoms_from
// Access: Published

View File

@ -53,6 +53,7 @@ public:
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
const TransformState *transform) const;
virtual CollideMask get_legal_collide_mask() const;
PUBLISHED:
INLINE int get_num_geoms() const;
@ -69,6 +70,8 @@ PUBLISHED:
void write_geoms(ostream &out, int indent_level) const;
void write_verbose(ostream &out, int indent_level) const;
INLINE static CollideMask get_default_collide_mask();
public:
virtual void output(ostream &out) const;

View File

@ -1453,6 +1453,42 @@ is_stashed() const {
return !get_stashed_ancestor().is_empty();
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::get_collide_mask
// Access: Published
// Description: Returns the union of all of the into_collide_masks
// for nodes at this level and below. This is the same
// thing as node()->get_net_collide_mask().
//
// If you want to return what the into_collide_mask of
// this node itself is, without regard to its children,
// use node()->get_into_collide_mask().
////////////////////////////////////////////////////////////////////
INLINE CollideMask NodePath::
get_collide_mask() const {
nassertr_always(!is_empty(), CollideMask::all_off());
return node()->get_net_collide_mask();
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_collide_mask
// Access: Published
// Description: Recursively applies the indicated CollideMask to the
// into_collide_masks for all nodes at this level and
// below.
//
// The default is to change all bits, but if
// bits_to_change is not all bits on, then only the bits
// that are set in bits_to_change are modified, allowing
// this call to change only a subset of the bits in the
// subgraph.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
set_collide_mask(CollideMask new_mask, CollideMask bits_to_change) {
nassertv_always(!is_empty());
r_set_collide_mask(node(), ~bits_to_change, new_mask & bits_to_change);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::operator ==
// Access: Published

View File

@ -4944,6 +4944,26 @@ r_force_recompute_bounds(PandaNode *node) {
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::r_set_collide_mask
// Access: Private
// Description: Recursively applies the indicated collide mask to the
// nodes at and below this node.
////////////////////////////////////////////////////////////////////
void NodePath::
r_set_collide_mask(PandaNode *node,
CollideMask and_mask, CollideMask or_mask) {
CollideMask into_collide_mask = node->get_into_collide_mask();
into_collide_mask = (into_collide_mask & and_mask) | or_mask;
node->set_into_collide_mask(into_collide_mask);
PandaNode::Children cr = node->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
r_set_collide_mask(cr.get_child(i), and_mask, or_mask);
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::r_find_texture
// Access: Private

View File

@ -647,6 +647,9 @@ PUBLISHED:
INLINE bool is_stashed() const;
NodePath get_stashed_ancestor() const;
INLINE CollideMask get_collide_mask() const;
INLINE void set_collide_mask(CollideMask new_mask, CollideMask bits_to_change = CollideMask::all_on());
// Comparison methods
INLINE bool operator == (const NodePath &other) const;
INLINE bool operator != (const NodePath &other) const;
@ -708,6 +711,9 @@ private:
void r_force_recompute_bounds(PandaNode *node);
void r_set_collide_mask(PandaNode *node,
CollideMask and_mask, CollideMask or_mask);
typedef pset<Texture *> Textures;
Texture *r_find_texture(PandaNode *node, const RenderState *state,
const GlobPattern &glob) const;

View File

@ -120,6 +120,7 @@ CData() {
_transform = TransformState::make_identity();
_prev_transform = TransformState::make_identity();
_draw_mask = DrawMask::all_on();
_into_collide_mask = CollideMask::all_off();
_net_collide_mask = CollideMask::all_off();
_fixed_internal_bound = false;
}
@ -141,6 +142,7 @@ CData(const PandaNode::CData &copy) :
_prev_transform(copy._prev_transform),
_tag_data(copy._tag_data),
_draw_mask(copy._draw_mask),
_into_collide_mask(copy._into_collide_mask),
_fixed_internal_bound(copy._fixed_internal_bound)
{
_net_collide_mask = CollideMask::all_off();
@ -812,6 +814,45 @@ get_draw_mask() const {
return cdata->_draw_mask;
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::set_into_collide_mask
// Access: Published
// Description: Sets the "into" CollideMask.
//
// This specifies the set of bits that must be shared
// with a CollisionNode's "from" CollideMask in order
// for the CollisionNode to detect a collision with this
// particular node.
//
// The actual CollideMask that will be set is masked by
// the return value from get_legal_collide_mask().
// Thus, the into_collide_mask cannot be set to anything
// other than nonzero except for those types of nodes
// that can be collided into, such as CollisionNodes and
// GeomNodes.
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
set_into_collide_mask(CollideMask mask) {
CDWriter cdata(_cycler);
cdata->_into_collide_mask = mask & get_legal_collide_mask();
// We mark the bound stale when this changes, not because the actual
// bounding volume changes, but rather because we piggyback the
// computing of the _net_collide_mask on the bounding volume.
mark_bound_stale();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::get_into_collide_mask
// Access: Published
// Description: Returns the "into" collide mask for this node.
////////////////////////////////////////////////////////////////////
INLINE CollideMask PandaNode::
get_into_collide_mask() const {
CDReader cdata(_cycler);
return cdata->_into_collide_mask;
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::get_net_collide_mask
// Access: Published
@ -897,19 +938,6 @@ changed_internal_bound() {
BoundedObject::mark_bound_stale();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::add_net_collide_mask
// Access: Protected
// Description: Adds the indicated bits into the net_collide_mask for
// this node. This is normally called only by
// CollisionNode::recompute_bound().
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
add_net_collide_mask(CollideMask mask) {
CDWriter cdata(_cycler);
cdata->_net_collide_mask |= mask;
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::get_children
// Access: Public

View File

@ -77,6 +77,7 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
manager->write_pointer(dg, _transform);
dg.add_uint32(_draw_mask.get_word());
dg.add_uint32(_into_collide_mask.get_word());
write_up_list(_up, manager, dg);
write_down_list(_down, manager, dg);
@ -142,6 +143,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
manager->read_pointer(scan);
_draw_mask.set_word(scan.get_uint32());
if (manager->get_file_minor_ver() >= 12) {
_into_collide_mask.set_word(scan.get_uint32());
}
// Read the parent and child pointers.
fillin_up_list(_up, scan, manager);
@ -383,6 +387,7 @@ PandaNode(const PandaNode &copy) :
cdata->_prev_transform = copy_cdata->_prev_transform;
cdata->_tag_data = copy_cdata->_tag_data;
cdata->_draw_mask = copy_cdata->_draw_mask;
cdata->_into_collide_mask = copy_cdata->_into_collide_mask;
cdata->_fixed_internal_bound = copy_cdata->_fixed_internal_bound;
}
@ -1275,6 +1280,22 @@ list_tags(ostream &out, const string &separator) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::get_legal_collide_mask
// Access: Published, Virtual
// Description: Returns the subset of CollideMask bits that may be
// set for this particular type of PandaNode. For most
// nodes, this is 0; it doesn't make sense to set a
// CollideMask for most kinds of nodes.
//
// For nodes that can be collided with, such as GeomNode
// and CollisionNode, this returns all bits on.
////////////////////////////////////////////////////////////////////
CollideMask PandaNode::
get_legal_collide_mask() const {
return CollideMask::all_off();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::output
// Access: Published, Virtual
@ -1382,7 +1403,7 @@ recompute_bound() {
// Also, recompute the net_collide_mask bits while we do this.
CDWriter cdata(_cycler);
cdata->_net_collide_mask = CollideMask::all_off();
cdata->_net_collide_mask = cdata->_into_collide_mask;
// Now actually compute the bounding volume by putting it around all
// of our child bounding volumes.

View File

@ -164,6 +164,10 @@ PUBLISHED:
INLINE void set_draw_mask(DrawMask mask);
INLINE DrawMask get_draw_mask() const;
INLINE void set_into_collide_mask(CollideMask mask);
INLINE CollideMask get_into_collide_mask() const;
virtual CollideMask get_legal_collide_mask() const;
INLINE CollideMask get_net_collide_mask() const;
virtual void output(ostream &out) const;
@ -320,12 +324,18 @@ private:
// This is the draw_mask of this particular node.
DrawMask _draw_mask;
// This is the union of all into_collide_mask bits for any
// CollisionNodes at and below this level. It's conceptually
// similar to a bounding volume--it represents the bounding volume
// of this node in the space of collision bits--and it needs to be
// updated for the same reasons the bounding volume needs to be
// updated. So we update them together.
// This is the mask that indicates which CollisionNodes may detect
// a collision with this particular node. By default it is zero
// for an ordinary PandaNode, and all bits on for a CollisionNode
// or GeomNode.
CollideMask _into_collide_mask;
// This is the union of all into_collide_mask bits for any nodes
// at and below this level. It's conceptually similar to a
// bounding volume--it represents the bounding volume of this node
// in the space of collision bits--and it needs to be updated for
// the same reasons the bounding volume needs to be updated. So
// we update them together.
CollideMask _net_collide_mask;
bool _fixed_internal_bound;

View File

@ -34,7 +34,7 @@ static const unsigned short _bam_major_ver = 4;
// Bumped to major version 3 on 12/8/00 to change float64's to float32's.
// Bumped to major version 4 on 4/10/02 to store new scene graph.
static const unsigned short _bam_minor_ver = 11;
static const unsigned short _bam_minor_ver = 12;
// Bumped to minor version 1 on 4/10/03 to add CullFaceAttrib::reverse.
// Bumped to minor version 1 on 4/10/03 to add CullFaceAttrib::reverse.
// Bumped to minor version 2 on 4/12/03 to add num_components to texture.
@ -47,6 +47,7 @@ static const unsigned short _bam_minor_ver = 11;
// Bumped to minor version 9 on 12/02/03 to change CollisionPolygon internals.
// Bumped to minor version 10 on 04/23/04 to make ComputedVertices use uint32's.
// Bumped to minor version 11 on 07/26/04 to add multitexture pointers.
// Bumped to minor version 12 on 09/22/04 to add PandaNode::into_collide_mask.
#endif

View File

@ -34,5 +34,27 @@
typedef BitMask32 CollideMask;
// We need some conventions for initial bits for GeomNodes and
// CollideNodes. These are primarily advisory, since the application
// programmer is free to define each bit as he or she chooses, but
// they also control the initial default values that are assigned to
// new nodes.
// By established convention, the lower 20 bits are reserved for
// CollisionNodes. Each CollisionNode has all these bits set on by
// default (and no others). You can (and probably should) change this
// on a per-node basis to specialize CollisionNodes for different
// purposes.
static const CollideMask default_collision_node_collide_mask = CollideMask::lower_on(20);
// The next bit is reserved for generic GeomNodes. Each GeomNode has
// this bit on by default (and no others). You can, of course, set
// any mask you want on a particular GeomNode; this is just the
// default bit if you choose not to do anything.
static const CollideMask default_geom_node_collide_mask = CollideMask::bit(20);
// The remaining 11 bits are presently unassigned. No nodes will have
// these bits on by default.
#endif