Panda3D
 All Classes Functions Variables Enumerations
collisionHandlerPhysical.cxx
1 // Filename: collisionHandlerPhysical.cxx
2 // Created by: drose (16Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "collisionHandlerPhysical.h"
16 #include "config_collide.h"
17 
18 #include "transformState.h"
19 
20 TypeHandle CollisionHandlerPhysical::_type_handle;
21 
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: CollisionHandlerPhysical::Constructor
25 // Access: Public
26 // Description:
27 ////////////////////////////////////////////////////////////////////
28 CollisionHandlerPhysical::
29 CollisionHandlerPhysical() {
30  _has_contact = false;
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: CollisionHandlerPhysical::Destructor
35 // Access: Public, Virtual
36 // Description:
37 ////////////////////////////////////////////////////////////////////
38 CollisionHandlerPhysical::
39 ~CollisionHandlerPhysical() {
40 }
41 
42 ////////////////////////////////////////////////////////////////////
43 // Function: CollisionHandlerPhysical::begin_group
44 // Access: Public, Virtual
45 // Description: Will be called by the CollisionTraverser before a new
46 // traversal is begun. It instructs the handler to
47 // reset itself in preparation for a number of
48 // CollisionEntries to be sent.
49 ////////////////////////////////////////////////////////////////////
53  _from_entries.clear();
54  _has_contact = false;
55 }
56 
57 ////////////////////////////////////////////////////////////////////
58 // Function: CollisionHandlerPhysical::add_entry
59 // Access: Public, Virtual
60 // Description: Called between a begin_group() .. end_group()
61 // sequence for each collision that is detected.
62 ////////////////////////////////////////////////////////////////////
65  nassertv(entry != (CollisionEntry *)NULL);
67 
68  if (entry->get_from()->is_tangible() &&
69  (!entry->has_into() || entry->get_into()->is_tangible())) {
70 
71  if (has_center()) {
72  // If a center is specified, we have to make sure the surface is
73  // more-or-less facing it.
74  if (!entry->has_surface_point() || !entry->has_surface_normal()) {
75  return;
76  }
77 
78  LPoint3 point = entry->get_surface_point(_center);
79  LVector3 normal = entry->get_surface_normal(_center);
80  if (point.dot(normal) > 0) {
81  return;
82  }
83  }
84 
85  _from_entries[entry->get_from_node_path()].push_back(entry);
86  _has_contact = true;
87  }
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: CollisionHandlerPhysical::end_group
92 // Access: Public, Virtual
93 // Description: Called by the CollisionTraverser at the completion of
94 // all collision detections for this traversal. It
95 // should do whatever finalization is required for the
96 // handler.
97 ////////////////////////////////////////////////////////////////////
100  bool result = handle_entries();
102 
103  return result;
104 }
105 
106 ////////////////////////////////////////////////////////////////////
107 // Function: CollisionHandlerPhysical::add_collider
108 // Access: Published
109 // Description: Adds a new collider to the list with a NodePath
110 // that will be updated with the collider's new
111 // position, or updates the existing collider with a new
112 // NodePath object.
113 ////////////////////////////////////////////////////////////////////
115 add_collider(const NodePath &collider, const NodePath &target) {
116  nassertv(!collider.is_empty() && collider.node()->is_collision_node());
117  nassertv(validate_target(target));
118  _colliders[collider].set_target(target);
119 }
120 
121 ////////////////////////////////////////////////////////////////////
122 // Function: CollisionHandlerPhysical::add_collider
123 // Access: Published
124 // Description: Adds a new collider to the list with a NodePath
125 // that will be updated with the collider's new
126 // position, or updates the existing collider with a new
127 // NodePath object.
128 //
129 // The indicated DriveInterface will also be updated
130 // with the target's new transform each frame. This
131 // method should be used when the target is directly
132 // controlled by a DriveInterface.
133 ////////////////////////////////////////////////////////////////////
135 add_collider(const NodePath &collider, const NodePath &target,
136  DriveInterface *drive_interface) {
137  nassertv(!collider.is_empty() && collider.node()->is_collision_node());
138  nassertv(validate_target(target));
139  _colliders[collider].set_target(target, drive_interface);
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: CollisionHandlerPhysical::remove_collider
144 // Access: Published
145 // Description: Removes the collider from the list of colliders that
146 // this handler knows about.
147 ////////////////////////////////////////////////////////////////////
149 remove_collider(const NodePath &collider) {
150  Colliders::iterator ci = _colliders.find(collider);
151  if (ci == _colliders.end()) {
152  return false;
153  }
154  _colliders.erase(ci);
155  return true;
156 }
157 
158 ////////////////////////////////////////////////////////////////////
159 // Function: CollisionHandlerPhysical::has_collider
160 // Access: Published
161 // Description: Returns true if the handler knows about the indicated
162 // collider, false otherwise.
163 ////////////////////////////////////////////////////////////////////
165 has_collider(const NodePath &target) const {
166  Colliders::const_iterator ci = _colliders.find(target);
167  return (ci != _colliders.end());
168 }
169 
170 ////////////////////////////////////////////////////////////////////
171 // Function: CollisionHandlerPhysical::clear_colliders
172 // Access: Published
173 // Description: Completely empties the list of colliders this handler
174 // knows about.
175 ////////////////////////////////////////////////////////////////////
178  _colliders.clear();
179 }
180 
181 ////////////////////////////////////////////////////////////////////
182 // Function: CollisionHandlerPhysical::validate_target
183 // Access: Protected, Virtual
184 // Description: Called internally to validate the target passed to
185 // add_collider(). Returns true if acceptable, false
186 // otherwise.
187 ////////////////////////////////////////////////////////////////////
188 bool CollisionHandlerPhysical::
189 validate_target(const NodePath &target) {
190  nassertr_always(!target.is_empty(), false);
191  return true;
192 }
virtual bool end_group()
Called by the CollisionTraverser at the completion of all collision detections for this traversal...
virtual bool end_group()
Called by the CollisionTraverser at the completion of all collision detections for this traversal...
This is a TFormer, similar to Trackball, that moves around a transform matrix in response to mouse in...
virtual bool is_collision_node() const
A simple downcast check.
Definition: pandaNode.cxx:2516
virtual void begin_group()
Will be called by the CollisionTraverser before a new traversal is begun.
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:284
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
const CollisionSolid * get_from() const
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
bool has_center() const
Returns true if a NodePath has been specified with set_center(), false otherwise. ...
virtual void begin_group()
Will be called by the CollisionTraverser before a new traversal is begun.
LPoint3 get_surface_point(const NodePath &space) const
Returns the point, on the surface of the "into" object, at which a collision is detected.
void clear_colliders()
Completely empties the list of colliders this handler knows about.
bool has_collider(const NodePath &collider) const
Returns true if the handler knows about the indicated collider, false otherwise.
Defines a single collision event.
const CollisionSolid * get_into() const
Returns the CollisionSolid pointer for the particular solid was collided into.
bool remove_collider(const NodePath &collider)
Removes the collider from the list of colliders that this handler knows about.
bool is_tangible() const
Returns whether the solid is considered 'tangible' or not.
bool has_surface_point() const
Returns true if the surface point has been specified, false otherwise.
bool has_surface_normal() const
Returns true if the surface normal has been specified, false otherwise.
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
LVector3 get_surface_normal(const NodePath &space) const
Returns the surface normal of the "into" object at the point at which a collision is detected...
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:236
NodePath get_from_node_path() const
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
void add_collider(const NodePath &collider, const NodePath &target)
Adds a new collider to the list with a NodePath that will be updated with the collider's new position...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
bool has_into() const
Returns true if the "into" solid is, in fact, a CollisionSolid, and its pointer is known (in which ca...