Panda3D
 All Classes Functions Variables Enumerations
collisionEntry.cxx
1 // Filename: collisionEntry.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 "collisionEntry.h"
16 #include "dcast.h"
17 #include "indent.h"
18 
19 TypeHandle CollisionEntry::_type_handle;
20 
21 ////////////////////////////////////////////////////////////////////
22 // Function: CollisionEntry::Copy Constructor
23 // Access: Public
24 // Description:
25 ////////////////////////////////////////////////////////////////////
26 CollisionEntry::
27 CollisionEntry(const CollisionEntry &copy) :
28  _from(copy._from),
29  _into(copy._into),
30  _from_node(copy._from_node),
31  _into_node(copy._into_node),
32  _from_node_path(copy._from_node_path),
33  _into_node_path(copy._into_node_path),
34  _into_clip_planes(copy._into_clip_planes),
35  _t(copy._t),
36  _flags(copy._flags),
37  _surface_point(copy._surface_point),
38  _surface_normal(copy._surface_normal),
39  _interior_point(copy._interior_point),
40  _contact_pos(copy._contact_pos),
41  _contact_normal(copy._contact_normal)
42 {
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: CollisionEntry::Copy Assignment Operator
47 // Access: Public
48 // Description:
49 ////////////////////////////////////////////////////////////////////
50 void CollisionEntry::
51 operator = (const CollisionEntry &copy) {
52  _from = copy._from;
53  _into = copy._into;
54  _from_node = copy._from_node;
55  _into_node = copy._into_node;
56  _from_node_path = copy._from_node_path;
57  _into_node_path = copy._into_node_path;
58  _into_clip_planes = copy._into_clip_planes;
59  _t = copy._t;
60  _flags = copy._flags;
61  _surface_point = copy._surface_point;
62  _surface_normal = copy._surface_normal;
63  _interior_point = copy._interior_point;
64  _contact_pos = copy._contact_pos;
65  _contact_normal = copy._contact_normal;
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: CollisionEntry::get_surface_point
70 // Access: Published
71 // Description: Returns the point, on the surface of the "into"
72 // object, at which a collision is detected. This can
73 // be thought of as the first point of intersection.
74 // However the contact point is the actual first point of
75 // intersection.
76 //
77 // The point will be converted into whichever coordinate
78 // space the caller specifies.
79 ////////////////////////////////////////////////////////////////////
81 get_surface_point(const NodePath &space) const {
82  nassertr(has_surface_point(), LPoint3::zero());
83  CPT(TransformState) transform = _into_node_path.get_transform(space);
84  return _surface_point * transform->get_mat();
85 }
86 
87 ////////////////////////////////////////////////////////////////////
88 // Function: CollisionEntry::get_surface_normal
89 // Access: Published
90 // Description: Returns the surface normal of the "into" object at
91 // the point at which a collision is detected.
92 //
93 // The normal will be converted into whichever coordinate
94 // space the caller specifies.
95 ////////////////////////////////////////////////////////////////////
97 get_surface_normal(const NodePath &space) const {
98  nassertr(has_surface_normal(), LVector3::zero());
99  CPT(TransformState) transform = _into_node_path.get_transform(space);
100  return _surface_normal * transform->get_mat();
101 }
102 
103 ////////////////////////////////////////////////////////////////////
104 // Function: CollisionEntry::get_interior_point
105 // Access: Published
106 // Description: Returns the point, within the interior of the "into"
107 // object, which represents the depth to which the
108 // "from" object has penetrated. This can also be
109 // described as the intersection point on the surface of
110 // the "from" object (which is inside the "into"
111 // object). It can be thought of as the deepest point
112 // of intersection.
113 //
114 // The point will be converted into whichever coordinate
115 // space the caller specifies.
116 ////////////////////////////////////////////////////////////////////
118 get_interior_point(const NodePath &space) const {
119  if (!has_interior_point()) {
120  return get_surface_point(space);
121  }
122  CPT(TransformState) transform = _into_node_path.get_transform(space);
123  return _interior_point * transform->get_mat();
124 }
125 
126 ////////////////////////////////////////////////////////////////////
127 // Function: CollisionEntry::get_all
128 // Access: Published
129 // Description: Simultaneously transforms the surface point, surface
130 // normal, and interior point of the collision into the
131 // indicated coordinate space.
132 //
133 // Returns true if all three properties are available,
134 // or false if any one of them is not.
135 ////////////////////////////////////////////////////////////////////
136 bool CollisionEntry::
137 get_all(const NodePath &space, LPoint3 &surface_point,
138  LVector3 &surface_normal, LPoint3 &interior_point) const {
139  CPT(TransformState) transform = _into_node_path.get_transform(space);
140  const LMatrix4 &mat = transform->get_mat();
141  bool all_ok = true;
142 
143  if (!has_surface_point()) {
144  surface_point = LPoint3::zero();
145  all_ok = false;
146  } else {
147  surface_point = _surface_point * mat;
148  }
149 
150  if (!has_surface_normal()) {
151  surface_normal = LVector3::zero();
152  all_ok = false;
153  } else {
154  surface_normal = _surface_normal * mat;
155  }
156 
157  if (!has_interior_point()) {
158  interior_point = surface_point;
159  all_ok = false;
160  } else {
161  interior_point = _interior_point * mat;
162  }
163 
164  return all_ok;
165 }
166 
167 ////////////////////////////////////////////////////////////////////
168 // Function: CollisionEntry::get_contact_pos
169 // Access: Published
170 // Description: Returns the position of the "from" object at the instant
171 // that a collision is first detected.
172 //
173 // The position will be converted into whichever coordinate
174 // space the caller specifies.
175 ////////////////////////////////////////////////////////////////////
177 get_contact_pos(const NodePath &space) const {
178  nassertr(has_contact_pos(), LPoint3::zero());
179  CPT(TransformState) transform = _into_node_path.get_transform(space);
180  return _contact_pos * transform->get_mat();
181 }
182 
183 ////////////////////////////////////////////////////////////////////
184 // Function: CollisionEntry::get_contact_normal
185 // Access: Published
186 // Description: Returns the surface normal of the "into" object at
187 // the contact position.
188 //
189 // The normal will be converted into whichever coordinate
190 // space the caller specifies.
191 ////////////////////////////////////////////////////////////////////
193 get_contact_normal(const NodePath &space) const {
194  nassertr(has_contact_normal(), LVector3::zero());
195  CPT(TransformState) transform = _into_node_path.get_transform(space);
196  return _contact_normal * transform->get_mat();
197 }
198 
199 ////////////////////////////////////////////////////////////////////
200 // Function: CollisionEntry::get_all_contact_info
201 // Access: Published
202 // Description: Simultaneously transforms the contact position and
203 // contact normal of the collision into the
204 // indicated coordinate space.
205 //
206 // Returns true if all three properties are available,
207 // or false if any one of them is not.
208 ////////////////////////////////////////////////////////////////////
209 bool CollisionEntry::
210 get_all_contact_info(const NodePath &space, LPoint3 &contact_pos,
211  LVector3 &contact_normal) const {
212  CPT(TransformState) transform = _into_node_path.get_transform(space);
213  const LMatrix4 &mat = transform->get_mat();
214  bool all_ok = true;
215 
216  if (!has_contact_pos()) {
217  contact_pos = LPoint3::zero();
218  all_ok = false;
219  } else {
220  contact_pos = _contact_pos * mat;
221  }
222 
223  if (!has_contact_normal()) {
224  contact_normal = LVector3::zero();
225  all_ok = false;
226  } else {
227  contact_normal = _contact_normal * mat;
228  }
229 
230  return all_ok;
231 }
232 
233 ////////////////////////////////////////////////////////////////////
234 // Function: CollisionEntry::output
235 // Access: Published
236 // Description:
237 ////////////////////////////////////////////////////////////////////
238 void CollisionEntry::
239 output(ostream &out) const {
240  out << _from_node_path;
241  if (!_into_node_path.is_empty()) {
242  out << " into " << _into_node_path;
243  }
244  if (has_surface_point()) {
245  out << " at " << get_surface_point(NodePath());
246  }
247 }
248 
249 ////////////////////////////////////////////////////////////////////
250 // Function: CollisionEntry::write
251 // Access: Published
252 // Description:
253 ////////////////////////////////////////////////////////////////////
254 void CollisionEntry::
255 write(ostream &out, int indent_level) const {
256  indent(out, indent_level)
257  << "CollisionEntry:\n";
258  if (!_from_node_path.is_empty()) {
259  indent(out, indent_level + 2)
260  << "from " << _from_node_path << "\n";
261  }
262  if (!_into_node_path.is_empty()) {
263  indent(out, indent_level + 2)
264  << "into " << _into_node_path;
265 
266  out << " [";
267  _into_node_path.node()->list_tags(out, ", ");
268  out << "]";
269 
270  const ClipPlaneAttrib *cpa = get_into_clip_planes();
271  if (cpa != (ClipPlaneAttrib *)NULL) {
272  out << " (clipped)";
273  }
274  out << "\n";
275  }
276  if (has_surface_point()) {
277  indent(out, indent_level + 2)
278  << "at " << get_surface_point(NodePath()) << "\n";
279  }
280  if (has_surface_normal()) {
281  indent(out, indent_level + 2)
282  << "normal " << get_surface_normal(NodePath()) << "\n";
283  }
284  if (has_interior_point()) {
285  indent(out, indent_level + 2)
286  << "interior " << get_interior_point(NodePath())
287  << " (depth "
289  << ")\n";
290  }
291  indent(out, indent_level + 2)
292  << "respect_prev_transform = " << get_respect_prev_transform() << "\n";
293 }
294 
295 ////////////////////////////////////////////////////////////////////
296 // Function: CollisionEntry::check_clip_planes
297 // Access: Private
298 // Description: Checks whether the into_node_path has a
299 // ClipPlaneAttrib defined.
300 ////////////////////////////////////////////////////////////////////
301 void CollisionEntry::
302 check_clip_planes() {
303  _into_clip_planes = DCAST(ClipPlaneAttrib, _into_node_path.get_net_state()->get_attrib(ClipPlaneAttrib::get_class_slot()));
304  _flags |= F_checked_clip_planes;
305 }
LPoint3 get_interior_point(const NodePath &space) const
Returns the point, within the interior of the &quot;into&quot; object, which represents the depth to which the ...
void list_tags(ostream &out, const string &separator="\n") const
Writes a list of all the tag keys assigned to the node to the indicated stream.
Definition: pandaNode.cxx:1505
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:925
static const LPoint3f & zero()
Returns a zero-length point.
Definition: lpoint3.h:258
bool has_contact_pos() const
Returns true if the contact position has been specified, false otherwise.
static const LVector3f & zero()
Returns a zero-length vector.
Definition: lvector3.h:269
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
This functions similarly to a LightAttrib.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
bool get_respect_prev_transform() const
Returns true if the collision was detected by a CollisionTraverser whose respect_prev_transform flag ...
const ClipPlaneAttrib * get_into_clip_planes() const
Returns the ClipPlaneAttrib, if any, that is applied to the into_node_path, or NULL if there is no cl...
LPoint3 get_surface_point(const NodePath &space) const
Returns the point, on the surface of the &quot;into&quot; object, at which a collision is detected.
bool has_contact_normal() const
Returns true if the contact normal has been specified, false otherwise.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
const RenderAttrib * get_attrib(TypeHandle type) const
Returns the render attribute of the indicated type, if it is defined on the node, or NULL if it is no...
Definition: nodePath.I:583
Defines a single collision event.
LPoint3 get_contact_pos(const NodePath &space) const
Returns the position of the &quot;from&quot; object at the instant that a collision is first detected...
bool get_all_contact_info(const NodePath &space, LPoint3 &contact_pos, LVector3 &contact_normal) const
Simultaneously transforms the contact position and contact normal of the collision into the indicated...
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.
LVector3 get_surface_normal(const NodePath &space) const
Returns the surface normal of the &quot;into&quot; 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
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
bool has_interior_point() const
Returns true if the interior point has been specified, false otherwise.
LVector3 get_contact_normal(const NodePath &space) const
Returns the surface normal of the &quot;into&quot; object at the contact position.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165
bool get_all(const NodePath &space, LPoint3 &surface_point, LVector3 &surface_normal, LPoint3 &interior_point) const
Simultaneously transforms the surface point, surface normal, and interior point of the collision into...