00001 // Filename: boundedObject.I 00002 // Created by: drose (02Oct99) 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 //////////////////////////////////////////////////////////////////// 00021 // Function: BoundedObject::CData::Constructor 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 INLINE BoundedObject::CData:: 00026 CData() { 00027 _bound_type = BoundedObject::BVT_dynamic_sphere; 00028 _flags = F_bound_stale; 00029 } 00030 00031 //////////////////////////////////////////////////////////////////// 00032 // Function: BoundedObject::CData::Copy Constructor 00033 // Access: Public 00034 // Description: 00035 //////////////////////////////////////////////////////////////////// 00036 INLINE BoundedObject::CData:: 00037 CData(const BoundedObject::CData ©) : 00038 _flags(copy._flags), 00039 _bound_type(copy._bound_type), 00040 _bound(copy._bound) 00041 { 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: BoundedObject::CData::Copy Assignment Operator 00046 // Access: Public 00047 // Description: 00048 //////////////////////////////////////////////////////////////////// 00049 INLINE void BoundedObject::CData:: 00050 operator = (const BoundedObject::CData ©) { 00051 _flags = copy._flags; 00052 _bound_type = copy._bound_type; 00053 _bound = copy._bound; 00054 } 00055 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: BoundedObject::Constructor 00059 // Access: Published 00060 // Description: 00061 //////////////////////////////////////////////////////////////////// 00062 INLINE BoundedObject:: 00063 BoundedObject() { 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: BoundedObject::Copy Constructor 00068 // Access: Published 00069 // Description: 00070 //////////////////////////////////////////////////////////////////// 00071 INLINE BoundedObject:: 00072 BoundedObject(const BoundedObject ©) : 00073 _cycler(copy._cycler) 00074 { 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: BoundedObject::Copy Assignment Operator 00079 // Access: Published 00080 // Description: 00081 //////////////////////////////////////////////////////////////////// 00082 INLINE void BoundedObject:: 00083 operator = (const BoundedObject ©) { 00084 _cycler = copy._cycler; 00085 } 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: BoundedObject::set_bound 00089 // Access: Published 00090 // Description: Sets the type of the bounding volume that will be 00091 // dynamically computed for this particular node. 00092 // Presently, this should only be BVT_dynamic_sphere. 00093 //////////////////////////////////////////////////////////////////// 00094 INLINE void BoundedObject:: 00095 set_bound(BoundedObject::BoundingVolumeType type) { 00096 nassertv(type != BVT_static); 00097 mark_bound_stale(); 00098 CDWriter cdata(_cycler); 00099 cdata->_bound_type = type; 00100 } 00101 00102 //////////////////////////////////////////////////////////////////// 00103 // Function: BoundedObject::set_bound 00104 // Access: Published 00105 // Description: Explicitly sets a new bounding volume on this node. 00106 // This will be a static bounding volume that will no 00107 // longer be recomputed automatically. 00108 //////////////////////////////////////////////////////////////////// 00109 INLINE void BoundedObject:: 00110 set_bound(const BoundingVolume &bound) { 00111 mark_bound_stale(); 00112 CDWriter cdata(_cycler); 00113 cdata->_bound_type = BVT_static; 00114 cdata->_flags &= ~F_bound_stale; 00115 cdata->_bound = bound.make_copy(); 00116 } 00117 00118 //////////////////////////////////////////////////////////////////// 00119 // Function: BoundedObject::mark_bound_stale 00120 // Access: Published 00121 // Description: Marks the current bounding volume as stale, so that 00122 // it will be recomputed later. This may have a 00123 // cascading effect up to the root of all graphs of 00124 // which the node is a part. Returns true if the 00125 // setting was changed, or false if it was already 00126 // marked stale (or if it is a static bounding volume). 00127 //////////////////////////////////////////////////////////////////// 00128 INLINE bool BoundedObject:: 00129 mark_bound_stale() { 00130 if (is_bound_stale()) { 00131 return false; 00132 } 00133 { 00134 CDWriter cdata(_cycler); 00135 cdata->_flags |= F_bound_stale; 00136 } 00137 propagate_stale_bound(); 00138 00139 return true; 00140 } 00141 00142 //////////////////////////////////////////////////////////////////// 00143 // Function: BoundedObject::force_bound_stale 00144 // Access: Published 00145 // Description: Marks the current volume as stale and propagates the 00146 // effect at least one level, even if it had already 00147 // been marked stale. 00148 //////////////////////////////////////////////////////////////////// 00149 INLINE void BoundedObject:: 00150 force_bound_stale() { 00151 { 00152 CDWriter cdata(_cycler); 00153 cdata->_flags |= F_bound_stale; 00154 } 00155 propagate_stale_bound(); 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: BoundedObject::is_bound_stale 00160 // Access: Published 00161 // Description: Returns true if the bound is currently marked stale 00162 // and will be recomputed the next time get_bound() is 00163 // called. 00164 // 00165 // This function is defined up at the top of this file, 00166 // because several of the inline functions below 00167 // reference it. 00168 //////////////////////////////////////////////////////////////////// 00169 INLINE bool BoundedObject:: 00170 is_bound_stale() const { 00171 CDReader cdata(_cycler); 00172 return (cdata->_flags & F_bound_stale) != 0; 00173 } 00174 00175 00176 //////////////////////////////////////////////////////////////////// 00177 // Function: BoundedObject::set_final 00178 // Access: Published 00179 // Description: Sets the "final" flag on this BoundedObject. If 00180 // this is true, than no bounding volume need be tested 00181 // below it; a positive intersection with this bounding 00182 // volume is deemed to be a positive intersection with 00183 // all geometry inside. 00184 // 00185 // This is useful to quickly force a larger bounding 00186 // volume around a node when the GeomNodes themselves 00187 // are inaccurate for some reason, without forcing a 00188 // recompute of every nested bounding volume. It's also 00189 // helpful when the bounding volume is tricked by some 00190 // special properties, like billboards, that may move 00191 // geometry out of its bounding volume otherwise. 00192 //////////////////////////////////////////////////////////////////// 00193 INLINE void BoundedObject:: 00194 set_final(bool flag) { 00195 CDWriter cdata(_cycler); 00196 if (flag) { 00197 cdata->_flags |= F_final; 00198 } else { 00199 cdata->_flags &= ~F_final; 00200 } 00201 } 00202 00203 //////////////////////////////////////////////////////////////////// 00204 // Function: BoundedObject::is_final 00205 // Access: Published 00206 // Description: Returns the current state of the "final" flag. 00207 // Initially, this flag is off (false), but it may be 00208 // changed by an explicit call to set_final(). See 00209 // set_final(). 00210 //////////////////////////////////////////////////////////////////// 00211 INLINE bool BoundedObject:: 00212 is_final() const { 00213 CDReader cdata(_cycler); 00214 return (cdata->_flags & F_final) != 0; 00215 } 00216 00217 //////////////////////////////////////////////////////////////////// 00218 // Function: BoundedObject::get_bound_ptr 00219 // Access: Protected 00220 // Description: Returns the state of the _bound pointer. To be used 00221 // only internally by derived classes. 00222 // 00223 // This returns a const pointer only; the bounding 00224 // volume should not be modified directly, because that 00225 // might interfere with pipelining. Instead, create a 00226 // new copy with make_copy(), modify the copy, and 00227 // set_bound_ptr() with the copy. 00228 // 00229 // Alternatively, if you have just called 00230 // recompute_bound(), which is guaranteed to reset the 00231 // pointer, just use the return value from that as a 00232 // non-const BoundingVolume pointer. 00233 //////////////////////////////////////////////////////////////////// 00234 INLINE const BoundingVolume *BoundedObject:: 00235 get_bound_ptr() const { 00236 CDReader cdata(_cycler); 00237 return cdata->_bound; 00238 } 00239 00240 //////////////////////////////////////////////////////////////////// 00241 // Function: BoundedObject::set_bound_ptr 00242 // Access: Protected 00243 // Description: Changes the _bound pointer. To be used only 00244 // internally by derived classes, usually in 00245 // recompute_bound(). The return value is the same 00246 // pointer passed in, as a convenience (it will now be 00247 // reference counted). 00248 //////////////////////////////////////////////////////////////////// 00249 INLINE BoundingVolume *BoundedObject:: 00250 set_bound_ptr(BoundingVolume *bound) { 00251 CDWriter cdata(_cycler); 00252 cdata->_bound = bound; 00253 return bound; 00254 }