Panda3D

Loading...
Searching...
No Matches
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 */
23CollisionEntry::
24CollisionEntry(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::
46operator = (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 */
72LPoint3 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 */
86LVector3 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 */
103LPoint3 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 */
157LPoint3 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 */
170LVector3 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::
212output(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::
226write(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 "
259 << (get_interior_point(NodePath()) - get_surface_point(NodePath())).length()
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::
270check_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}
CollisionEntry
Defines a single collision event.
Definition collisionEntry.h:42
CollisionEntry::get_contact_pos
LPoint3 get_contact_pos(const NodePath &space) const
Returns the position of the "from" object at the instant that a collision is first detected.
Definition collisionEntry.cxx:158
CollisionEntry::get_respect_prev_transform
get_respect_prev_transform
Returns true if the collision was detected by a CollisionTraverser whose respect_prev_transform flag ...
Definition collisionEntry.h:105
CollisionEntry::has_contact_normal
bool has_contact_normal() const
Returns true if the contact normal has been specified, false otherwise.
Definition collisionEntry.I:257
CollisionEntry::has_surface_normal
bool has_surface_normal() const
Returns true if the surface normal has been specified, false otherwise.
Definition collisionEntry.I:202
CollisionEntry::get_contact_normal
LVector3 get_contact_normal(const NodePath &space) const
Returns the surface normal of the "into" object at the contact position.
Definition collisionEntry.cxx:171
CollisionEntry::get_surface_point
LPoint3 get_surface_point(const NodePath &space) const
Returns the point, on the surface of the "into" object, at which a collision is detected.
Definition collisionEntry.cxx:73
CollisionEntry::has_surface_point
bool has_surface_point() const
Returns true if the surface point has been specified, false otherwise.
Definition collisionEntry.I:192
CollisionEntry::get_surface_normal
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.
Definition collisionEntry.cxx:87
CollisionEntry::get_interior_point
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 ...
Definition collisionEntry.cxx:104
CollisionEntry::get_all
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...
Definition collisionEntry.cxx:120
CollisionEntry::has_interior_point
bool has_interior_point() const
Returns true if the interior point has been specified, false otherwise.
Definition collisionEntry.I:212
CollisionEntry::get_all_contact_info
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...
Definition collisionEntry.cxx:185
CollisionEntry::has_contact_pos
bool has_contact_pos() const
Returns true if the contact position has been specified, false otherwise.
Definition collisionEntry.I:247
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
NodePath::is_empty
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition nodePath.I:188
TransformState
Indicates a coordinate-system transform on vertices.
Definition transformState.h:54
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
collisionEntry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dcast.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition indent.cxx:20
indent.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.