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  */
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 }
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition: boundingBox.h:29
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_empty() const
Any kind of volume might be empty.
This defines a bounding sphere, consisting of a center and a radius.
bool is_infinite() const
The other side of the empty coin is an infinite volume.
virtual const BoundingLine * as_bounding_line() const
Virtual downcast method.
const LPoint3 & get_point_a() const
Returns the first point that defines the line.
Definition: boundingLine.I:39
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LPoint3 & get_maxq() const
An inline accessor for the maximum value.
Definition: boundingBox.I:52
LPoint3 get_point_b() const
Returns the second point that defines the line.
Definition: boundingLine.I:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
Definition: boundingLine.h:29
const LPoint3 & get_minq() const
An inline accessor for the minimum value.
Definition: boundingBox.I:41