Panda3D
 All Classes Functions Variables Enumerations
boundingLine.cxx
1 // Filename: boundingLine.cxx
2 // Created by: drose (04Jul00)
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 "boundingLine.h"
16 #include "boundingSphere.h"
17 #include "boundingBox.h"
18 #include "config_mathutil.h"
19 
20 #include <math.h>
21 
22 TypeHandle BoundingLine::_type_handle;
23 
24 ////////////////////////////////////////////////////////////////////
25 // Function: BoundingLine::make_copy
26 // Access: Public, Virtual
27 // Description:
28 ////////////////////////////////////////////////////////////////////
29 BoundingVolume *BoundingLine::
30 make_copy() const {
31  return new BoundingLine(*this);
32 }
33 
34 ////////////////////////////////////////////////////////////////////
35 // Function: BoundingLine::get_approx_center
36 // Access: Public, Virtual
37 // Description:
38 ////////////////////////////////////////////////////////////////////
39 LPoint3 BoundingLine::
40 get_approx_center() const {
41  nassertr(!is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
42  nassertr(!is_infinite(), LPoint3(0.0f, 0.0f, 0.0f));
43  return (get_point_a() + get_point_b()) / 2.0;
44 }
45 
46 ////////////////////////////////////////////////////////////////////
47 // Function: BoundingLine::xform
48 // Access: Public, Virtual
49 // Description:
50 ////////////////////////////////////////////////////////////////////
51 void BoundingLine::
52 xform(const LMatrix4 &mat) {
53  nassertv(!mat.is_nan());
54 
55  if (!is_empty() && !is_infinite()) {
56  _origin = _origin * mat;
57  _vector = _vector * mat;
58  if (!_vector.normalize()) {
59  // If we just scaled the line down to nothing, it becomes an
60  // empty volume.
61  _flags |= F_empty;
62  }
63  }
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: BoundingLine::output
68 // Access: Public, Virtual
69 // Description:
70 ////////////////////////////////////////////////////////////////////
71 void BoundingLine::
72 output(ostream &out) const {
73  if (is_empty()) {
74  out << "bline, empty";
75  } else if (is_infinite()) {
76  out << "bline, infinite";
77  } else {
78  out << "bline, (" << _origin << ") - (" << _origin + _vector << ")";
79  }
80 }
81 
82 ////////////////////////////////////////////////////////////////////
83 // Function: BoundingLine::as_bounding_line
84 // Access: Public, Virtual
85 // Description: Virtual downcast method. Returns this object as a
86 // pointer of the indicated type, if it is in fact that
87 // type. Returns NULL if it is not that type.
88 ////////////////////////////////////////////////////////////////////
91  return this;
92 }
93 
94 ////////////////////////////////////////////////////////////////////
95 // Function: BoundingLine::extend_other
96 // Access: Protected, Virtual
97 // Description:
98 ////////////////////////////////////////////////////////////////////
99 bool BoundingLine::
100 extend_other(BoundingVolume *other) const {
101  return other->extend_by_line(this);
102 }
103 
104 ////////////////////////////////////////////////////////////////////
105 // Function: BoundingLine::around_other
106 // Access: Protected, Virtual
107 // Description:
108 ////////////////////////////////////////////////////////////////////
109 bool BoundingLine::
110 around_other(BoundingVolume *other,
111  const BoundingVolume **first,
112  const BoundingVolume **last) const {
113  return other->around_lines(first, last);
114 }
115 
116 ////////////////////////////////////////////////////////////////////
117 // Function: BoundingLine::contains_other
118 // Access: Protected, Virtual
119 // Description:
120 ////////////////////////////////////////////////////////////////////
121 int BoundingLine::
122 contains_other(const BoundingVolume *other) const {
123  return other->contains_line(this);
124 }
125 
126 ////////////////////////////////////////////////////////////////////
127 // Function: BoundingLine::extend_by_line
128 // Access: Protected, Virtual
129 // Description:
130 ////////////////////////////////////////////////////////////////////
131 bool BoundingLine::
132 extend_by_line(const BoundingLine *line) {
133  nassertr(!line->is_empty() && !line->is_infinite(), false);
134  nassertr(!is_infinite(), false);
135 
136  if (is_empty()) {
137  _origin = line->_origin;
138  _vector = line->_vector;
139  _flags = 0;
140  } else {
141  _flags = F_infinite;
142  }
143  return true;
144 }
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: BoundingLine::contains_sphere
148 // Access: Protected, Virtual
149 // Description:
150 ////////////////////////////////////////////////////////////////////
151 int BoundingLine::
152 contains_sphere(const BoundingSphere *sphere) const {
153  nassertr(!is_empty() && !is_infinite(), 0);
154  nassertr(!sphere->is_empty() && !sphere->is_infinite(), 0);
155 
156  PN_stdfloat r = sphere->get_radius();
157 
158  if (r * r >= sqr_dist_to_line(sphere->get_center())) {
159  return IF_possible | IF_some;
160  } else {
161  return IF_no_intersection;
162  }
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: BoundingLine::contains_box
167 // Access: Protected, Virtual
168 // Description:
169 ////////////////////////////////////////////////////////////////////
170 int BoundingLine::
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  LPoint3 center = (box->get_minq() + box->get_maxq()) * 0.5f;
176  PN_stdfloat r2 = (box->get_maxq() - box->get_minq()).length_squared() * 0.25f;
177 
178  if (r2 >= sqr_dist_to_line(center)) {
179  return IF_possible;
180  } else {
181  return IF_no_intersection;
182  }
183 }
184 
185 ////////////////////////////////////////////////////////////////////
186 // Function: BoundingLine::sqr_dist_to_line
187 // Access: Protected
188 // Description:
189 ////////////////////////////////////////////////////////////////////
190 PN_stdfloat BoundingLine::
191 sqr_dist_to_line(const LPoint3 &point) const {
192  nassertr(!point.is_nan(), 0.0f);
193  nassertr(!is_empty() && !is_infinite(), 0.0f);
194  nassertr(!_vector.almost_equal(LVector3(0.0f, 0.0f, 0.0f)), 0.0f);
195 
196  // The formula for the distance from a point to the line based on
197  // the quadratic equation.
198 
199  PN_stdfloat A = dot(_vector, _vector);
200  nassertr(A != 0.0f, 0.0f);
201  LVector3 fc = _origin - point;
202  PN_stdfloat B = 2.0 * dot(_vector, fc);
203  PN_stdfloat fc_d2 = dot(fc, fc);
204 
205  PN_stdfloat r2 = fc_d2 - B*B / 4.0*A;
206 
207  nassertr(!cnan(r2), 0.0f);
208  return r2;
209 }
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.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
bool is_nan() const
Returns true if any component of the vector is not-a-number, false otherwise.
Definition: lvecBase3.h:463
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
const LPoint3 & get_point_a() const
Returns the first point that defines the line.
Definition: boundingLine.I:47
bool is_infinite() const
The other side of the empty coin is an infinite volume.
LPoint3 get_point_b() const
Returns the second point that defines the line.
Definition: boundingLine.I:59
bool almost_equal(const LVecBase3f &other, float threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
Definition: lvecBase3.h:1264
virtual const BoundingLine * as_bounding_line() const
Virtual downcast method.
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 normalize()
Normalizes the vector in place.
Definition: lvecBase3.h:782
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 funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
Definition: boundingLine.h:33