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