Panda3D
collisionEntry.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file collisionEntry.cxx
10  * @author drose
11  * @date 2002-03-16
12  */
13 
14 #include "collisionEntry.h"
15 #include "dcast.h"
16 #include "indent.h"
17 
18 TypeHandle CollisionEntry::_type_handle;
19 
20 /**
21  *
22  */
23 CollisionEntry::
24 CollisionEntry(const CollisionEntry &copy) :
25  _from(copy._from),
26  _into(copy._into),
27  _from_node(copy._from_node),
28  _into_node(copy._into_node),
29  _from_node_path(copy._from_node_path),
30  _into_node_path(copy._into_node_path),
31  _into_clip_planes(copy._into_clip_planes),
32  _t(copy._t),
33  _flags(copy._flags),
34  _surface_point(copy._surface_point),
35  _surface_normal(copy._surface_normal),
36  _interior_point(copy._interior_point),
37  _contact_pos(copy._contact_pos),
38  _contact_normal(copy._contact_normal)
39 {
40 }
41 
42 /**
43  *
44  */
45 void CollisionEntry::
46 operator = (const CollisionEntry &copy) {
47  _from = copy._from;
48  _into = copy._into;
49  _from_node = copy._from_node;
50  _into_node = copy._into_node;
51  _from_node_path = copy._from_node_path;
52  _into_node_path = copy._into_node_path;
53  _into_clip_planes = copy._into_clip_planes;
54  _t = copy._t;
55  _flags = copy._flags;
56  _surface_point = copy._surface_point;
57  _surface_normal = copy._surface_normal;
58  _interior_point = copy._interior_point;
59  _contact_pos = copy._contact_pos;
60  _contact_normal = copy._contact_normal;
61 }
62 
63 /**
64  * Returns the point, on the surface of the "into" object, at which a
65  * collision is detected. This can be thought of as the first point of
66  * intersection. However the contact point is the actual first point of
67  * intersection.
68  *
69  * The point will be converted into whichever coordinate space the caller
70  * specifies.
71  */
72 LPoint3 CollisionEntry::
73 get_surface_point(const NodePath &space) const {
74  nassertr(has_surface_point(), LPoint3::zero());
75  CPT(TransformState) transform = _into_node_path.get_transform(space);
76  return _surface_point * transform->get_mat();
77 }
78 
79 /**
80  * Returns the surface normal of the "into" object at the point at which a
81  * collision is detected.
82  *
83  * The normal will be converted into whichever coordinate space the caller
84  * specifies.
85  */
86 LVector3 CollisionEntry::
87 get_surface_normal(const NodePath &space) const {
88  nassertr(has_surface_normal(), LVector3::zero());
89  CPT(TransformState) transform = _into_node_path.get_transform(space);
90  return _surface_normal * transform->get_mat();
91 }
92 
93 /**
94  * Returns the point, within the interior of the "into" object, which
95  * represents the depth to which the "from" object has penetrated. This can
96  * also be described as the intersection point on the surface of the "from"
97  * object (which is inside the "into" object). It can be thought of as the
98  * deepest point of intersection.
99  *
100  * The point will be converted into whichever coordinate space the caller
101  * specifies.
102  */
103 LPoint3 CollisionEntry::
104 get_interior_point(const NodePath &space) const {
105  if (!has_interior_point()) {
106  return get_surface_point(space);
107  }
108  CPT(TransformState) transform = _into_node_path.get_transform(space);
109  return _interior_point * transform->get_mat();
110 }
111 
112 /**
113  * Simultaneously transforms the surface point, surface normal, and interior
114  * point of the collision into the indicated coordinate space.
115  *
116  * Returns true if all three properties are available, or false if any one of
117  * them is not.
118  */
119 bool CollisionEntry::
120 get_all(const NodePath &space, LPoint3 &surface_point,
121  LVector3 &surface_normal, LPoint3 &interior_point) const {
122  CPT(TransformState) transform = _into_node_path.get_transform(space);
123  const LMatrix4 &mat = transform->get_mat();
124  bool all_ok = true;
125 
126  if (!has_surface_point()) {
127  surface_point = LPoint3::zero();
128  all_ok = false;
129  } else {
130  surface_point = _surface_point * mat;
131  }
132 
133  if (!has_surface_normal()) {
134  surface_normal = LVector3::zero();
135  all_ok = false;
136  } else {
137  surface_normal = _surface_normal * mat;
138  }
139 
140  if (!has_interior_point()) {
141  interior_point = surface_point;
142  all_ok = false;
143  } else {
144  interior_point = _interior_point * mat;
145  }
146 
147  return all_ok;
148 }
149 
150 /**
151  * Returns the position of the "from" object at the instant that a collision
152  * is first detected.
153  *
154  * The position will be converted into whichever coordinate space the caller
155  * specifies.
156  */
157 LPoint3 CollisionEntry::
158 get_contact_pos(const NodePath &space) const {
159  nassertr(has_contact_pos(), LPoint3::zero());
160  CPT(TransformState) transform = _into_node_path.get_transform(space);
161  return _contact_pos * transform->get_mat();
162 }
163 
164 /**
165  * Returns the surface normal of the "into" object at the contact position.
166  *
167  * The normal will be converted into whichever coordinate space the caller
168  * specifies.
169  */
170 LVector3 CollisionEntry::
171 get_contact_normal(const NodePath &space) const {
172  nassertr(has_contact_normal(), LVector3::zero());
173  CPT(TransformState) transform = _into_node_path.get_transform(space);
174  return _contact_normal * transform->get_mat();
175 }
176 
177 /**
178  * Simultaneously transforms the contact position and contact normal of the
179  * collision into the indicated coordinate space.
180  *
181  * Returns true if all three properties are available, or false if any one of
182  * them is not.
183  */
184 bool CollisionEntry::
185 get_all_contact_info(const NodePath &space, LPoint3 &contact_pos,
186  LVector3 &contact_normal) const {
187  CPT(TransformState) transform = _into_node_path.get_transform(space);
188  const LMatrix4 &mat = transform->get_mat();
189  bool all_ok = true;
190 
191  if (!has_contact_pos()) {
192  contact_pos = LPoint3::zero();
193  all_ok = false;
194  } else {
195  contact_pos = _contact_pos * mat;
196  }
197 
198  if (!has_contact_normal()) {
199  contact_normal = LVector3::zero();
200  all_ok = false;
201  } else {
202  contact_normal = _contact_normal * mat;
203  }
204 
205  return all_ok;
206 }
207 
208 /**
209  *
210  */
211 void CollisionEntry::
212 output(std::ostream &out) const {
213  out << _from_node_path;
214  if (!_into_node_path.is_empty()) {
215  out << " into " << _into_node_path;
216  }
217  if (has_surface_point()) {
218  out << " at " << get_surface_point(NodePath());
219  }
220 }
221 
222 /**
223  *
224  */
225 void CollisionEntry::
226 write(std::ostream &out, int indent_level) const {
227  indent(out, indent_level)
228  << "CollisionEntry:\n";
229  if (!_from_node_path.is_empty()) {
230  indent(out, indent_level + 2)
231  << "from " << _from_node_path << "\n";
232  }
233  if (!_into_node_path.is_empty()) {
234  indent(out, indent_level + 2)
235  << "into " << _into_node_path;
236 
237  out << " [";
238  _into_node_path.node()->list_tags(out, ", ");
239  out << "]";
240 
241  const ClipPlaneAttrib *cpa = get_into_clip_planes();
242  if (cpa != nullptr) {
243  out << " (clipped)";
244  }
245  out << "\n";
246  }
247  if (has_surface_point()) {
248  indent(out, indent_level + 2)
249  << "at " << get_surface_point(NodePath()) << "\n";
250  }
251  if (has_surface_normal()) {
252  indent(out, indent_level + 2)
253  << "normal " << get_surface_normal(NodePath()) << "\n";
254  }
255  if (has_interior_point()) {
256  indent(out, indent_level + 2)
257  << "interior " << get_interior_point(NodePath())
258  << " (depth "
260  << ")\n";
261  }
262  indent(out, indent_level + 2)
263  << "respect_prev_transform = " << get_respect_prev_transform() << "\n";
264 }
265 
266 /**
267  * Checks whether the into_node_path has a ClipPlaneAttrib defined.
268  */
269 void CollisionEntry::
270 check_clip_planes() {
271  _into_clip_planes = DCAST(ClipPlaneAttrib, _into_node_path.get_net_state()->get_attrib(ClipPlaneAttrib::get_class_slot()));
272  _flags |= F_checked_clip_planes;
273 }
bool has_surface_point() const
Returns true if the surface point has been specified, false otherwise.
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...
LPoint3 get_surface_point(const NodePath &space) const
Returns the point, on the surface of the "into" object, at which a collision is detected.
Indicates a coordinate-system transform on vertices.
LPoint3 get_contact_pos(const NodePath &space) const
Returns the position of the "from" object at the instant that a collision is first detected.
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:188
void list_tags(std::ostream &out, const std::string &separator="\n") const
Writes a list of all the tag keys assigned to the node to the indicated stream.
Definition: pandaNode.cxx:1283
bool has_contact_normal() const
Returns true if the contact normal has been specified, false otherwise.
This functions similarly to a LightAttrib.
LVector3 get_contact_normal(const NodePath &space) const
Returns the surface normal of the "into" object at the contact position.
bool has_surface_normal() const
Returns true if the surface normal has been specified, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
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:459
get_respect_prev_transform
Returns true if the collision was detected by a CollisionTraverser whose respect_prev_transform flag ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
Defines a single collision event.
LPoint3 get_interior_point(const NodePath &space) const
Returns the point, within the interior of the "into" object, which represents the depth to which the ...
bool has_contact_pos() const
Returns true if the contact position has been specified, false otherwise.
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
bool has_interior_point() const
Returns true if the interior point has been specified, false otherwise.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:758
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.