00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "boundingLine.h"
00020 #include "boundingSphere.h"
00021 #include "config_mathutil.h"
00022
00023 #include <math.h>
00024
00025 TypeHandle BoundingLine::_type_handle;
00026
00027 BoundingVolume *BoundingLine::
00028 make_copy() const {
00029 return new BoundingLine(*this);
00030 }
00031
00032 LPoint3f BoundingLine::
00033 get_approx_center() const {
00034 nassertr(!is_empty(), LPoint3f(0.0f, 0.0f, 0.0f));
00035 nassertr(!is_infinite(), LPoint3f(0.0f, 0.0f, 0.0f));
00036 return (get_point_a() + get_point_b()) / 2.0;
00037 }
00038
00039 void BoundingLine::
00040 xform(const LMatrix4f &mat) {
00041 nassertv(!mat.is_nan());
00042
00043 if (!is_empty() && !is_infinite()) {
00044 _origin = _origin * mat;
00045 _vector = _vector * mat;
00046 if (!_vector.normalize()) {
00047
00048
00049 _flags |= F_empty;
00050 }
00051 }
00052 }
00053
00054 void BoundingLine::
00055 output(ostream &out) const {
00056 if (is_empty()) {
00057 out << "bline, empty";
00058 } else if (is_infinite()) {
00059 out << "bline, infinite";
00060 } else {
00061 out << "bline, (" << _origin << ") - (" << _origin + _vector << ")";
00062 }
00063 }
00064
00065 bool BoundingLine::
00066 extend_other(BoundingVolume *other) const {
00067 return other->extend_by_line(this);
00068 }
00069
00070 bool BoundingLine::
00071 around_other(BoundingVolume *other,
00072 const BoundingVolume **first,
00073 const BoundingVolume **last) const {
00074 return other->around_lines(first, last);
00075 }
00076
00077 int BoundingLine::
00078 contains_other(const BoundingVolume *other) const {
00079 return other->contains_line(this);
00080 }
00081
00082
00083 bool BoundingLine::
00084 extend_by_line(const BoundingLine *line) {
00085 nassertr(!line->is_empty() && !line->is_infinite(), false);
00086 nassertr(!is_infinite(), false);
00087
00088 if (is_empty()) {
00089 _origin = line->_origin;
00090 _vector = line->_vector;
00091 _flags = 0;
00092 } else {
00093 _flags = F_infinite;
00094 }
00095 return true;
00096 }
00097
00098 int BoundingLine::
00099 contains_sphere(const BoundingSphere *sphere) const {
00100 nassertr(!is_empty() && !is_infinite(), 0);
00101 nassertr(!sphere->is_empty() && !sphere->is_infinite(), 0);
00102
00103 float r = sphere->get_radius();
00104
00105 if (r * r >= sqr_dist_to_line(sphere->get_center())) {
00106 return IF_possible | IF_some;
00107 } else {
00108 return IF_no_intersection;
00109 }
00110 }
00111
00112 float BoundingLine::
00113 sqr_dist_to_line(const LPoint3f &point) const {
00114 nassertr(!point.is_nan(), 0.0f);
00115 nassertr(!is_empty() && !is_infinite(), 0.0f);
00116 nassertr(!_vector.almost_equal(LVector3f(0.0f, 0.0f, 0.0f)), 0.0f);
00117
00118
00119
00120
00121 float A = dot(_vector, _vector);
00122 nassertr(A != 0.0f, 0.0f);
00123 LVector3f fc = _origin - point;
00124 float B = 2.0 * dot(_vector, fc);
00125 float fc_d2 = dot(fc, fc);
00126
00127 float r2 = fc_d2 - B*B / 4.0*A;
00128
00129 nassertr(!cnan(r2), 0.0f);
00130 return r2;
00131 }