Panda3D
 All Classes Functions Variables Enumerations
boundingPlane.cxx
1 // Filename: boundingPlane.cxx
2 // Created by: drose (19Aug05)
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 "boundingPlane.h"
16 #include "boundingSphere.h"
17 #include "boundingBox.h"
18 #include "boundingHexahedron.h"
19 #include "config_mathutil.h"
20 
21 TypeHandle BoundingPlane::_type_handle;
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: BoundingPlane::make_copy
25 // Access: Public, Virtual
26 // Description:
27 ////////////////////////////////////////////////////////////////////
28 BoundingVolume *BoundingPlane::
29 make_copy() const {
30  return new BoundingPlane(*this);
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: BoundingPlane::get_approx_center
35 // Access: Public, Virtual
36 // Description:
37 ////////////////////////////////////////////////////////////////////
38 LPoint3 BoundingPlane::
39 get_approx_center() const {
40  nassertr(!is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
41  nassertr(!is_infinite(), LPoint3(0.0f, 0.0f, 0.0f));
42  return _plane.get_point();
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: BoundingPlane::xform
47 // Access: Public, Virtual
48 // Description:
49 ////////////////////////////////////////////////////////////////////
50 void BoundingPlane::
51 xform(const LMatrix4 &mat) {
52  nassertv(!mat.is_nan());
53 
54  if (!is_empty() && !is_infinite()) {
55  _plane.xform(mat);
56  }
57 }
58 
59 ////////////////////////////////////////////////////////////////////
60 // Function: BoundingPlane::output
61 // Access: Public, Virtual
62 // Description:
63 ////////////////////////////////////////////////////////////////////
64 void BoundingPlane::
65 output(ostream &out) const {
66  if (is_empty()) {
67  out << "bplane, empty";
68  } else if (is_infinite()) {
69  out << "bplane, infinite";
70  } else {
71  out << "bplane: " << _plane;
72  }
73 }
74 
75 ////////////////////////////////////////////////////////////////////
76 // Function: BoundingPlane::as_bounding_plane
77 // Access: Public, Virtual
78 // Description: Virtual downcast method. Returns this object as a
79 // pointer of the indicated type, if it is in fact that
80 // type. Returns NULL if it is not that type.
81 ////////////////////////////////////////////////////////////////////
84  return this;
85 }
86 
87 ////////////////////////////////////////////////////////////////////
88 // Function: BoundingPlane::extend_other
89 // Access: Public, Virtual
90 // Description:
91 ////////////////////////////////////////////////////////////////////
92 bool BoundingPlane::
93 extend_other(BoundingVolume *other) const {
94  return other->extend_by_plane(this);
95 }
96 
97 ////////////////////////////////////////////////////////////////////
98 // Function: BoundingPlane::around_other
99 // Access: Public, Virtual
100 // Description:
101 ////////////////////////////////////////////////////////////////////
102 bool BoundingPlane::
103 around_other(BoundingVolume *other,
104  const BoundingVolume **first,
105  const BoundingVolume **last) const {
106  return other->around_planes(first, last);
107 }
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: BoundingPlane::contains_other
111 // Access: Public, Virtual
112 // Description:
113 ////////////////////////////////////////////////////////////////////
114 int BoundingPlane::
115 contains_other(const BoundingVolume *other) const {
116  return other->contains_plane(this);
117 }
118 
119 ////////////////////////////////////////////////////////////////////
120 // Function: BoundingPlane::extend_by_plane
121 // Access: Public, Virtual
122 // Description:
123 ////////////////////////////////////////////////////////////////////
124 bool BoundingPlane::
125 extend_by_plane(const BoundingPlane *plane) {
126  nassertr(!plane->is_empty() && !plane->is_infinite(), false);
127  nassertr(!is_infinite(), false);
128 
129  if (is_empty()) {
130  _plane = plane->get_plane();
131  _flags = 0;
132  } else {
133  _flags = F_infinite;
134  }
135  return true;
136 }
137 
138 ////////////////////////////////////////////////////////////////////
139 // Function: BoundingPlane::contains_sphere
140 // Access: Public, Virtual
141 // Description:
142 ////////////////////////////////////////////////////////////////////
143 int BoundingPlane::
144 contains_sphere(const BoundingSphere *sphere) const {
145  nassertr(!is_empty() && !is_infinite(), 0);
146  nassertr(!sphere->is_empty() && !sphere->is_infinite(), 0);
147 
148  PN_stdfloat r = sphere->get_radius();
149  PN_stdfloat d = _plane.dist_to_plane(sphere->get_center());
150 
151  if (d <= -r) {
152  // The sphere is completely behind the plane.
153  return IF_all | IF_possible | IF_some;
154 
155  } else if (d <= r) {
156  // The sphere is intersecting with the plane itself.
157  return IF_possible | IF_some;
158 
159  } else {
160  // The sphere is completely in front of the plane.
161  return IF_no_intersection;
162  }
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: BoundingPlane::contains_box
167 // Access: Public, Virtual
168 // Description:
169 ////////////////////////////////////////////////////////////////////
170 int BoundingPlane::
171 contains_box(const BoundingBox *box) const {
172  nassertr(!is_empty() && !is_infinite(), 0);
173  nassertr(!box->is_empty() && !box->is_infinite(), 0);
174 
175  // Put the box inside a sphere for the purpose of this test.
176  const LPoint3 &min = box->get_minq();
177  const LPoint3 &max = box->get_maxq();
178  LPoint3 center = (min + max) * 0.5f;
179  PN_stdfloat radius2 = (max - center).length_squared();
180 
181  int result = IF_possible | IF_some | IF_all;
182 
183  PN_stdfloat dist = _plane.dist_to_plane(center);
184  PN_stdfloat dist2 = dist * dist;
185 
186  if (dist2 <= radius2) {
187  // The sphere is not completely behind this plane, but some of
188  // it is.
189 
190  // Look a little closer.
191  bool all_in = true;
192  bool all_out = true;
193  for (int i = 0; i < 8 && (all_in || all_out) ; ++i) {
194  if (_plane.dist_to_plane(box->get_point(i)) < 0.0f) {
195  // This point is inside the plane.
196  all_out = false;
197  } else {
198  // This point is outside the plane.
199  all_in = false;
200  }
201  }
202 
203  if (all_out) {
204  return IF_no_intersection;
205  } else if (!all_in) {
206  result &= ~IF_all;
207  }
208 
209  } else if (dist >= 0.0f) {
210  // The sphere is completely in front of this plane.
211  return IF_no_intersection;
212  }
213 
214  return result;
215 }
216 
217 ////////////////////////////////////////////////////////////////////
218 // Function: BoundingPlane::contains_line
219 // Access: Public, Virtual
220 // Description:
221 ////////////////////////////////////////////////////////////////////
222 int BoundingPlane::
223 contains_line(const BoundingLine *line) const {
224  return IF_possible;
225 }
226 
227 ////////////////////////////////////////////////////////////////////
228 // Function: BoundingPlane::contains_plane
229 // Access: Public, Virtual
230 // Description:
231 ////////////////////////////////////////////////////////////////////
232 int BoundingPlane::
233 contains_plane(const BoundingPlane *plane) const {
234  return IF_possible;
235 }
236 
237 ////////////////////////////////////////////////////////////////////
238 // Function: BoundingPlane::contains_hexahedron
239 // Access: Protected, Virtual
240 // Description: Double-dispatch support: called by contains_other()
241 // when the type we're testing for intersection is known
242 // to be a hexahedron.
243 ////////////////////////////////////////////////////////////////////
244 int BoundingPlane::
245 contains_hexahedron(const BoundingHexahedron *hexahedron) const {
246  nassertr(!is_empty() && !is_infinite(), 0);
247  nassertr(!hexahedron->is_empty() && !hexahedron->is_infinite(), 0);
248 
249  int result = IF_possible | IF_some | IF_all;
250 
251  bool all_in = true;
252  bool all_out = true;
253  for (int i = 0; i < 8 && (all_in || all_out) ; ++i) {
254  if (_plane.dist_to_plane(hexahedron->get_point(i)) < 0.0f) {
255  // This point is inside the plane.
256  all_out = false;
257  } else {
258  // This point is outside the plane.
259  all_in = false;
260  }
261  }
262 
263  if (all_out) {
264  return IF_no_intersection;
265  } else if (!all_in) {
266  result &= ~IF_all;
267  }
268 
269  return result;
270 }
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition: boundingBox.h:31
This defines a bounding sphere, consisting of a center and a radius.
virtual const BoundingPlane * as_bounding_plane() const
Virtual downcast method.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
This funny bounding volume is an infinite plane that divides space into two regions: the part behind ...
Definition: boundingPlane.h:31
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
const LPoint3 & get_maxq() const
An inline accessor for the maximum value.
Definition: boundingBox.I:64
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
BoundingPlane()
Constructs an empty &quot;plane&quot; that has no intersections.
Definition: boundingPlane.I:23
LPoint3 get_point(int n) const
Returns the nth vertex of the hexahedron.
bool is_infinite() const
The other side of the empty coin is an infinite volume.
LPoint3 get_point(int n) const
Returns the nth vertex of the rectangular solid.
Definition: boundingBox.I:86
bool is_empty() const
Any kind of volume might be empty.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
bool is_nan() const
Returns true if any component of the matrix is not-a-number, false otherwise.
Definition: lmatrix.h:1417
const LPoint3 & get_minq() const
An inline accessor for the minimum value.
Definition: boundingBox.I:50
This defines a bounding convex hexahedron.
This funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
Definition: boundingLine.h:33