00001 // Filename: boundingVolume.I 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 //////////////////////////////////////////////////////////////////// 00020 // Function: BoundingVolume::Constructor 00021 // Access: Public 00022 // Description: 00023 //////////////////////////////////////////////////////////////////// 00024 INLINE_MATHUTIL BoundingVolume:: 00025 BoundingVolume() { 00026 _flags = F_empty; 00027 } 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: BoundingVolume::is_empty 00031 // Access: Public 00032 // Description: Any kind of volume might be empty. This is a 00033 // degenerate volume that contains no points; it's not 00034 // the same as, for instance, a sphere with radius zero, 00035 // since that contains one point (the center). It 00036 // intersects with no other volumes. 00037 //////////////////////////////////////////////////////////////////// 00038 INLINE_MATHUTIL bool BoundingVolume:: 00039 is_empty() const { 00040 return (_flags & F_empty) != 0; 00041 } 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Function: BoundingVolume::is_infinite 00045 // Access: Public 00046 // Description: The other side of the empty coin is an infinite 00047 // volume. This is a degenerate state of a normally 00048 // finite volume that contains all points. (Note that 00049 // some kinds of infinite bounding volumes, like binary 00050 // separating planes, do not contain all points and thus 00051 // correctly return is_infinite() == false, even though 00052 // they are technically infinite. This is a special 00053 // case of the word 'infinite' meaning the volume covers 00054 // all points in space.) 00055 // 00056 // It completely intersects with all other volumes 00057 // except empty volumes. 00058 //////////////////////////////////////////////////////////////////// 00059 INLINE_MATHUTIL bool BoundingVolume:: 00060 is_infinite() const { 00061 return (_flags & F_infinite) != 0; 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function: BoundingVolume::set_infinite 00066 // Access: Public 00067 // Description: Marks the volume as infinite, even if it is normally 00068 // finite. You can think of this as an infinite 00069 // extend_by() operation. 00070 //////////////////////////////////////////////////////////////////// 00071 INLINE_MATHUTIL void BoundingVolume:: 00072 set_infinite() { 00073 _flags = F_infinite; 00074 } 00075 00076 //////////////////////////////////////////////////////////////////// 00077 // Function: BoundingVolume::extend_by 00078 // Access: Public 00079 // Description: Increases the size of the volume to include the given 00080 // volume. 00081 //////////////////////////////////////////////////////////////////// 00082 INLINE_MATHUTIL bool BoundingVolume:: 00083 extend_by(const BoundingVolume *vol) { 00084 if (vol->is_infinite()) { 00085 set_infinite(); 00086 00087 } else if (!vol->is_empty()) { 00088 // This is a double-dispatch. We call this virtual function on the 00089 // volume we were given, which will in turn call the appropriate 00090 // virtual function in our own class to perform the operation. 00091 return vol->extend_other(this); 00092 } 00093 return true; 00094 } 00095 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: BoundingVolume::contains 00099 // Access: Public 00100 // Description: Returns the appropriate set of IntersectionFlags to 00101 // indicate the amount of intersection with the 00102 // indicated volume. 00103 //////////////////////////////////////////////////////////////////// 00104 INLINE_MATHUTIL int BoundingVolume:: 00105 contains(const BoundingVolume *vol) const { 00106 if (is_empty() || vol->is_empty()) { 00107 return IF_no_intersection; 00108 00109 } else if (is_infinite()) { 00110 return IF_possible | IF_some | IF_all; 00111 00112 } else if (vol->is_infinite()) { 00113 return IF_possible | IF_some; 00114 } 00115 00116 // This is a double-dispatch. We call this virtual function on the 00117 // volume we were given, which will in turn call the appropriate 00118 // virtual function in our own class to perform the operation. 00119 return vol->contains_other(this); 00120 } 00121 00122 INLINE_MATHUTIL ostream &operator << (ostream &out, const BoundingVolume &bound) { 00123 bound.output(out); 00124 return out; 00125 }