Panda3D
boundingLine.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 boundingLine.cxx
10  * @author drose
11  * @date 2000-07-04
12  */
13 
14 #include "boundingLine.h"
15 #include "boundingSphere.h"
16 #include "boundingBox.h"
17 #include "config_mathutil.h"
18 
19 #include <math.h>
20 
21 TypeHandle BoundingLine::_type_handle;
22 
23 /**
24  *
25  */
26 BoundingVolume *BoundingLine::
27 make_copy() const {
28  return new BoundingLine(*this);
29 }
30 
31 /**
32  *
33  */
34 LPoint3 BoundingLine::
35 get_approx_center() const {
36  nassertr(!is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
37  nassertr(!is_infinite(), LPoint3(0.0f, 0.0f, 0.0f));
38  return (get_point_a() + get_point_b()) / 2.0;
39 }
40 
41 /**
42  *
43  */
44 void BoundingLine::
45 xform(const LMatrix4 &mat) {
46  nassertv(!mat.is_nan());
47 
48  if (!is_empty() && !is_infinite()) {
49  _origin = _origin * mat;
50  _vector = _vector * mat;
51  if (!_vector.normalize()) {
52  // If we just scaled the line down to nothing, it becomes an empty
53  // volume.
54  _flags |= F_empty;
55  }
56  }
57 }
58 
59 /**
60  *
61  */
62 void BoundingLine::
63 output(std::ostream &out) const {
64  if (is_empty()) {
65  out << "bline, empty";
66  } else if (is_infinite()) {
67  out << "bline, infinite";
68  } else {
69  out << "bline, (" << _origin << ") - (" << _origin + _vector << ")";
70  }
71 }
72 
73 /**
74  * Virtual downcast method. Returns this object as a pointer of the indicated
75  * type, if it is in fact that type. Returns NULL if it is not that type.
76  */
78 as_bounding_line() const {
79  return this;
80 }
81 
82 /**
83  *
84  */
85 bool BoundingLine::
86 extend_other(BoundingVolume *other) const {
87  return other->extend_by_line(this);
88 }
89 
90 /**
91  *
92  */
93 bool BoundingLine::
94 around_other(BoundingVolume *other,
95  const BoundingVolume **first,
96  const BoundingVolume **last) const {
97  return other->around_lines(first, last);
98 }
99 
100 /**
101  *
102  */
103 int BoundingLine::
104 contains_other(const BoundingVolume *other) const {
105  return other->contains_line(this);
106 }
107 
108 /**
109  *
110  */
111 bool BoundingLine::
112 extend_by_line(const BoundingLine *line) {
113  nassertr(!line->is_empty() && !line->is_infinite(), false);
114  nassertr(!is_infinite(), false);
115 
116  if (is_empty()) {
117  _origin = line->_origin;
118  _vector = line->_vector;
119  _flags = 0;
120  } else {
121  _flags = F_infinite;
122  }
123  return true;
124 }
125 
126 /**
127  *
128  */
129 int BoundingLine::
130 contains_sphere(const BoundingSphere *sphere) const {
131  nassertr(!is_empty() && !is_infinite(), 0);
132  nassertr(!sphere->is_empty() && !sphere->is_infinite(), 0);
133 
134  PN_stdfloat r = sphere->get_radius();
135 
136  if (r * r >= sqr_dist_to_line(sphere->get_center())) {
137  return IF_possible | IF_some;
138  } else {
139  return IF_no_intersection;
140  }
141 }
142 
143 /**
144  *
145  */
146 int BoundingLine::
147 contains_box(const BoundingBox *box) const {
148  nassertr(!is_empty() && !is_infinite(), 0);
149  nassertr(!box->is_empty() && !box->is_infinite(), 0);
150 
151  LPoint3 center = (box->get_minq() + box->get_maxq()) * 0.5f;
152  PN_stdfloat r2 = (box->get_maxq() - box->get_minq()).length_squared() * 0.25f;
153 
154  if (r2 >= sqr_dist_to_line(center)) {
155  return IF_possible;
156  } else {
157  return IF_no_intersection;
158  }
159 }
160 
161 /**
162  *
163  */
164 PN_stdfloat BoundingLine::
165 sqr_dist_to_line(const LPoint3 &point) const {
166  nassertr(!point.is_nan(), 0.0f);
167  nassertr(!is_empty() && !is_infinite(), 0.0f);
168  nassertr(!_vector.almost_equal(LVector3(0.0f, 0.0f, 0.0f)), 0.0f);
169 
170  // The formula for the distance from a point to the line based on the
171  // quadratic equation.
172 
173  PN_stdfloat A = dot(_vector, _vector);
174  nassertr(A != 0.0f, 0.0f);
175  LVector3 fc = _origin - point;
176  PN_stdfloat B = 2.0 * dot(_vector, fc);
177  PN_stdfloat fc_d2 = dot(fc, fc);
178 
179  PN_stdfloat r2 = fc_d2 - B*B / 4.0*A;
180 
181  nassertr(!cnan(r2), 0.0f);
182  return r2;
183 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition: boundingBox.h:29
const LPoint3 & get_minq() const
An inline accessor for the minimum value.
Definition: boundingBox.I:41
const LPoint3 & get_maxq() const
An inline accessor for the maximum value.
Definition: boundingBox.I:52
This funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
Definition: boundingLine.h:29
LPoint3 get_point_b() const
Returns the second point that defines the line.
Definition: boundingLine.I:49
const LPoint3 & get_point_a() const
Returns the first point that defines the line.
Definition: boundingLine.I:39
virtual const BoundingLine * as_bounding_line() const
Virtual downcast method.
This defines a bounding sphere, consisting of a center and a radius.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
bool is_empty() const
Any kind of volume might be empty.
bool is_infinite() const
The other side of the empty coin is an infinite volume.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.