first steps toward a NodePath-based interface

This commit is contained in:
David Rose 2003-10-23 15:35:26 +00:00
parent 7249626033
commit e07d4b7847
14 changed files with 218 additions and 201 deletions

View File

@ -100,6 +100,20 @@ get_into_node() const {
return _into_node; return _into_node;
} }
////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_from_node_path
// Access: Published
// Description: Returns the NodePath that represents the
// CollisionNode that contains the CollisionSolid that
// triggered this collision. This will be a NodePath
// that has been added to a CollisionTraverser via
// add_collider().
////////////////////////////////////////////////////////////////////
INLINE const NodePath &CollisionEntry::
get_from_node_path() const {
return _from_node_path;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionEntry::get_into_node_path // Function: CollisionEntry::get_into_node_path
// Access: Published // Access: Published

View File

@ -31,6 +31,7 @@ CollisionEntry(const CollisionEntry &copy) :
_into(copy._into), _into(copy._into),
_from_node(copy._from_node), _from_node(copy._from_node),
_into_node(copy._into_node), _into_node(copy._into_node),
_from_node_path(copy._from_node_path),
_into_node_path(copy._into_node_path), _into_node_path(copy._into_node_path),
_from_space(copy._from_space), _from_space(copy._from_space),
_into_space(copy._into_space), _into_space(copy._into_space),
@ -55,6 +56,7 @@ operator = (const CollisionEntry &copy) {
_into = copy._into; _into = copy._into;
_from_node = copy._from_node; _from_node = copy._from_node;
_into_node = copy._into_node; _into_node = copy._into_node;
_from_node_path = copy._from_node_path;
_into_node_path = copy._into_node_path; _into_node_path = copy._into_node_path;
_from_space = copy._from_space; _from_space = copy._from_space;
_into_space = copy._into_space; _into_space = copy._into_space;

View File

@ -59,6 +59,7 @@ PUBLISHED:
INLINE CollisionNode *get_from_node() const; INLINE CollisionNode *get_from_node() const;
INLINE PandaNode *get_into_node() const; INLINE PandaNode *get_into_node() const;
INLINE const NodePath &get_from_node_path() const;
INLINE const NodePath &get_into_node_path() const; INLINE const NodePath &get_into_node_path() const;
INLINE const TransformState *get_from_space() const; INLINE const TransformState *get_from_space() const;
@ -106,6 +107,7 @@ private:
PT(CollisionNode) _from_node; PT(CollisionNode) _from_node;
PT(PandaNode) _into_node; PT(PandaNode) _into_node;
NodePath _from_node_path;
NodePath _into_node_path; NodePath _into_node_path;
CPT(TransformState) _from_space; CPT(TransformState) _from_space;
CPT(TransformState) _into_space; CPT(TransformState) _into_space;

View File

@ -62,25 +62,24 @@ handle_entries() {
FromEntries::const_iterator fi; FromEntries::const_iterator fi;
for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) { for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
CollisionNode *from_node = (*fi).first; const NodePath &from_node_path = (*fi).first;
nassertr(from_node != (CollisionNode *)NULL, false);
const Entries &entries = (*fi).second; const Entries &entries = (*fi).second;
Colliders::iterator ci; Colliders::iterator ci;
ci = _colliders.find(from_node); ci = _colliders.find(from_node_path);
if (ci == _colliders.end()) { if (ci == _colliders.end()) {
// Hmm, someone added a CollisionNode to a traverser and gave // Hmm, someone added a CollisionNode to a traverser and gave
// it this CollisionHandler pointer--but they didn't tell us // it this CollisionHandler pointer--but they didn't tell us
// about the node. // about the node.
collide_cat.error() collide_cat.error()
<< get_type() << " doesn't know about " << get_type() << " doesn't know about "
<< *from_node << ", disabling.\n"; << from_node_path << ", disabling.\n";
okflag = false; okflag = false;
} else { } else {
ColliderDef &def = (*ci).second; ColliderDef &def = (*ci).second;
if (!def.is_valid()) { if (!def.is_valid()) {
collide_cat.error() collide_cat.error()
<< "Removing invalid collider " << *from_node << " from " << "Removing invalid collider " << from_node_path << " from "
<< get_type() << "\n"; << get_type() << "\n";
_colliders.erase(ci); _colliders.erase(ci);
} else { } else {
@ -92,7 +91,7 @@ handle_entries() {
for (ei = entries.begin(); ei != entries.end(); ++ei) { for (ei = entries.begin(); ei != entries.end(); ++ei) {
CollisionEntry *entry = (*ei); CollisionEntry *entry = (*ei);
nassertr(entry != (CollisionEntry *)NULL, false); nassertr(entry != (CollisionEntry *)NULL, false);
nassertr(from_node == entry->get_from_node(), false); nassertr(from_node_path == entry->get_from_node_path(), false);
if (entry->has_from_intersection_point()) { if (entry->has_from_intersection_point()) {
LPoint3f point = entry->get_from_intersection_point(); LPoint3f point = entry->get_from_intersection_point();

View File

@ -39,6 +39,19 @@ set_node(PandaNode *node) {
_drive_interface.clear(); _drive_interface.clear();
} }
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::ColliderDef::set_target
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CollisionHandlerPhysical::ColliderDef::
set_target(const NodePath &target) {
_target = target;
if (!target.is_empty()) {
_node = target.node();
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::ColliderDef::is_valid // Function: CollisionHandlerPhysical::ColliderDef::is_valid
// Access: Public // Access: Public

View File

@ -126,40 +126,29 @@ end_group() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_collider_drive // Function: CollisionHandlerPhysical::add_collider
// Access: Public // Access: Published
// Description: Adds a new collider to the list with a DriveInterface // Description: Adds a new collider to the list with a NodePath
// pointer that needs to be told about the collider's // that will be updated with the collider's new
// new position, or updates the existing collider with a // position, or updates the existing collider with a new
// new DriveInterface pointer. // NodePath object.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical:: void CollisionHandlerPhysical::
add_collider_drive(CollisionNode *node, DriveInterface *drive_interface) { add_collider(const NodePath &collider, const NodePath &target) {
_colliders[node].set_drive_interface(drive_interface); nassertv(!collider.is_empty() && collider.node()->is_of_type(CollisionNode::get_class_type()));
} nassertv(!target.is_empty());
_colliders[collider].set_target(target);
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_collider_node
// Access: Public
// Description: Adds a new collider to the list with a PandaNode
// pointer that will be updated with the collider's
// new position, or updates the existing collider with a
// new PandaNode pointer.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
add_collider_node(CollisionNode *node, PandaNode *target) {
_colliders[node].set_node(target);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::remove_collider // Function: CollisionHandlerPhysical::remove_collider
// Access: Public // Access: Published
// Description: Removes the collider from the list of colliders that // Description: Removes the collider from the list of colliders that
// this handler knows about. // this handler knows about.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CollisionHandlerPhysical:: bool CollisionHandlerPhysical::
remove_collider(CollisionNode *node) { remove_collider(const NodePath &collider) {
Colliders::iterator ci = _colliders.find(node); Colliders::iterator ci = _colliders.find(collider);
if (ci == _colliders.end()) { if (ci == _colliders.end()) {
return false; return false;
} }
@ -169,19 +158,19 @@ remove_collider(CollisionNode *node) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::has_collider // Function: CollisionHandlerPhysical::has_collider
// Access: Public // Access: Published
// Description: Returns true if the handler knows about the indicated // Description: Returns true if the handler knows about the indicated
// collider, false otherwise. // collider, false otherwise.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CollisionHandlerPhysical:: bool CollisionHandlerPhysical::
has_collider(CollisionNode *node) const { has_collider(const NodePath &target) const {
Colliders::const_iterator ci = _colliders.find(node); Colliders::const_iterator ci = _colliders.find(target);
return (ci != _colliders.end()); return (ci != _colliders.end());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::clear_colliders // Function: CollisionHandlerPhysical::clear_colliders
// Access: Public // Access: Published
// Description: Completely empties the list of colliders this handler // Description: Completely empties the list of colliders this handler
// knows about. // knows about.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -190,4 +179,26 @@ clear_colliders() {
_colliders.clear(); _colliders.clear();
} }
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_collider_node
// Access: Published
// Description: This method is deprecated and will shortly be removed
// in favor of the newer NodePath-based method, above.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
add_collider_node(CollisionNode *node, PandaNode *target) {
add_collider(NodePath(node), NodePath(target));
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_collider_drive
// Access: Published
// Description: Adds a new collider to the list with a DriveInterface
// pointer that needs to be told about the collider's
// new position, or updates the existing collider with a
// new DriveInterface pointer.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
add_collider_drive(CollisionNode *node, DriveInterface *drive_interface) {
_colliders[NodePath(node)].set_drive_interface(drive_interface);
}

View File

@ -45,23 +45,28 @@ public:
virtual bool end_group(); virtual bool end_group();
PUBLISHED: PUBLISHED:
void add_collider_node(CollisionNode *node, PandaNode *target); void add_collider(const NodePath &collider, const NodePath &target);
bool remove_collider(CollisionNode *node); bool remove_collider(const NodePath &collider);
bool has_collider(CollisionNode *node) const; bool has_collider(const NodePath &collider) const;
void clear_colliders(); void clear_colliders();
// The following method is deprecated and exists only as a temporary
// transition to the above new NodePath-based methods.
void add_collider_node(CollisionNode *node, PandaNode *target);
// add_collider_drive() is becoming obsolete. If you need it, let us know. // add_collider_drive() is becoming obsolete. If you need it, let us know.
void add_collider_drive(CollisionNode *node, DriveInterface *drive_interface); void add_collider_drive(CollisionNode *node, DriveInterface *drive_interface);
protected: protected:
typedef pvector< PT(CollisionEntry) > Entries; typedef pvector< PT(CollisionEntry) > Entries;
typedef pmap<PT(CollisionNode), Entries> FromEntries; typedef pmap<NodePath, Entries> FromEntries;
FromEntries _from_entries; FromEntries _from_entries;
class ColliderDef { class ColliderDef {
public: public:
INLINE void set_drive_interface(DriveInterface *drive_interface); INLINE void set_drive_interface(DriveInterface *drive_interface);
INLINE void set_node(PandaNode *node); INLINE void set_node(PandaNode *node);
INLINE void set_target(const NodePath &target);
INLINE bool is_valid() const; INLINE bool is_valid() const;
void get_mat(LMatrix4f &mat) const; void get_mat(LMatrix4f &mat) const;
@ -69,9 +74,10 @@ protected:
PT(DriveInterface) _drive_interface; PT(DriveInterface) _drive_interface;
PT(PandaNode) _node; PT(PandaNode) _node;
NodePath _target;
}; };
typedef pmap<PT(CollisionNode), ColliderDef> Colliders; typedef pmap<NodePath, ColliderDef> Colliders;
Colliders _colliders; Colliders _colliders;
virtual bool handle_entries()=0; virtual bool handle_entries()=0;

View File

@ -76,25 +76,24 @@ handle_entries() {
FromEntries::const_iterator fi; FromEntries::const_iterator fi;
for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) { for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) {
CollisionNode *from_node = (*fi).first; const NodePath &from_node_path = (*fi).first;
nassertr(from_node != (CollisionNode *)NULL, false);
const Entries &entries = (*fi).second; const Entries &entries = (*fi).second;
Colliders::iterator ci; Colliders::iterator ci;
ci = _colliders.find(from_node); ci = _colliders.find(from_node_path);
if (ci == _colliders.end()) { if (ci == _colliders.end()) {
// Hmm, someone added a CollisionNode to a traverser and gave // Hmm, someone added a CollisionNode to a traverser and gave
// it this CollisionHandler pointer--but they didn't tell us // it this CollisionHandler pointer--but they didn't tell us
// about the node. // about the node.
collide_cat.error() collide_cat.error()
<< "CollisionHandlerPusher doesn't know about " << "CollisionHandlerPusher doesn't know about "
<< *from_node << ", disabling.\n"; << from_node_path << ", disabling.\n";
okflag = false; okflag = false;
} else { } else {
ColliderDef &def = (*ci).second; ColliderDef &def = (*ci).second;
if (!def.is_valid()) { if (!def.is_valid()) {
collide_cat.error() collide_cat.error()
<< "Removing invalid collider " << *from_node << " from " << "Removing invalid collider " << from_node_path << " from "
<< get_type() << "\n"; << get_type() << "\n";
_colliders.erase(ci); _colliders.erase(ci);
} else { } else {
@ -113,14 +112,14 @@ handle_entries() {
for (ei = entries.begin(); ei != entries.end(); ++ei) { for (ei = entries.begin(); ei != entries.end(); ++ei) {
CollisionEntry *entry = (*ei); CollisionEntry *entry = (*ei);
nassertr(entry != (CollisionEntry *)NULL, false); nassertr(entry != (CollisionEntry *)NULL, false);
nassertr(from_node == entry->get_from_node(), false); nassertr(from_node_path == entry->get_from_node_path(), false);
if (!entry->has_from_surface_normal() || if (!entry->has_from_surface_normal() ||
!entry->has_from_depth()) { !entry->has_from_depth()) {
#ifndef NDEBUG #ifndef NDEBUG
if (collide_cat.is_debug()) { if (collide_cat.is_debug()) {
collide_cat.debug() collide_cat.debug()
<< "Cannot shove on " << *from_node << " for collision into " << "Cannot shove on " << from_node_path << " for collision into "
<< *entry->get_into_node() << "; no normal/depth information.\n"; << *entry->get_into_node() << "; no normal/depth information.\n";
} }
#endif #endif
@ -145,7 +144,7 @@ handle_entries() {
#ifndef NDEBUG #ifndef NDEBUG
if (collide_cat.is_debug()) { if (collide_cat.is_debug()) {
collide_cat.debug() collide_cat.debug()
<< "Shove on " << *from_node << " from " << "Shove on " << from_node_path << " from "
<< *entry->get_into_node() << ": " << sd._vector << *entry->get_into_node() << ": " << sd._vector
<< " times " << sd._length << "\n"; << " times " << sd._length << "\n";
} }
@ -244,7 +243,7 @@ handle_entries() {
#ifndef NDEBUG #ifndef NDEBUG
if (collide_cat.is_debug()) { if (collide_cat.is_debug()) {
collide_cat.debug() collide_cat.debug()
<< "Net shove on " << *from_node << " is: " << "Net shove on " << from_node_path << " is: "
<< net_shove << "\n"; << net_shove << "\n";
} }
#endif #endif

View File

@ -150,12 +150,12 @@ get_collider(int n) const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_node // Function: CollisionLevelState::get_collider_node
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE CollisionNode *CollisionLevelState:: INLINE CollisionNode *CollisionLevelState::
get_node(int n) const { get_collider_node(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), NULL); nassertr(n >= 0 && n < (int)_colliders.size(), NULL);
nassertr(has_collider(n), NULL); nassertr(has_collider(n), NULL);
@ -163,55 +163,16 @@ get_node(int n) const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_space // Function: CollisionLevelState::get_collider_node_path
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE const TransformState *CollisionLevelState:: INLINE NodePath CollisionLevelState::
get_space(int n) const { get_collider_node_path(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity()); nassertr(n >= 0 && n < (int)_colliders.size(), NodePath::fail());
nassertr(has_collider(n), TransformState::make_identity()); nassertr(has_collider(n), NodePath::fail());
return _colliders[n]._space; return _colliders[n]._node_path;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_inv_space
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const TransformState *CollisionLevelState::
get_inv_space(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity());
nassertr(has_collider(n), TransformState::make_identity());
return _colliders[n]._inv_space;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_prev_space
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const TransformState *CollisionLevelState::
get_prev_space(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity());
nassertr(has_collider(n), TransformState::make_identity());
return _colliders[n]._prev_space;
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_delta
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LVector3f &CollisionLevelState::
get_delta(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), LVector3f::zero());
nassertr(has_collider(n), LVector3f::zero());
return _colliders[n]._delta;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -64,6 +64,11 @@ prepare_collider(const ColliderDef &def) {
GeometricBoundingVolume *gbv; GeometricBoundingVolume *gbv;
DCAST_INTO_V(gbv, bv.make_copy()); DCAST_INTO_V(gbv, bv.make_copy());
// TODO: we need to make this logic work in the new relative
// world. The bounding volume should be extended by the object's
// motion relative to each object it is considering a collision
// with. That makes things complicated!
/*
if (def._delta != LVector3f::zero()) { if (def._delta != LVector3f::zero()) {
// If the node has a delta, we have to include the starting // If the node has a delta, we have to include the starting
// point in the volume as well. // point in the volume as well.
@ -76,8 +81,9 @@ prepare_collider(const ColliderDef &def) {
// same results, and is much easier to compute. // same results, and is much easier to compute.
gbv->extend_by(LPoint3f(-def._delta)); gbv->extend_by(LPoint3f(-def._delta));
} }
*/
gbv->xform(def._space->get_mat()); gbv->xform(def._node_path.get_mat(NodePath()));
_local_bounds.push_back(gbv); _local_bounds.push_back(gbv);
} }
@ -119,14 +125,14 @@ any_in_bounds() {
int num_colliders = get_num_colliders(); int num_colliders = get_num_colliders();
for (int c = 0; c < num_colliders; c++) { for (int c = 0; c < num_colliders; c++) {
if (has_collider(c)) { if (has_collider(c)) {
CollisionNode *collider = get_node(c); CollisionNode *cnode = get_collider_node(c);
bool is_in = false; bool is_in = false;
// Don't even bother testing the bounding volume if there are // Don't even bother testing the bounding volume if there are
// no collide bits in common between our collider and this // no collide bits in common between our collider and this
// node. // node.
CollideMask from_mask = collider->get_from_collide_mask(); CollideMask from_mask = cnode->get_from_collide_mask();
if (collider->get_collide_geom() || if (cnode->get_collide_geom() ||
(from_mask & node()->get_net_collide_mask()) != 0) { (from_mask & node()->get_net_collide_mask()) != 0) {
// There are bits in common, so go ahead and try the // There are bits in common, so go ahead and try the
// bounding volume. // bounding volume.

View File

@ -26,7 +26,6 @@
#include "geometricBoundingVolume.h" #include "geometricBoundingVolume.h"
#include "nodePath.h" #include "nodePath.h"
#include "workingNodePath.h" #include "workingNodePath.h"
#include "transformState.h"
#include "pointerTo.h" #include "pointerTo.h"
#include "plist.h" #include "plist.h"
@ -45,10 +44,7 @@ public:
public: public:
CollisionSolid *_collider; CollisionSolid *_collider;
CollisionNode *_node; CollisionNode *_node;
CPT(TransformState) _space; NodePath _node_path;
CPT(TransformState) _inv_space;
CPT(TransformState) _prev_space;
LVector3f _delta;
}; };
INLINE CollisionLevelState(const NodePath &node_path); INLINE CollisionLevelState(const NodePath &node_path);
@ -74,11 +70,8 @@ public:
INLINE void reached_collision_node(); INLINE void reached_collision_node();
INLINE CollisionSolid *get_collider(int n) const; INLINE CollisionSolid *get_collider(int n) const;
INLINE CollisionNode *get_node(int n) const; INLINE CollisionNode *get_collider_node(int n) const;
INLINE const TransformState *get_space(int n) const; INLINE NodePath get_collider_node_path(int n) const;
INLINE const TransformState *get_inv_space(int n) const;
INLINE const TransformState *get_prev_space(int n) const;
INLINE const LVector3f &get_delta(int n) const;
INLINE const GeometricBoundingVolume *get_local_bound(int n) const; INLINE const GeometricBoundingVolume *get_local_bound(int n) const;
INLINE const GeometricBoundingVolume *get_parent_bound(int n) const; INLINE const GeometricBoundingVolume *get_parent_bound(int n) const;

View File

@ -19,7 +19,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::set_respect_prev_transform // Function: CollisionTraverser::set_respect_prev_transform
// Access: Public // Access: Published
// Description: Sets the flag that indicates whether the // Description: Sets the flag that indicates whether the
// prev_transform stored on a node (as updated via // prev_transform stored on a node (as updated via
// set_fluid_pos(), etc.) is respected to calculate // set_fluid_pos(), etc.) is respected to calculate
@ -36,7 +36,7 @@ set_respect_prev_transform(bool flag) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_respect_prev_transform // Function: CollisionTraverser::get_respect_prev_transform
// Access: Public // Access: Published
// Description: Returns the flag that indicates whether the // Description: Returns the flag that indicates whether the
// prev_transform stored on a node is respected to // prev_transform stored on a node is respected to
// calculate collisions. See // calculate collisions. See
@ -51,7 +51,7 @@ get_respect_prev_transform() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::has_recorder // Function: CollisionTraverser::has_recorder
// Access: Public // Access: Published
// Description: Returns true if the CollisionTraverser has a // Description: Returns true if the CollisionTraverser has a
// CollisionRecorder object currently assigned, false // CollisionRecorder object currently assigned, false
// otherwise. // otherwise.
@ -63,7 +63,7 @@ has_recorder() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_recorder // Function: CollisionTraverser::get_recorder
// Access: Public // Access: Published
// Description: Returns the CollisionRecorder currently assigned, or // Description: Returns the CollisionRecorder currently assigned, or
// NULL if no recorder is assigned. // NULL if no recorder is assigned.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -74,7 +74,7 @@ get_recorder() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::clear_recorder // Function: CollisionTraverser::clear_recorder
// Access: Public // Access: Published
// Description: Removes the CollisionRecorder from the traverser and // Description: Removes the CollisionRecorder from the traverser and
// restores normal low-overhead operation. // restores normal low-overhead operation.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -36,7 +36,7 @@ PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::Constructor // Function: CollisionTraverser::Constructor
// Access: Public // Access: Published
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CollisionTraverser:: CollisionTraverser::
@ -49,7 +49,7 @@ CollisionTraverser() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::Destructor // Function: CollisionTraverser::Destructor
// Access: Public // Access: Published
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CollisionTraverser:: CollisionTraverser::
@ -61,7 +61,7 @@ CollisionTraverser::
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::add_collider // Function: CollisionTraverser::add_collider
// Access: Public // Access: Published
// Description: Adds a new CollisionNode, representing an object that // Description: Adds a new CollisionNode, representing an object that
// will be tested for collisions into other objects, // will be tested for collisions into other objects,
// along with the handler that will serve each detected // along with the handler that will serve each detected
@ -74,12 +74,12 @@ CollisionTraverser::
// again on the same node. // again on the same node.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionTraverser:: void CollisionTraverser::
add_collider(CollisionNode *node, CollisionHandler *handler) { add_collider(const NodePath &collider, CollisionHandler *handler) {
nassertv(_ordered_colliders.size() == _colliders.size()); nassertv(_ordered_colliders.size() == _colliders.size());
nassertv(node != (CollisionNode *)NULL); nassertv(!collider.is_empty() && collider.node()->is_of_type(CollisionNode::get_class_type()));
nassertv(handler != (CollisionHandler *)NULL); nassertv(handler != (CollisionHandler *)NULL);
Colliders::iterator ci = _colliders.find(node); Colliders::iterator ci = _colliders.find(collider);
if (ci != _colliders.end()) { if (ci != _colliders.end()) {
// We already knew about this collider. // We already knew about this collider.
if ((*ci).second != handler) { if ((*ci).second != handler) {
@ -106,8 +106,8 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
} else { } else {
// We hadn't already known about this collider. // We hadn't already known about this collider.
_colliders.insert(Colliders::value_type(node, handler)); _colliders.insert(Colliders::value_type(collider, handler));
_ordered_colliders.push_back(node); _ordered_colliders.push_back(collider);
Handlers::iterator hi = _handlers.find(handler); Handlers::iterator hi = _handlers.find(handler);
if (hi == _handlers.end()) { if (hi == _handlers.end()) {
@ -122,7 +122,7 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::remove_collider // Function: CollisionTraverser::remove_collider
// Access: Public // Access: Published
// Description: Removes the collider (and its associated handler) // Description: Removes the collider (and its associated handler)
// from the set of CollisionNodes that will be tested // from the set of CollisionNodes that will be tested
// each frame for collisions into other objects. // each frame for collisions into other objects.
@ -130,10 +130,10 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
// false if it wasn't present to begin with. // false if it wasn't present to begin with.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CollisionTraverser:: bool CollisionTraverser::
remove_collider(CollisionNode *node) { remove_collider(const NodePath &collider) {
nassertr(_ordered_colliders.size() == _colliders.size(), false); nassertr(_ordered_colliders.size() == _colliders.size(), false);
Colliders::iterator ci = _colliders.find(node); Colliders::iterator ci = _colliders.find(collider);
if (ci == _colliders.end()) { if (ci == _colliders.end()) {
// We didn't know about this node. // We didn't know about this node.
return false; return false;
@ -153,7 +153,7 @@ remove_collider(CollisionNode *node) {
_colliders.erase(ci); _colliders.erase(ci);
OrderedColliders::iterator oci = OrderedColliders::iterator oci =
find(_ordered_colliders.begin(), _ordered_colliders.end(), node); find(_ordered_colliders.begin(), _ordered_colliders.end(), collider);
nassertr(oci != _ordered_colliders.end(), false); nassertr(oci != _ordered_colliders.end(), false);
_ordered_colliders.erase(oci); _ordered_colliders.erase(oci);
@ -163,20 +163,20 @@ remove_collider(CollisionNode *node) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::has_collider // Function: CollisionTraverser::has_collider
// Access: Public // Access: Published
// Description: Returns true if the indicated node is current in the // Description: Returns true if the indicated node is current in the
// set of nodes that will be tested each frame for // set of nodes that will be tested each frame for
// collisions into other objects. // collisions into other objects.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CollisionTraverser:: bool CollisionTraverser::
has_collider(CollisionNode *node) const { has_collider(const NodePath &collider) const {
Colliders::const_iterator ci = _colliders.find(node); Colliders::const_iterator ci = _colliders.find(collider);
return (ci != _colliders.end()); return (ci != _colliders.end());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_num_colliders // Function: CollisionTraverser::get_num_colliders
// Access: Public // Access: Published
// Description: Returns the number of CollisionNodes that have been // Description: Returns the number of CollisionNodes that have been
// added to the traverser via add_collider(). // added to the traverser via add_collider().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -188,11 +188,11 @@ get_num_colliders() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_collider // Function: CollisionTraverser::get_collider
// Access: Public // Access: Published
// Description: Returns the nth CollisionNode that has been // Description: Returns the nth CollisionNode that has been
// added to the traverser via add_collider(). // added to the traverser via add_collider().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CollisionNode *CollisionTraverser:: NodePath CollisionTraverser::
get_collider(int n) const { get_collider(int n) const {
nassertr(_ordered_colliders.size() == _colliders.size(), NULL); nassertr(_ordered_colliders.size() == _colliders.size(), NULL);
nassertr(n >= 0 && n < (int)_ordered_colliders.size(), NULL); nassertr(n >= 0 && n < (int)_ordered_colliders.size(), NULL);
@ -201,14 +201,14 @@ get_collider(int n) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_handler // Function: CollisionTraverser::get_handler
// Access: Public // Access: Published
// Description: Returns the handler that is currently assigned to // Description: Returns the handler that is currently assigned to
// serve the indicated collision node, or NULL if the // serve the indicated collision node, or NULL if the
// node is not on the traverser's set of active nodes. // node is not on the traverser's set of active nodes.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CollisionHandler *CollisionTraverser:: CollisionHandler *CollisionTraverser::
get_handler(CollisionNode *node) const { get_handler(const NodePath &collider) const {
Colliders::const_iterator ci = _colliders.find(node); Colliders::const_iterator ci = _colliders.find(collider);
if (ci != _colliders.end()) { if (ci != _colliders.end()) {
return (*ci).second; return (*ci).second;
}; };
@ -217,7 +217,7 @@ get_handler(CollisionNode *node) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::clear_colliders // Function: CollisionTraverser::clear_colliders
// Access: Public // Access: Published
// Description: Completely empties the set of collision nodes and // Description: Completely empties the set of collision nodes and
// their associated handlers. // their associated handlers.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -227,10 +227,31 @@ clear_colliders() {
_ordered_colliders.clear(); _ordered_colliders.clear();
} }
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::add_collider
// Access: Published
// Description: This method is deprecated and will shortly be removed
// in favor of the newer NodePath-based method, above.
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
add_collider(CollisionNode *node, CollisionHandler *handler) {
add_collider(NodePath(node), handler);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::remove_collider
// Access: Published
// Description: This method is deprecated and will shortly be removed
// in favor of the newer NodePath-based method, above.
////////////////////////////////////////////////////////////////////
bool CollisionTraverser::
remove_collider(CollisionNode *node) {
return remove_collider(NodePath(node));
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::traverse // Function: CollisionTraverser::traverse
// Access: Public // Access: Published
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionTraverser:: void CollisionTraverser::
@ -272,7 +293,7 @@ traverse(const NodePath &root) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::reset_prev_transform // Function: CollisionTraverser::reset_prev_transform
// Access: Public // Access: Published
// Description: Once the collision traversal has finished, resets all // Description: Once the collision traversal has finished, resets all
// of the velocity deltas in the scene graph by setting // of the velocity deltas in the scene graph by setting
// the "previous" transform to the current transform. // the "previous" transform to the current transform.
@ -287,7 +308,7 @@ reset_prev_transform(const NodePath &root) {
#ifdef DO_COLLISION_RECORDING #ifdef DO_COLLISION_RECORDING
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::set_recorder // Function: CollisionTraverser::set_recorder
// Access: Public // Access: Published
// Description: Uses the indicated CollisionRecorder object to start // Description: Uses the indicated CollisionRecorder object to start
// recording the intersection tests made by each // recording the intersection tests made by each
// subsequent call to traverse() on this object. A // subsequent call to traverse() on this object. A
@ -333,7 +354,7 @@ set_recorder(CollisionRecorder *recorder) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::output // Function: CollisionTraverser::output
// Access: Public // Access: Published
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionTraverser:: void CollisionTraverser::
@ -344,7 +365,7 @@ output(ostream &out) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::write // Function: CollisionTraverser::write
// Access: Public // Access: Published
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CollisionTraverser:: void CollisionTraverser::
@ -354,18 +375,21 @@ write(ostream &out, int indent_level) const {
<< " colliders and " << _handlers.size() << " handlers:\n"; << " colliders and " << _handlers.size() << " handlers:\n";
Colliders::const_iterator ci; Colliders::const_iterator ci;
for (ci = _colliders.begin(); ci != _colliders.end(); ++ci) { for (ci = _colliders.begin(); ci != _colliders.end(); ++ci) {
CollisionNode *cnode = (*ci).first; NodePath cnode_path = (*ci).first;
CollisionHandler *handler = (*ci).second; CollisionHandler *handler = (*ci).second;
nassertv(cnode != (CollisionNode *)NULL);
nassertv(handler != (CollisionHandler *)NULL); nassertv(handler != (CollisionHandler *)NULL);
indent(out, indent_level + 2) indent(out, indent_level + 2)
<< *cnode << " handled by " << handler->get_type() << "\n"; << cnode_path << " handled by " << handler->get_type() << "\n";
if (!cnode_path.is_empty() && cnode_path.node()->is_of_type(CollisionNode::get_class_type())) {
CollisionNode *cnode = DCAST(CollisionNode, cnode_path.node());
int num_solids = cnode->get_num_solids(); int num_solids = cnode->get_num_solids();
for (int i = 0; i < num_solids; i++) { for (int i = 0; i < num_solids; i++) {
cnode->get_solid(i)->write(out, indent_level + 4); cnode->get_solid(i)->write(out, indent_level + 4);
} }
} }
}
} }
@ -381,32 +405,15 @@ prepare_colliders(CollisionLevelState &level_state) {
int i = 0; int i = 0;
while (i < (int)_ordered_colliders.size()) { while (i < (int)_ordered_colliders.size()) {
CollisionNode *cnode = _ordered_colliders[i]; NodePath cnode_path = _ordered_colliders[i];
if (!cnode_path.is_empty() &&
cnode_path.node()->is_of_type(CollisionNode::get_class_type())) {
CollisionNode *cnode = DCAST(CollisionNode, cnode_path.node());
CollisionLevelState::ColliderDef def; CollisionLevelState::ColliderDef def;
def._node = cnode; def._node = cnode;
NodePath cnode_path(cnode); def._node_path = cnode_path;
def._space = cnode_path.get_net_transform();
def._inv_space = def._space->invert_compose(TransformState::make_identity());
def._prev_space = cnode_path.get_net_prev_transform();
if (_respect_prev_transform) {
def._delta = cnode_path.get_pos_delta();
} else {
def._delta = LVector3f::zero();
}
#ifndef NDEBUG
if (def._space->is_invalid()) {
collide_cat.error()
<< "Collider " << *cnode
<< " has become invalid. Dropping from traverser.\n";
// This is safe to do while traversing the list of colliders,
// because we do not increment i in this case.
remove_collider(cnode);
} else
#endif
{
int num_solids = cnode->get_num_solids(); int num_solids = cnode->get_num_solids();
for (int s = 0; s < num_solids; s++) { for (int s = 0; s < num_solids; s++) {
CollisionSolid *collider = cnode->get_solid(s); CollisionSolid *collider = cnode->get_solid(s);
@ -450,21 +457,20 @@ r_traverse(CollisionLevelState &level_state) {
int num_colliders = level_state.get_num_colliders(); int num_colliders = level_state.get_num_colliders();
for (int c = 0; c < num_colliders; c++) { for (int c = 0; c < num_colliders; c++) {
if (level_state.has_collider(c)) { if (level_state.has_collider(c)) {
entry._from_node = level_state.get_node(c); entry._from_node = level_state.get_collider_node(c);
if ((entry._from_node->get_from_collide_mask() & if ((entry._from_node->get_from_collide_mask() &
cnode->get_into_collide_mask()) != 0) { cnode->get_into_collide_mask()) != 0) {
entry._from_node_path = level_state.get_collider_node_path(c);
entry._from = level_state.get_collider(c); entry._from = level_state.get_collider(c);
entry._from_space = level_state.get_space(c); entry._from_space = entry._from_node_path.get_net_transform();
LVector3f from_delta = level_state.get_delta(c); entry._wrt_space = entry._from_node_path.get_transform(entry._into_node_path);
entry._inv_wrt_space = entry._into_node_path.get_transform(entry._from_node_path);
entry._wrt_space = entry._into_space->invert_compose(entry._from_space);
entry._inv_wrt_space = entry._from_space->invert_compose(entry._into_space);
if (_respect_prev_transform) { if (_respect_prev_transform) {
CPT(TransformState) into_prev_space = entry._into_node_path.get_net_prev_transform(); entry._wrt_prev_space = entry._from_node_path.get_prev_transform(entry._into_node_path);
CPT(TransformState) from_prev_space = level_state.get_prev_space(c);
entry._wrt_prev_space = into_prev_space->invert_compose(from_prev_space);
} else { } else {
entry._wrt_prev_space = entry._wrt_space; entry._wrt_prev_space = entry._wrt_space;
} }
@ -501,13 +507,13 @@ r_traverse(CollisionLevelState &level_state) {
int num_colliders = level_state.get_num_colliders(); int num_colliders = level_state.get_num_colliders();
for (int c = 0; c < num_colliders; c++) { for (int c = 0; c < num_colliders; c++) {
if (level_state.has_collider_with_geom(c)) { if (level_state.has_collider_with_geom(c)) {
entry._from_node = level_state.get_node(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); entry._from = level_state.get_collider(c);
entry._from_space = level_state.get_space(c); entry._from_space = entry._from_node_path.get_net_transform();
entry._wrt_space = entry._into_space->invert_compose(entry._from_space); entry._wrt_space = entry._from_node_path.get_transform(entry._into_node_path);
entry._inv_wrt_space = entry._from_space->invert_compose(entry._into_space); entry._inv_wrt_space = entry._into_node_path.get_transform(entry._from_node_path);
compare_collider_to_geom_node(entry, compare_collider_to_geom_node(entry,
level_state.get_parent_bound(c), level_state.get_parent_bound(c),
@ -708,7 +714,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
while (ci != _colliders.end()) { while (ci != _colliders.end()) {
if ((*ci).second == handler) { if ((*ci).second == handler) {
// This collider references this handler; remove it. // This collider references this handler; remove it.
PT(CollisionNode) node = (*ci).first; NodePath node_path = (*ci).first;
Colliders::iterator cnext = ci; Colliders::iterator cnext = ci;
++cnext; ++cnext;
@ -717,7 +723,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
// Also remove it from the ordered list. // Also remove it from the ordered list.
OrderedColliders::iterator oci = OrderedColliders::iterator oci =
find(_ordered_colliders.begin(), _ordered_colliders.end(), node); find(_ordered_colliders.begin(), _ordered_colliders.end(), node_path);
nassertr(oci != _ordered_colliders.end(), hi); nassertr(oci != _ordered_colliders.end(), hi);
_ordered_colliders.erase(oci); _ordered_colliders.erase(oci);

View File

@ -56,13 +56,18 @@ PUBLISHED:
INLINE void set_respect_prev_transform(bool flag); INLINE void set_respect_prev_transform(bool flag);
INLINE bool get_respect_prev_transform() const; INLINE bool get_respect_prev_transform() const;
void add_collider(const NodePath &collider, CollisionHandler *handler);
bool remove_collider(const NodePath &collider);
bool has_collider(const NodePath &collider) const;
int get_num_colliders() const;
NodePath get_collider(int n) const;
CollisionHandler *get_handler(const NodePath &collider) const;
void clear_colliders();
// The following methods are deprecated and exist only as a temporary
// transition to the above new NodePath-based methods.
void add_collider(CollisionNode *node, CollisionHandler *handler); void add_collider(CollisionNode *node, CollisionHandler *handler);
bool remove_collider(CollisionNode *node); bool remove_collider(CollisionNode *node);
bool has_collider(CollisionNode *node) const;
int get_num_colliders() const;
CollisionNode *get_collider(int n) const;
CollisionHandler *get_handler(CollisionNode *node) const;
void clear_colliders();
void traverse(const NodePath &root); void traverse(const NodePath &root);
void reset_prev_transform(const NodePath &root); void reset_prev_transform(const NodePath &root);
@ -103,9 +108,9 @@ private:
PT(CollisionHandler) _default_handler; PT(CollisionHandler) _default_handler;
TypeHandle _graph_type; TypeHandle _graph_type;
typedef pmap<PT(CollisionNode), PT(CollisionHandler) > Colliders; typedef pmap<NodePath, PT(CollisionHandler) > Colliders;
Colliders _colliders; Colliders _colliders;
typedef pvector<CollisionNode *> OrderedColliders; typedef pvector<NodePath> OrderedColliders;
OrderedColliders _ordered_colliders; OrderedColliders _ordered_colliders;
typedef pmap<PT(CollisionHandler), int> Handlers; typedef pmap<PT(CollisionHandler), int> Handlers;