mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
all nodes now have a CollideMask
This commit is contained in:
parent
47a6d4716f
commit
0369f07074
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ©) :
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 ©) :
|
||||
_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
|
||||
|
@ -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 ©) :
|
||||
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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user