mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
first steps toward a NodePath-based interface
This commit is contained in:
parent
7249626033
commit
e07d4b7847
@ -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
|
||||
|
@ -31,6 +31,7 @@ CollisionEntry(const CollisionEntry ©) :
|
||||
_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 ©) {
|
||||
_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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user