00001 // Filename: boundingVolume.cxx 00002 // Created by: drose (01Oct99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "boundingVolume.h" 00020 #include "finiteBoundingVolume.h" 00021 00022 #include <indent.h> 00023 00024 TypeHandle BoundingVolume::_type_handle; 00025 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: BoundingVolume::around 00029 // Access: Public 00030 // Description: Resets the volume to enclose only the volumes 00031 // indicated. Returns true if successful, false if the 00032 // volume doesn't know how to do that or can't do that. 00033 //////////////////////////////////////////////////////////////////// 00034 bool BoundingVolume:: 00035 around(const BoundingVolume **first, const BoundingVolume **last) { 00036 _flags = F_empty; 00037 00038 // Skip any empty volumes at the beginning of the list. We want to 00039 // get to the first real volume. 00040 while (first != last && (*first)->is_empty()) { 00041 if ((*first)->is_infinite()) { 00042 // If we go around an infinite volume, we're infinite too. 00043 _flags = F_infinite; 00044 return true; 00045 } 00046 ++first; 00047 } 00048 00049 bool okflag = true; 00050 00051 if (first != last) { 00052 // Check for more infinite bounding volumes in the list. 00053 const BoundingVolume **bvi; 00054 for (bvi = first; bvi != last; ++bvi) { 00055 if ((*bvi)->is_infinite()) { 00056 _flags = F_infinite; 00057 return true; 00058 } 00059 } 00060 00061 // This is a double-dispatch. We call this virtual function on 00062 // the volume we were given, which will in turn call the 00063 // appropriate virtual function in our own class to perform the 00064 // operation. 00065 if (!(*first)->around_other(this, first, last)) { 00066 okflag = false; 00067 } 00068 } 00069 00070 return okflag; 00071 } 00072 00073 //////////////////////////////////////////////////////////////////// 00074 // Function: BoundingVolume::write 00075 // Access: Public 00076 // Description: 00077 //////////////////////////////////////////////////////////////////// 00078 void BoundingVolume:: 00079 write(ostream &out, int indent_level) const { 00080 indent(out, indent_level) << *this << "\n"; 00081 } 00082 00083 //////////////////////////////////////////////////////////////////// 00084 // Function: BoundingVolume::extend_by_sphere 00085 // Access: Protected, Virtual 00086 // Description: Double-dispatch support: called by extend_other() 00087 // when the type we're extending by is known to be a 00088 // sphere. 00089 //////////////////////////////////////////////////////////////////// 00090 bool BoundingVolume:: 00091 extend_by_sphere(const BoundingSphere *) { 00092 _flags = F_infinite; 00093 return false; 00094 } 00095 00096 //////////////////////////////////////////////////////////////////// 00097 // Function: BoundingVolume::extend_by_hexahedron 00098 // Access: Protected, Virtual 00099 // Description: Double-dispatch support: called by extend_other() 00100 // when the type we're extending by is known to be a 00101 // hexahedron. 00102 //////////////////////////////////////////////////////////////////// 00103 bool BoundingVolume:: 00104 extend_by_hexahedron(const BoundingHexahedron *) { 00105 _flags = F_infinite; 00106 return false; 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: BoundingVolume::extend_by_line 00111 // Access: Protected, Virtual 00112 // Description: Double-dispatch support: called by extend_other() 00113 // when the type we're extending by is known to be a 00114 // line. 00115 //////////////////////////////////////////////////////////////////// 00116 bool BoundingVolume:: 00117 extend_by_line(const BoundingLine *) { 00118 _flags = F_infinite; 00119 return false; 00120 } 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Function: BoundingVolume::around_spheres 00124 // Access: Protected, Virtual 00125 // Description: Double-dispatch support: called by around_other() 00126 // when the type of the first element in the list is 00127 // known to be a nonempty sphere. 00128 //////////////////////////////////////////////////////////////////// 00129 bool BoundingVolume:: 00130 around_spheres(const BoundingVolume **, const BoundingVolume **) { 00131 _flags = F_infinite; 00132 return false; 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function: BoundingVolume::around_hexahedrons 00137 // Access: Protected, Virtual 00138 // Description: Double-dispatch support: called by around_other() 00139 // when the type of the first element in the list is 00140 // known to be a nonempty hexahedron. 00141 //////////////////////////////////////////////////////////////////// 00142 bool BoundingVolume:: 00143 around_hexahedrons(const BoundingVolume **, const BoundingVolume **) { 00144 _flags = F_infinite; 00145 return false; 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: BoundingVolume::around_lines 00150 // Access: Protected, Virtual 00151 // Description: Double-dispatch support: called by around_other() 00152 // when the type of the first element in the list is 00153 // known to be a nonempty line. 00154 //////////////////////////////////////////////////////////////////// 00155 bool BoundingVolume:: 00156 around_lines(const BoundingVolume **, const BoundingVolume **) { 00157 _flags = F_infinite; 00158 if (is_of_type(FiniteBoundingVolume::get_class_type())) { 00159 // If it's a FiniteBoundingVolume, we can't do any better than 00160 // making it infinite. So we return true. 00161 return true; 00162 } 00163 00164 // Otherwise, we might do better, and we require each class to 00165 // define a function. If we get here, the function isn't defined, 00166 // so we return false to indicate this. 00167 return false; 00168 } 00169 00170 //////////////////////////////////////////////////////////////////// 00171 // Function: BoundingVolume::contains_sphere 00172 // Access: Protected, Virtual 00173 // Description: Double-dispatch support: called by contains_other() 00174 // when the type we're testing for intersection is known 00175 // to be a sphere. 00176 //////////////////////////////////////////////////////////////////// 00177 int BoundingVolume:: 00178 contains_sphere(const BoundingSphere *) const { 00179 return IF_dont_understand; 00180 } 00181 00182 //////////////////////////////////////////////////////////////////// 00183 // Function: BoundingVolume::contains_hexahedron 00184 // Access: Protected, Virtual 00185 // Description: Double-dispatch support: called by contains_other() 00186 // when the type we're testing for intersection is known 00187 // to be a hexahedron. 00188 //////////////////////////////////////////////////////////////////// 00189 int BoundingVolume:: 00190 contains_hexahedron(const BoundingHexahedron *) const { 00191 return IF_dont_understand; 00192 } 00193 00194 //////////////////////////////////////////////////////////////////// 00195 // Function: BoundingVolume::contains_line 00196 // Access: Protected, Virtual 00197 // Description: Double-dispatch support: called by contains_other() 00198 // when the type we're testing for intersection is known 00199 // to be a line. 00200 //////////////////////////////////////////////////////////////////// 00201 int BoundingVolume:: 00202 contains_line(const BoundingLine *) const { 00203 return IF_dont_understand; 00204 }