Panda3D
|
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