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;
}
////////////////////////////////////////////////////////////////////
// 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
// Access: Published

View File

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

View File

@ -59,6 +59,7 @@ PUBLISHED:
INLINE CollisionNode *get_from_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 TransformState *get_from_space() const;
@ -106,6 +107,7 @@ private:
PT(CollisionNode) _from_node;
PT(PandaNode) _into_node;
NodePath _from_node_path;
NodePath _into_node_path;
CPT(TransformState) _from_space;
CPT(TransformState) _into_space;

View File

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

View File

@ -39,6 +39,19 @@ set_node(PandaNode *node) {
_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
// Access: Public

View File

@ -126,40 +126,29 @@ end_group() {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::add_collider_drive
// Access: Public
// 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.
// Function: CollisionHandlerPhysical::add_collider
// Access: Published
// Description: Adds a new collider to the list with a NodePath
// that will be updated with the collider's new
// position, or updates the existing collider with a new
// NodePath object.
////////////////////////////////////////////////////////////////////
void CollisionHandlerPhysical::
add_collider_drive(CollisionNode *node, DriveInterface *drive_interface) {
_colliders[node].set_drive_interface(drive_interface);
}
////////////////////////////////////////////////////////////////////
// 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);
add_collider(const NodePath &collider, const NodePath &target) {
nassertv(!collider.is_empty() && collider.node()->is_of_type(CollisionNode::get_class_type()));
nassertv(!target.is_empty());
_colliders[collider].set_target(target);
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::remove_collider
// Access: Public
// Access: Published
// Description: Removes the collider from the list of colliders that
// this handler knows about.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerPhysical::
remove_collider(CollisionNode *node) {
Colliders::iterator ci = _colliders.find(node);
remove_collider(const NodePath &collider) {
Colliders::iterator ci = _colliders.find(collider);
if (ci == _colliders.end()) {
return false;
}
@ -169,19 +158,19 @@ remove_collider(CollisionNode *node) {
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::has_collider
// Access: Public
// Access: Published
// Description: Returns true if the handler knows about the indicated
// collider, false otherwise.
////////////////////////////////////////////////////////////////////
bool CollisionHandlerPhysical::
has_collider(CollisionNode *node) const {
Colliders::const_iterator ci = _colliders.find(node);
has_collider(const NodePath &target) const {
Colliders::const_iterator ci = _colliders.find(target);
return (ci != _colliders.end());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionHandlerPhysical::clear_colliders
// Access: Public
// Access: Published
// Description: Completely empties the list of colliders this handler
// knows about.
////////////////////////////////////////////////////////////////////
@ -190,4 +179,26 @@ clear_colliders() {
_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();
PUBLISHED:
void add_collider_node(CollisionNode *node, PandaNode *target);
bool remove_collider(CollisionNode *node);
bool has_collider(CollisionNode *node) const;
void add_collider(const NodePath &collider, const NodePath &target);
bool remove_collider(const NodePath &collider);
bool has_collider(const NodePath &collider) const;
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.
void add_collider_drive(CollisionNode *node, DriveInterface *drive_interface);
protected:
typedef pvector< PT(CollisionEntry) > Entries;
typedef pmap<PT(CollisionNode), Entries> FromEntries;
typedef pmap<NodePath, Entries> FromEntries;
FromEntries _from_entries;
class ColliderDef {
public:
INLINE void set_drive_interface(DriveInterface *drive_interface);
INLINE void set_node(PandaNode *node);
INLINE void set_target(const NodePath &target);
INLINE bool is_valid() const;
void get_mat(LMatrix4f &mat) const;
@ -69,9 +74,10 @@ protected:
PT(DriveInterface) _drive_interface;
PT(PandaNode) _node;
NodePath _target;
};
typedef pmap<PT(CollisionNode), ColliderDef> Colliders;
typedef pmap<NodePath, ColliderDef> Colliders;
Colliders _colliders;
virtual bool handle_entries()=0;

View File

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

View File

@ -150,12 +150,12 @@ get_collider(int n) const {
}
////////////////////////////////////////////////////////////////////
// Function: CollisionLevelState::get_node
// Function: CollisionLevelState::get_collider_node
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CollisionNode *CollisionLevelState::
get_node(int n) const {
get_collider_node(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), 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
// Description:
////////////////////////////////////////////////////////////////////
INLINE const TransformState *CollisionLevelState::
get_space(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), TransformState::make_identity());
nassertr(has_collider(n), TransformState::make_identity());
INLINE NodePath CollisionLevelState::
get_collider_node_path(int n) const {
nassertr(n >= 0 && n < (int)_colliders.size(), NodePath::fail());
nassertr(has_collider(n), NodePath::fail());
return _colliders[n]._space;
}
////////////////////////////////////////////////////////////////////
// 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;
return _colliders[n]._node_path;
}
////////////////////////////////////////////////////////////////////

View File

@ -64,6 +64,11 @@ prepare_collider(const ColliderDef &def) {
GeometricBoundingVolume *gbv;
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 the node has a delta, we have to include the starting
// point in the volume as well.
@ -76,8 +81,9 @@ prepare_collider(const ColliderDef &def) {
// same results, and is much easier to compute.
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);
}
@ -119,14 +125,14 @@ any_in_bounds() {
int num_colliders = get_num_colliders();
for (int c = 0; c < num_colliders; c++) {
if (has_collider(c)) {
CollisionNode *collider = get_node(c);
CollisionNode *cnode = get_collider_node(c);
bool is_in = false;
// Don't even bother testing the bounding volume if there are
// no collide bits in common between our collider and this
// node.
CollideMask from_mask = collider->get_from_collide_mask();
if (collider->get_collide_geom() ||
CollideMask from_mask = cnode->get_from_collide_mask();
if (cnode->get_collide_geom() ||
(from_mask & node()->get_net_collide_mask()) != 0) {
// There are bits in common, so go ahead and try the
// bounding volume.

View File

@ -26,7 +26,6 @@
#include "geometricBoundingVolume.h"
#include "nodePath.h"
#include "workingNodePath.h"
#include "transformState.h"
#include "pointerTo.h"
#include "plist.h"
@ -45,10 +44,7 @@ public:
public:
CollisionSolid *_collider;
CollisionNode *_node;
CPT(TransformState) _space;
CPT(TransformState) _inv_space;
CPT(TransformState) _prev_space;
LVector3f _delta;
NodePath _node_path;
};
INLINE CollisionLevelState(const NodePath &node_path);
@ -74,11 +70,8 @@ public:
INLINE void reached_collision_node();
INLINE CollisionSolid *get_collider(int n) const;
INLINE CollisionNode *get_node(int n) const;
INLINE const TransformState *get_space(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 CollisionNode *get_collider_node(int n) const;
INLINE NodePath get_collider_node_path(int n) const;
INLINE const GeometricBoundingVolume *get_local_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
// Access: Public
// Access: Published
// Description: Sets the flag that indicates whether the
// prev_transform stored on a node (as updated via
// set_fluid_pos(), etc.) is respected to calculate
@ -36,7 +36,7 @@ set_respect_prev_transform(bool flag) {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_respect_prev_transform
// Access: Public
// Access: Published
// Description: Returns the flag that indicates whether the
// prev_transform stored on a node is respected to
// calculate collisions. See
@ -51,7 +51,7 @@ get_respect_prev_transform() const {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::has_recorder
// Access: Public
// Access: Published
// Description: Returns true if the CollisionTraverser has a
// CollisionRecorder object currently assigned, false
// otherwise.
@ -63,7 +63,7 @@ has_recorder() const {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_recorder
// Access: Public
// Access: Published
// Description: Returns the CollisionRecorder currently assigned, or
// NULL if no recorder is assigned.
////////////////////////////////////////////////////////////////////
@ -74,7 +74,7 @@ get_recorder() const {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::clear_recorder
// Access: Public
// Access: Published
// Description: Removes the CollisionRecorder from the traverser and
// restores normal low-overhead operation.
////////////////////////////////////////////////////////////////////

View File

@ -36,7 +36,7 @@ PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::Constructor
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CollisionTraverser::
@ -49,7 +49,7 @@ CollisionTraverser() {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::Destructor
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CollisionTraverser::
@ -61,7 +61,7 @@ CollisionTraverser::
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::add_collider
// Access: Public
// Access: Published
// Description: Adds a new CollisionNode, representing an object that
// will be tested for collisions into other objects,
// along with the handler that will serve each detected
@ -74,12 +74,12 @@ CollisionTraverser::
// again on the same node.
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
add_collider(CollisionNode *node, CollisionHandler *handler) {
add_collider(const NodePath &collider, CollisionHandler *handler) {
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);
Colliders::iterator ci = _colliders.find(node);
Colliders::iterator ci = _colliders.find(collider);
if (ci != _colliders.end()) {
// We already knew about this collider.
if ((*ci).second != handler) {
@ -106,8 +106,8 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
} else {
// We hadn't already known about this collider.
_colliders.insert(Colliders::value_type(node, handler));
_ordered_colliders.push_back(node);
_colliders.insert(Colliders::value_type(collider, handler));
_ordered_colliders.push_back(collider);
Handlers::iterator hi = _handlers.find(handler);
if (hi == _handlers.end()) {
@ -122,7 +122,7 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::remove_collider
// Access: Public
// Access: Published
// Description: Removes the collider (and its associated handler)
// from the set of CollisionNodes that will be tested
// 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.
////////////////////////////////////////////////////////////////////
bool CollisionTraverser::
remove_collider(CollisionNode *node) {
remove_collider(const NodePath &collider) {
nassertr(_ordered_colliders.size() == _colliders.size(), false);
Colliders::iterator ci = _colliders.find(node);
Colliders::iterator ci = _colliders.find(collider);
if (ci == _colliders.end()) {
// We didn't know about this node.
return false;
@ -153,7 +153,7 @@ remove_collider(CollisionNode *node) {
_colliders.erase(ci);
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);
_ordered_colliders.erase(oci);
@ -163,20 +163,20 @@ remove_collider(CollisionNode *node) {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::has_collider
// Access: Public
// Access: Published
// Description: Returns true if the indicated node is current in the
// set of nodes that will be tested each frame for
// collisions into other objects.
////////////////////////////////////////////////////////////////////
bool CollisionTraverser::
has_collider(CollisionNode *node) const {
Colliders::const_iterator ci = _colliders.find(node);
has_collider(const NodePath &collider) const {
Colliders::const_iterator ci = _colliders.find(collider);
return (ci != _colliders.end());
}
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_num_colliders
// Access: Public
// Access: Published
// Description: Returns the number of CollisionNodes that have been
// added to the traverser via add_collider().
////////////////////////////////////////////////////////////////////
@ -188,11 +188,11 @@ get_num_colliders() const {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::get_collider
// Access: Public
// Access: Published
// Description: Returns the nth CollisionNode that has been
// added to the traverser via add_collider().
////////////////////////////////////////////////////////////////////
CollisionNode *CollisionTraverser::
NodePath CollisionTraverser::
get_collider(int n) const {
nassertr(_ordered_colliders.size() == _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
// Access: Public
// Access: Published
// Description: Returns the handler that is currently assigned to
// serve the indicated collision node, or NULL if the
// node is not on the traverser's set of active nodes.
////////////////////////////////////////////////////////////////////
CollisionHandler *CollisionTraverser::
get_handler(CollisionNode *node) const {
Colliders::const_iterator ci = _colliders.find(node);
get_handler(const NodePath &collider) const {
Colliders::const_iterator ci = _colliders.find(collider);
if (ci != _colliders.end()) {
return (*ci).second;
};
@ -217,7 +217,7 @@ get_handler(CollisionNode *node) const {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::clear_colliders
// Access: Public
// Access: Published
// Description: Completely empties the set of collision nodes and
// their associated handlers.
////////////////////////////////////////////////////////////////////
@ -227,10 +227,31 @@ clear_colliders() {
_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
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
@ -272,7 +293,7 @@ traverse(const NodePath &root) {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::reset_prev_transform
// Access: Public
// Access: Published
// Description: Once the collision traversal has finished, resets all
// of the velocity deltas in the scene graph by setting
// the "previous" transform to the current transform.
@ -287,7 +308,7 @@ reset_prev_transform(const NodePath &root) {
#ifdef DO_COLLISION_RECORDING
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::set_recorder
// Access: Public
// Access: Published
// Description: Uses the indicated CollisionRecorder object to start
// recording the intersection tests made by each
// subsequent call to traverse() on this object. A
@ -333,7 +354,7 @@ set_recorder(CollisionRecorder *recorder) {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::output
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
@ -344,7 +365,7 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
// Function: CollisionTraverser::write
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void CollisionTraverser::
@ -354,16 +375,19 @@ write(ostream &out, int indent_level) const {
<< " colliders and " << _handlers.size() << " handlers:\n";
Colliders::const_iterator ci;
for (ci = _colliders.begin(); ci != _colliders.end(); ++ci) {
CollisionNode *cnode = (*ci).first;
NodePath cnode_path = (*ci).first;
CollisionHandler *handler = (*ci).second;
nassertv(cnode != (CollisionNode *)NULL);
nassertv(handler != (CollisionHandler *)NULL);
indent(out, indent_level + 2)
<< *cnode << " handled by " << handler->get_type() << "\n";
int num_solids = cnode->get_num_solids();
for (int i = 0; i < num_solids; i++) {
cnode->get_solid(i)->write(out, indent_level + 4);
<< 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();
for (int i = 0; i < num_solids; i++) {
cnode->get_solid(i)->write(out, indent_level + 4);
}
}
}
}
@ -381,40 +405,23 @@ prepare_colliders(CollisionLevelState &level_state) {
int i = 0;
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;
def._node = cnode;
NodePath cnode_path(cnode);
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();
for (int s = 0; s < num_solids; s++) {
CollisionSolid *collider = cnode->get_solid(s);
def._collider = collider;
level_state.prepare_collider(def);
}
i++;
CollisionLevelState::ColliderDef def;
def._node = cnode;
def._node_path = cnode_path;
int num_solids = cnode->get_num_solids();
for (int s = 0; s < num_solids; s++) {
CollisionSolid *collider = cnode->get_solid(s);
def._collider = collider;
level_state.prepare_collider(def);
}
i++;
}
}
}
@ -450,21 +457,20 @@ 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(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() &
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_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) {
CPT(TransformState) into_prev_space = entry._into_node_path.get_net_prev_transform();
CPT(TransformState) from_prev_space = level_state.get_prev_space(c);
entry._wrt_prev_space = into_prev_space->invert_compose(from_prev_space);
entry._wrt_prev_space = entry._from_node_path.get_prev_transform(entry._into_node_path);
} else {
entry._wrt_prev_space = entry._wrt_space;
}
@ -501,13 +507,13 @@ 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)) {
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_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._inv_wrt_space = entry._from_space->invert_compose(entry._into_space);
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);
compare_collider_to_geom_node(entry,
level_state.get_parent_bound(c),
@ -708,7 +714,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
while (ci != _colliders.end()) {
if ((*ci).second == handler) {
// This collider references this handler; remove it.
PT(CollisionNode) node = (*ci).first;
NodePath node_path = (*ci).first;
Colliders::iterator cnext = ci;
++cnext;
@ -717,7 +723,7 @@ remove_handler(CollisionTraverser::Handlers::iterator hi) {
// Also remove it from the ordered list.
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);
_ordered_colliders.erase(oci);

View File

@ -56,13 +56,18 @@ PUBLISHED:
INLINE void set_respect_prev_transform(bool flag);
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);
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 reset_prev_transform(const NodePath &root);
@ -103,9 +108,9 @@ private:
PT(CollisionHandler) _default_handler;
TypeHandle _graph_type;
typedef pmap<PT(CollisionNode), PT(CollisionHandler) > Colliders;
typedef pmap<NodePath, PT(CollisionHandler) > Colliders;
Colliders _colliders;
typedef pvector<CollisionNode *> OrderedColliders;
typedef pvector<NodePath> OrderedColliders;
OrderedColliders _ordered_colliders;
typedef pmap<PT(CollisionHandler), int> Handlers;