Panda3D

boundingVolume.cxx

00001 // Filename: boundingVolume.cxx
00002 // Created by:  drose (01Oct99)
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 "boundingVolume.h"
00016 #include "finiteBoundingVolume.h"
00017 
00018 #include "indent.h"
00019 
00020 TypeHandle BoundingVolume::_type_handle;
00021 
00022 
00023 ////////////////////////////////////////////////////////////////////
00024 //     Function: BoundingVolume::around
00025 //       Access: Published
00026 //  Description: Resets the volume to enclose only the volumes
00027 //               indicated.  Returns true if successful, false if the
00028 //               volume doesn't know how to do that or can't do that.
00029 ////////////////////////////////////////////////////////////////////
00030 bool BoundingVolume::
00031 around(const BoundingVolume **first, const BoundingVolume **last) {
00032   _flags = F_empty;
00033 
00034   // Skip any empty volumes at the beginning of the list.  We want to
00035   // get to the first real volume.
00036   while (first != last && (*first)->is_empty()) {
00037     if ((*first)->is_infinite()) {
00038       // If we go around an infinite volume, we're infinite too.
00039       _flags = F_infinite;
00040       return true;
00041     }
00042     ++first;
00043   }
00044 
00045   bool okflag = true;
00046 
00047   if (first != last) {
00048     // Check for more infinite bounding volumes in the list.
00049     const BoundingVolume **bvi;
00050     for (bvi = first; bvi != last; ++bvi) {
00051       if ((*bvi)->is_infinite()) {
00052         _flags = F_infinite;
00053         return true;
00054       }
00055     }
00056 
00057     // This is a double-dispatch.  We call this virtual function on
00058     // the volume we were given, which will in turn call the
00059     // appropriate virtual function in our own class to perform the
00060     // operation.
00061     if (!(*first)->around_other(this, first, last)) {
00062       okflag = false;
00063     }
00064   }
00065 
00066   return okflag;
00067 }
00068 
00069 ////////////////////////////////////////////////////////////////////
00070 //     Function: BoundingVolume::write
00071 //       Access: Published
00072 //  Description:
00073 ////////////////////////////////////////////////////////////////////
00074 void BoundingVolume::
00075 write(ostream &out, int indent_level) const {
00076   indent(out, indent_level) << *this << "\n";
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: BoundingVolume::as_geometric_bounding_volume
00081 //       Access: Public, Virtual
00082 //  Description: Virtual downcast method.  Returns this object as a
00083 //               pointer of the indicated type, if it is in fact that
00084 //               type.  Returns NULL if it is not that type.
00085 ////////////////////////////////////////////////////////////////////
00086 const GeometricBoundingVolume *BoundingVolume::
00087 as_geometric_bounding_volume() const {
00088   return NULL;
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: BoundingVolume::as_finite_bounding_volume
00093 //       Access: Public, Virtual
00094 //  Description: Virtual downcast method.  Returns this object as a
00095 //               pointer of the indicated type, if it is in fact that
00096 //               type.  Returns NULL if it is not that type.
00097 ////////////////////////////////////////////////////////////////////
00098 const FiniteBoundingVolume *BoundingVolume::
00099 as_finite_bounding_volume() const {
00100   return NULL;
00101 }
00102 
00103 ////////////////////////////////////////////////////////////////////
00104 //     Function: BoundingVolume::as_bounding_sphere
00105 //       Access: Public, Virtual
00106 //  Description: Virtual downcast method.  Returns this object as a
00107 //               pointer of the indicated type, if it is in fact that
00108 //               type.  Returns NULL if it is not that type.
00109 ////////////////////////////////////////////////////////////////////
00110 const BoundingSphere *BoundingVolume::
00111 as_bounding_sphere() const {
00112   return NULL;
00113 }
00114 
00115 ////////////////////////////////////////////////////////////////////
00116 //     Function: BoundingVolume::as_bounding_box
00117 //       Access: Public, Virtual
00118 //  Description: Virtual downcast method.  Returns this object as a
00119 //               pointer of the indicated type, if it is in fact that
00120 //               type.  Returns NULL if it is not that type.
00121 ////////////////////////////////////////////////////////////////////
00122 const BoundingBox *BoundingVolume::
00123 as_bounding_box() const {
00124   return NULL;
00125 }
00126 
00127 ////////////////////////////////////////////////////////////////////
00128 //     Function: BoundingVolume::as_bounding_hexahedron
00129 //       Access: Public, Virtual
00130 //  Description: Virtual downcast method.  Returns this object as a
00131 //               pointer of the indicated type, if it is in fact that
00132 //               type.  Returns NULL if it is not that type.
00133 ////////////////////////////////////////////////////////////////////
00134 const BoundingHexahedron *BoundingVolume::
00135 as_bounding_hexahedron() const {
00136   return NULL;
00137 }
00138 
00139 ////////////////////////////////////////////////////////////////////
00140 //     Function: BoundingVolume::as_bounding_line
00141 //       Access: Public, Virtual
00142 //  Description: Virtual downcast method.  Returns this object as a
00143 //               pointer of the indicated type, if it is in fact that
00144 //               type.  Returns NULL if it is not that type.
00145 ////////////////////////////////////////////////////////////////////
00146 const BoundingLine *BoundingVolume::
00147 as_bounding_line() const {
00148   return NULL;
00149 }
00150 
00151 ////////////////////////////////////////////////////////////////////
00152 //     Function: BoundingVolume::as_bounding_plane
00153 //       Access: Public, Virtual
00154 //  Description: Virtual downcast method.  Returns this object as a
00155 //               pointer of the indicated type, if it is in fact that
00156 //               type.  Returns NULL if it is not that type.
00157 ////////////////////////////////////////////////////////////////////
00158 const BoundingPlane *BoundingVolume::
00159 as_bounding_plane() const {
00160   return NULL;
00161 }
00162 
00163 ////////////////////////////////////////////////////////////////////
00164 //     Function: BoundingVolume::string_bounds_type
00165 //       Access: Public, Static
00166 //  Description: Returns the BoundsType corresponding to the indicated
00167 //               string.
00168 ////////////////////////////////////////////////////////////////////
00169 BoundingVolume::BoundsType BoundingVolume::
00170 string_bounds_type(const string &str) {
00171   if (strcmp(str.c_str(), "default") == 0) {
00172     return BT_default;
00173 
00174   } else if (strcmp(str.c_str(), "best") == 0) {
00175     return BT_best;
00176 
00177   } else if (strcmp(str.c_str(), "sphere") == 0) {
00178     return BT_sphere;
00179 
00180   } else if (strcmp(str.c_str(), "box") == 0) {
00181     return BT_box;
00182   }
00183 
00184   return BT_default;
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: BoundingVolume::extend_by_sphere
00189 //       Access: Protected, Virtual
00190 //  Description: Double-dispatch support: called by extend_other()
00191 //               when the type we're extending by is known to be a
00192 //               sphere.
00193 ////////////////////////////////////////////////////////////////////
00194 bool BoundingVolume::
00195 extend_by_sphere(const BoundingSphere *) {
00196   mathutil_cat.warning()
00197     << get_type() << "::extend_by_sphere() called\n";
00198   _flags = F_infinite;
00199   return false;
00200 }
00201 
00202 ////////////////////////////////////////////////////////////////////
00203 //     Function: BoundingVolume::extend_by_box
00204 //       Access: Protected, Virtual
00205 //  Description: Double-dispatch support: called by extend_other()
00206 //               when the type we're extending by is known to be a
00207 //               box.
00208 ////////////////////////////////////////////////////////////////////
00209 bool BoundingVolume::
00210 extend_by_box(const BoundingBox *) {
00211   mathutil_cat.warning()
00212     << get_type() << "::extend_by_box() called\n";
00213   _flags = F_infinite;
00214   return false;
00215 }
00216 
00217 ////////////////////////////////////////////////////////////////////
00218 //     Function: BoundingVolume::extend_by_hexahedron
00219 //       Access: Protected, Virtual
00220 //  Description: Double-dispatch support: called by extend_other()
00221 //               when the type we're extending by is known to be a
00222 //               hexahedron.
00223 ////////////////////////////////////////////////////////////////////
00224 bool BoundingVolume::
00225 extend_by_hexahedron(const BoundingHexahedron *) {
00226   mathutil_cat.warning()
00227     << get_type() << "::extend_by_hexahedron() called\n";
00228   _flags = F_infinite;
00229   return false;
00230 }
00231 
00232 ////////////////////////////////////////////////////////////////////
00233 //     Function: BoundingVolume::extend_by_line
00234 //       Access: Protected, Virtual
00235 //  Description: Double-dispatch support: called by extend_other()
00236 //               when the type we're extending by is known to be a
00237 //               line.
00238 ////////////////////////////////////////////////////////////////////
00239 bool BoundingVolume::
00240 extend_by_line(const BoundingLine *) {
00241   mathutil_cat.warning()
00242     << get_type() << "::extend_by_line() called\n";
00243   _flags = F_infinite;
00244   return false;
00245 }
00246 
00247 ////////////////////////////////////////////////////////////////////
00248 //     Function: BoundingVolume::extend_by_plane
00249 //       Access: Protected, Virtual
00250 //  Description: Double-dispatch support: called by extend_other()
00251 //               when the type we're extending by is known to be a
00252 //               plane.
00253 ////////////////////////////////////////////////////////////////////
00254 bool BoundingVolume::
00255 extend_by_plane(const BoundingPlane *) {
00256   mathutil_cat.warning()
00257     << get_type() << "::extend_by_plane() called\n";
00258   _flags = F_infinite;
00259   return false;
00260 }
00261 
00262 ////////////////////////////////////////////////////////////////////
00263 //     Function: BoundingVolume::around_spheres
00264 //       Access: Protected, Virtual
00265 //  Description: Double-dispatch support: called by around_other()
00266 //               when the type of the first element in the list is
00267 //               known to be a nonempty sphere.
00268 ////////////////////////////////////////////////////////////////////
00269 bool BoundingVolume::
00270 around_spheres(const BoundingVolume **, const BoundingVolume **) {
00271   mathutil_cat.warning()
00272     << get_type() << "::around_spheres() called\n";
00273   _flags = F_infinite;
00274   return false;
00275 }
00276 
00277 ////////////////////////////////////////////////////////////////////
00278 //     Function: BoundingVolume::around_boxes
00279 //       Access: Protected, Virtual
00280 //  Description: Double-dispatch support: called by around_other()
00281 //               when the type of the first element in the list is
00282 //               known to be a nonempty box.
00283 ////////////////////////////////////////////////////////////////////
00284 bool BoundingVolume::
00285 around_boxes(const BoundingVolume **, const BoundingVolume **) {
00286   mathutil_cat.warning()
00287     << get_type() << "::around_boxes() called\n";
00288   _flags = F_infinite;
00289   return false;
00290 }
00291 
00292 ////////////////////////////////////////////////////////////////////
00293 //     Function: BoundingVolume::around_hexahedrons
00294 //       Access: Protected, Virtual
00295 //  Description: Double-dispatch support: called by around_other()
00296 //               when the type of the first element in the list is
00297 //               known to be a nonempty hexahedron.
00298 ////////////////////////////////////////////////////////////////////
00299 bool BoundingVolume::
00300 around_hexahedrons(const BoundingVolume **, const BoundingVolume **) {
00301   mathutil_cat.warning()
00302     << get_type() << "::around_hexahedrons() called\n";
00303   _flags = F_infinite;
00304   return false;
00305 }
00306 
00307 ////////////////////////////////////////////////////////////////////
00308 //     Function: BoundingVolume::around_lines
00309 //       Access: Protected, Virtual
00310 //  Description: Double-dispatch support: called by around_other()
00311 //               when the type of the first element in the list is
00312 //               known to be a nonempty line.
00313 ////////////////////////////////////////////////////////////////////
00314 bool BoundingVolume::
00315 around_lines(const BoundingVolume **, const BoundingVolume **) {
00316   _flags = F_infinite;
00317 
00318   mathutil_cat.warning()
00319     << get_type() << "::around_lines() called\n";
00320 
00321   // If we get here, the function isn't defined by a subclass, so we
00322   // return false to indicate this.
00323   return false;
00324 }
00325 
00326 ////////////////////////////////////////////////////////////////////
00327 //     Function: BoundingVolume::around_planes
00328 //       Access: Protected, Virtual
00329 //  Description: Double-dispatch support: called by around_other()
00330 //               when the type of the first element in the list is
00331 //               known to be a nonempty plane.
00332 ////////////////////////////////////////////////////////////////////
00333 bool BoundingVolume::
00334 around_planes(const BoundingVolume **, const BoundingVolume **) {
00335   _flags = F_infinite;
00336 
00337   mathutil_cat.warning()
00338     << get_type() << "::around_planes() called\n";
00339 
00340   // If we get here, the function isn't defined by a subclass, so we
00341   // return false to indicate this.
00342   return false;
00343 }
00344 
00345 ////////////////////////////////////////////////////////////////////
00346 //     Function: BoundingVolume::contains_sphere
00347 //       Access: Protected, Virtual
00348 //  Description: Double-dispatch support: called by contains_other()
00349 //               when the type we're testing for intersection is known
00350 //               to be a sphere.
00351 ////////////////////////////////////////////////////////////////////
00352 int BoundingVolume::
00353 contains_sphere(const BoundingSphere *) const {
00354   mathutil_cat.warning()
00355     << get_type() << "::contains_sphere() called\n";
00356   return IF_dont_understand;
00357 }
00358 
00359 ////////////////////////////////////////////////////////////////////
00360 //     Function: BoundingVolume::contains_box
00361 //       Access: Protected, Virtual
00362 //  Description: Double-dispatch support: called by contains_other()
00363 //               when the type we're testing for intersection is known
00364 //               to be a box.
00365 ////////////////////////////////////////////////////////////////////
00366 int BoundingVolume::
00367 contains_box(const BoundingBox *) const {
00368   mathutil_cat.warning()
00369     << get_type() << "::contains_box() called\n";
00370   return IF_dont_understand;
00371 }
00372 
00373 ////////////////////////////////////////////////////////////////////
00374 //     Function: BoundingVolume::contains_hexahedron
00375 //       Access: Protected, Virtual
00376 //  Description: Double-dispatch support: called by contains_other()
00377 //               when the type we're testing for intersection is known
00378 //               to be a hexahedron.
00379 ////////////////////////////////////////////////////////////////////
00380 int BoundingVolume::
00381 contains_hexahedron(const BoundingHexahedron *) const {
00382   mathutil_cat.warning()
00383     << get_type() << "::contains_hexahedron() called\n";
00384   return IF_dont_understand;
00385 }
00386 
00387 ////////////////////////////////////////////////////////////////////
00388 //     Function: BoundingVolume::contains_line
00389 //       Access: Protected, Virtual
00390 //  Description: Double-dispatch support: called by contains_other()
00391 //               when the type we're testing for intersection is known
00392 //               to be a line.
00393 ////////////////////////////////////////////////////////////////////
00394 int BoundingVolume::
00395 contains_line(const BoundingLine *) const {
00396   mathutil_cat.warning()
00397     << get_type() << "::contains_line() called\n";
00398   return IF_dont_understand;
00399 }
00400 
00401 ////////////////////////////////////////////////////////////////////
00402 //     Function: BoundingVolume::contains_plane
00403 //       Access: Protected, Virtual
00404 //  Description: Double-dispatch support: called by contains_other()
00405 //               when the type we're testing for intersection is known
00406 //               to be a plane.
00407 ////////////////////////////////////////////////////////////////////
00408 int BoundingVolume::
00409 contains_plane(const BoundingPlane *) const {
00410   mathutil_cat.warning()
00411     << get_type() << "::contains_plane() called\n";
00412   return IF_dont_understand;
00413 }
00414 
00415 ostream &
00416 operator << (ostream &out, BoundingVolume::BoundsType type) {
00417   switch (type) {
00418   case BoundingVolume::BT_default:
00419     return out << "default";
00420 
00421   case BoundingVolume::BT_best:
00422     return out << "best";
00423 
00424   case BoundingVolume::BT_sphere:
00425     return out << "sphere";
00426 
00427   case BoundingVolume::BT_box:
00428     return out << "box";
00429   }
00430 
00431   mathutil_cat.error()
00432     << "Invalid BoundingVolume::BoundsType value: " << (int)type << "\n";
00433   nassertr(false, out);
00434   return out;
00435 }
00436 
00437 istream &
00438 operator >> (istream &in, BoundingVolume::BoundsType &type) {
00439   string word;
00440   in >> word;
00441   type = BoundingVolume::string_bounds_type(word);
00442   if (type == BoundingVolume::BT_default) {
00443     mathutil_cat->error()
00444       << "Invalid BoundingVolume::BoundsType string: " << word << "\n";
00445   }
00446   return in;
00447 }
00448 
 All Classes Functions Variables Enumerations