diff --git a/panda/src/collide/collisionHandlerPhysical.I b/panda/src/collide/collisionHandlerPhysical.I index 0e1b431d47..46983803cc 100644 --- a/panda/src/collide/collisionHandlerPhysical.I +++ b/panda/src/collide/collisionHandlerPhysical.I @@ -17,6 +17,52 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerPhysical::set_center +// Access: Published +// Description: Specifies an arbitrary NodePath that the handler is +// always considered to be facing. It does not detect +// collisions with surfaces that appear to be facing +// away from this NodePath. This works best when the +// collision surfaces in question are polygons. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerPhysical:: +set_center(const NodePath ¢er) { + _center = center; +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerPhysical::clear_center +// Access: Published +// Description: Clears the center NodePath specified with set_center. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionHandlerPhysical:: +clear_center() { + _center = NodePath(); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerPhysical::get_center +// Access: Published +// Description: Returns the NodePath specified with set_center, or +// the empty NodePath if nothing has been specified. +//////////////////////////////////////////////////////////////////// +INLINE const NodePath &CollisionHandlerPhysical:: +get_center() const { + return _center; +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionHandlerPhysical::has_center +// Access: Published +// Description: Returns true if a NodePath has been specified with +// set_center(), false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool CollisionHandlerPhysical:: +has_center() const { + return !_center.is_empty(); +} + //////////////////////////////////////////////////////////////////// // Function: CollisionHandlerPhysical::ColliderDef::set_target // Access: Public diff --git a/panda/src/collide/collisionHandlerPhysical.cxx b/panda/src/collide/collisionHandlerPhysical.cxx index e784290fa3..5aa148937c 100644 --- a/panda/src/collide/collisionHandlerPhysical.cxx +++ b/panda/src/collide/collisionHandlerPhysical.cxx @@ -69,6 +69,21 @@ add_entry(CollisionEntry *entry) { if (entry->get_from()->is_tangible() && (!entry->has_into() || entry->get_into()->is_tangible())) { + + if (has_center()) { + // If a center is specified, we have to make sure the surface is + // more-or-less facing it. + if (!entry->has_surface_point() || !entry->has_surface_normal()) { + return; + } + + LPoint3f point = entry->get_surface_point(_center); + LVector3f normal = entry->get_surface_normal(_center); + if (point.dot(normal) > 0) { + return; + } + } + _from_entries[entry->get_from_node_path()].push_back(entry); } } @@ -163,14 +178,3 @@ void CollisionHandlerPhysical:: 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)); -} diff --git a/panda/src/collide/collisionHandlerPhysical.h b/panda/src/collide/collisionHandlerPhysical.h index 28d21ea2ea..0513497af7 100644 --- a/panda/src/collide/collisionHandlerPhysical.h +++ b/panda/src/collide/collisionHandlerPhysical.h @@ -52,15 +52,12 @@ PUBLISHED: 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); + INLINE void set_center(const NodePath ¢er); + INLINE void clear_center(); + INLINE const NodePath &get_center() const; + INLINE bool has_center() const; protected: - typedef pvector< PT(CollisionEntry) > Entries; - typedef pmap FromEntries; - FromEntries _from_entries; - class ColliderDef { public: INLINE void set_target(const NodePath &target, @@ -71,11 +68,17 @@ protected: PT(DriveInterface) _drive_interface; }; + virtual bool handle_entries()=0; + virtual void apply_linear_force(ColliderDef &def, const LVector3f &force)=0; + + typedef pvector< PT(CollisionEntry) > Entries; + typedef pmap FromEntries; + FromEntries _from_entries; + typedef pmap Colliders; Colliders _colliders; - virtual bool handle_entries()=0; - virtual void apply_linear_force(ColliderDef &def, const LVector3f &force)=0; + NodePath _center; public: static TypeHandle get_class_type() {