Panda3D
 All Classes Functions Variables Enumerations
boundingPlane.cxx
00001 // Filename: boundingPlane.cxx
00002 // Created by:  drose (19Aug05)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "boundingPlane.h"
00016 #include "boundingSphere.h"
00017 #include "config_mathutil.h"
00018 
00019 TypeHandle BoundingPlane::_type_handle;
00020 
00021 ////////////////////////////////////////////////////////////////////
00022 //     Function: BoundingPlane::make_copy
00023 //       Access: Public, Virtual
00024 //  Description: 
00025 ////////////////////////////////////////////////////////////////////
00026 BoundingVolume *BoundingPlane::
00027 make_copy() const {
00028   return new BoundingPlane(*this);
00029 }
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: BoundingPlane::get_approx_center
00033 //       Access: Public, Virtual
00034 //  Description: 
00035 ////////////////////////////////////////////////////////////////////
00036 LPoint3 BoundingPlane::
00037 get_approx_center() const {
00038   nassertr(!is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
00039   nassertr(!is_infinite(), LPoint3(0.0f, 0.0f, 0.0f));
00040   return _plane.get_point();
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: BoundingPlane::xform
00045 //       Access: Public, Virtual
00046 //  Description: 
00047 ////////////////////////////////////////////////////////////////////
00048 void BoundingPlane::
00049 xform(const LMatrix4 &mat) {
00050   nassertv(!mat.is_nan());
00051 
00052   if (!is_empty() && !is_infinite()) {
00053     _plane.xform(mat);
00054   }
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: BoundingPlane::output
00059 //       Access: Public, Virtual
00060 //  Description: 
00061 ////////////////////////////////////////////////////////////////////
00062 void BoundingPlane::
00063 output(ostream &out) const {
00064   if (is_empty()) {
00065     out << "bplane, empty";
00066   } else if (is_infinite()) {
00067     out << "bplane, infinite";
00068   } else {
00069     out << "bplane: " << _plane;
00070   }
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: BoundingPlane::as_bounding_plane
00075 //       Access: Public, Virtual
00076 //  Description: Virtual downcast method.  Returns this object as a
00077 //               pointer of the indicated type, if it is in fact that
00078 //               type.  Returns NULL if it is not that type.
00079 ////////////////////////////////////////////////////////////////////
00080 const BoundingPlane *BoundingPlane::
00081 as_bounding_plane() const {
00082   return this;
00083 }
00084 
00085 ////////////////////////////////////////////////////////////////////
00086 //     Function: BoundingPlane::extend_other
00087 //       Access: Public, Virtual
00088 //  Description: 
00089 ////////////////////////////////////////////////////////////////////
00090 bool BoundingPlane::
00091 extend_other(BoundingVolume *other) const {
00092   return other->extend_by_plane(this);
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: BoundingPlane::around_other
00097 //       Access: Public, Virtual
00098 //  Description: 
00099 ////////////////////////////////////////////////////////////////////
00100 bool BoundingPlane::
00101 around_other(BoundingVolume *other,
00102              const BoundingVolume **first,
00103              const BoundingVolume **last) const {
00104   return other->around_planes(first, last);
00105 }
00106 
00107 ////////////////////////////////////////////////////////////////////
00108 //     Function: BoundingPlane::contains_other
00109 //       Access: Public, Virtual
00110 //  Description: 
00111 ////////////////////////////////////////////////////////////////////
00112 int BoundingPlane::
00113 contains_other(const BoundingVolume *other) const {
00114   return other->contains_plane(this);
00115 }
00116 
00117 ////////////////////////////////////////////////////////////////////
00118 //     Function: BoundingPlane::extend_by_plane
00119 //       Access: Public, Virtual
00120 //  Description: 
00121 ////////////////////////////////////////////////////////////////////
00122 bool BoundingPlane::
00123 extend_by_plane(const BoundingPlane *plane) {
00124   nassertr(!plane->is_empty() && !plane->is_infinite(), false);
00125   nassertr(!is_infinite(), false);
00126 
00127   if (is_empty()) {
00128     _plane = plane->get_plane();
00129     _flags = 0;
00130   } else {
00131     _flags = F_infinite;
00132   }
00133   return true;
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: BoundingPlane::contains_sphere
00138 //       Access: Public, Virtual
00139 //  Description: 
00140 ////////////////////////////////////////////////////////////////////
00141 int BoundingPlane::
00142 contains_sphere(const BoundingSphere *sphere) const {
00143   nassertr(!is_empty() && !is_infinite(), 0);
00144   nassertr(!sphere->is_empty() && !sphere->is_infinite(), 0);
00145 
00146   PN_stdfloat r = sphere->get_radius();
00147   PN_stdfloat d = _plane.dist_to_plane(sphere->get_center());
00148 
00149   if (d <= -r) {
00150     // The sphere is completely behind the plane.
00151     return IF_all | IF_possible | IF_some;
00152 
00153   } else if (d <= r) {
00154     // The sphere is intersecting with the plane itself.
00155     return IF_possible | IF_some;
00156 
00157   } else {
00158     // The sphere is completely in front of the plane.
00159     return IF_no_intersection;
00160   }
00161 }
00162 
00163 ////////////////////////////////////////////////////////////////////
00164 //     Function: BoundingPlane::contains_box
00165 //       Access: Public, Virtual
00166 //  Description: 
00167 ////////////////////////////////////////////////////////////////////
00168 int BoundingPlane::
00169 contains_box(const BoundingBox *box) const {
00170   nassertr(!is_empty() && !is_infinite(), 0);
00171   nassertr(!box->is_empty() && !box->is_infinite(), 0);
00172 
00173   // Put the box inside a sphere for the purpose of this test.
00174   const LPoint3 &min = box->get_minq();
00175   const LPoint3 &max = box->get_maxq();
00176   LPoint3 center = (min + max) * 0.5f;
00177   PN_stdfloat radius2 = (max - center).length_squared();
00178 
00179   int result = IF_possible | IF_some | IF_all;
00180 
00181   PN_stdfloat dist = _plane.dist_to_plane(center);
00182   PN_stdfloat dist2 = dist * dist;
00183 
00184   if (dist2 <= radius2) {
00185     // The sphere is not completely behind this plane, but some of
00186     // it is.
00187     
00188     // Look a little closer.
00189     bool all_in = true;
00190     bool all_out = true;
00191     for (int i = 0; i < 8 && (all_in || all_out) ; ++i) {
00192       if (_plane.dist_to_plane(box->get_point(i)) < 0.0f) {
00193         // This point is inside the plane.
00194         all_out = false;
00195       } else {
00196         // This point is outside the plane.
00197         all_in = false;
00198       }
00199     }
00200     
00201     if (all_out) {
00202       return IF_no_intersection;
00203     } else if (!all_in) {
00204       result &= ~IF_all;
00205     }
00206     
00207   } else if (dist >= 0.0f) {
00208     // The sphere is completely in front of this plane.
00209     return IF_no_intersection;
00210   }
00211 
00212   return result;
00213 }
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: BoundingPlane::contains_line
00217 //       Access: Public, Virtual
00218 //  Description: 
00219 ////////////////////////////////////////////////////////////////////
00220 int BoundingPlane::
00221 contains_line(const BoundingLine *line) const {
00222   return IF_possible;
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: BoundingPlane::contains_plane
00227 //       Access: Public, Virtual
00228 //  Description: 
00229 ////////////////////////////////////////////////////////////////////
00230 int BoundingPlane::
00231 contains_plane(const BoundingPlane *plane) const {
00232   return IF_possible;
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: BoundingPlane::contains_hexahedron
00237 //       Access: Protected, Virtual
00238 //  Description: Double-dispatch support: called by contains_other()
00239 //               when the type we're testing for intersection is known
00240 //               to be a hexahedron.
00241 ////////////////////////////////////////////////////////////////////
00242 int BoundingPlane::
00243 contains_hexahedron(const BoundingHexahedron *hexahedron) const {
00244   nassertr(!is_empty() && !is_infinite(), 0);
00245   nassertr(!hexahedron->is_empty() && !hexahedron->is_infinite(), 0);
00246 
00247   int result = IF_possible | IF_some | IF_all;
00248 
00249   bool all_in = true;
00250   bool all_out = true;
00251   for (int i = 0; i < 8 && (all_in || all_out) ; ++i) {
00252     if (_plane.dist_to_plane(hexahedron->get_point(i)) < 0.0f) {
00253       // This point is inside the plane.
00254       all_out = false;
00255     } else {
00256       // This point is outside the plane.
00257       all_in = false;
00258     }
00259   }
00260     
00261   if (all_out) {
00262     return IF_no_intersection;
00263   } else if (!all_in) {
00264     result &= ~IF_all;
00265   }
00266 
00267   return result;
00268 }
 All Classes Functions Variables Enumerations