00001 // Filename: cullableObject.I 00002 // Created by: drose (04Mar02) 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: CullableObject::Constructor 00017 // Access: Public 00018 // Description: Creates an empty CullableObject whose pointers can be 00019 // filled in later. 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE CullableObject:: 00022 CullableObject() : 00023 _fancy(false) 00024 { 00025 #ifdef DO_MEMORY_USAGE 00026 MemoryUsage::update_type(this, get_class_type()); 00027 #endif 00028 } 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: CullableObject::Constructor 00032 // Access: Public 00033 // Description: Creates a CullableObject based the indicated geom, 00034 // with the indicated render state and transform. 00035 //////////////////////////////////////////////////////////////////// 00036 INLINE CullableObject:: 00037 CullableObject(const Geom *geom, const RenderState *state, 00038 const TransformState *net_transform, 00039 const TransformState *modelview_transform, 00040 const GraphicsStateGuardianBase *gsg) : 00041 _geom(geom), 00042 _state(state), 00043 _net_transform(net_transform), 00044 _modelview_transform(modelview_transform), 00045 _internal_transform(gsg->get_cs_transform()->compose(modelview_transform)), 00046 _fancy(false) 00047 { 00048 #ifdef DO_MEMORY_USAGE 00049 MemoryUsage::update_type(this, get_class_type()); 00050 #endif 00051 } 00052 00053 //////////////////////////////////////////////////////////////////// 00054 // Function: CullableObject::Constructor 00055 // Access: Public 00056 // Description: Creates a CullableObject based the indicated geom, 00057 // with the indicated render state and transform. 00058 //////////////////////////////////////////////////////////////////// 00059 INLINE CullableObject:: 00060 CullableObject(const Geom *geom, const RenderState *state, 00061 const TransformState *net_transform, 00062 const TransformState *modelview_transform, 00063 const TransformState *internal_transform) : 00064 _geom(geom), 00065 _state(state), 00066 _net_transform(net_transform), 00067 _modelview_transform(modelview_transform), 00068 _internal_transform(internal_transform), 00069 _fancy(false) 00070 { 00071 #ifdef DO_MEMORY_USAGE 00072 MemoryUsage::update_type(this, get_class_type()); 00073 #endif 00074 } 00075 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: CullableObject::Copy Constructor 00079 // Access: Public 00080 // Description: Copies the CullableObject, but does not copy its 00081 // children (decals). 00082 //////////////////////////////////////////////////////////////////// 00083 INLINE CullableObject:: 00084 CullableObject(const CullableObject ©) : 00085 _geom(copy._geom), 00086 _munger(copy._munger), 00087 _munged_data(copy._munged_data), 00088 _state(copy._state), 00089 _net_transform(copy._net_transform), 00090 _modelview_transform(copy._modelview_transform), 00091 _internal_transform(copy._internal_transform), 00092 _fancy(false) 00093 { 00094 #ifdef DO_MEMORY_USAGE 00095 MemoryUsage::update_type(this, get_class_type()); 00096 #endif 00097 } 00098 00099 //////////////////////////////////////////////////////////////////// 00100 // Function: CullableObject::Copy Assignment Operator 00101 // Access: Public 00102 // Description: Copies the CullableObject, but does not copy its 00103 // children (decals). 00104 //////////////////////////////////////////////////////////////////// 00105 INLINE void CullableObject:: 00106 operator = (const CullableObject ©) { 00107 nassertv(!_fancy); 00108 _geom = copy._geom; 00109 _munger = copy._munger; 00110 _munged_data = copy._munged_data; 00111 _state = copy._state; 00112 _net_transform = copy._net_transform; 00113 _modelview_transform = copy._modelview_transform; 00114 _internal_transform = copy._internal_transform; 00115 } 00116 00117 //////////////////////////////////////////////////////////////////// 00118 // Function: CullableObject::is_fancy 00119 // Access: Public 00120 // Description: Returns true if the object has something fancy to it: 00121 // decals, maybe, or a draw_callback, that prevents it 00122 // from being rendered inline. 00123 //////////////////////////////////////////////////////////////////// 00124 INLINE bool CullableObject:: 00125 is_fancy() const { 00126 return _fancy; 00127 } 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Function: CullableObject::has_decals 00131 // Access: Public 00132 // Description: Returns true if the object has decals associated with 00133 // it. 00134 //////////////////////////////////////////////////////////////////// 00135 INLINE bool CullableObject:: 00136 has_decals() const { 00137 return _fancy && (_next != (CullableObject *)NULL); 00138 } 00139 00140 //////////////////////////////////////////////////////////////////// 00141 // Function: CullableObject::draw 00142 // Access: Public 00143 // Description: Draws the cullable object on the GSG immediately, in 00144 // the GSG's current state. This should only be called 00145 // from the draw thread. 00146 //////////////////////////////////////////////////////////////////// 00147 INLINE void CullableObject:: 00148 draw(GraphicsStateGuardianBase *gsg, bool force, Thread *current_thread) { 00149 if (_fancy) { 00150 draw_fancy(gsg, force, current_thread); 00151 } else { 00152 nassertv(_geom != (Geom *)NULL); 00153 gsg->set_state_and_transform(_state, _internal_transform); 00154 draw_inline(gsg, force, current_thread); 00155 } 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: CullableObject::request_resident 00160 // Access: Public 00161 // Description: Returns true if all the data necessary to render this 00162 // object is currently resident in memory. If this 00163 // returns false, the data will be brought back into 00164 // memory shortly; try again later. 00165 //////////////////////////////////////////////////////////////////// 00166 INLINE bool CullableObject:: 00167 request_resident() const { 00168 bool resident = true; 00169 if (!_geom->request_resident()) { 00170 resident = false; 00171 } 00172 if (!_munged_data->request_resident()) { 00173 resident = false; 00174 } 00175 return resident; 00176 } 00177 00178 00179 //////////////////////////////////////////////////////////////////// 00180 // Function: CullableObject::set_draw_callback 00181 // Access: Public 00182 // Description: Specifies a CallbackObject that will be responsible 00183 // for drawing this object. 00184 //////////////////////////////////////////////////////////////////// 00185 INLINE void CullableObject:: 00186 set_draw_callback(CallbackObject *draw_callback) { 00187 make_fancy(); 00188 if (draw_callback != _draw_callback) { 00189 if (_draw_callback != (CallbackObject *)NULL) { 00190 unref_delete(_draw_callback); 00191 } 00192 _draw_callback = draw_callback; 00193 if (_draw_callback != (CallbackObject *)NULL) { 00194 _draw_callback->ref(); 00195 } 00196 } 00197 } 00198 00199 //////////////////////////////////////////////////////////////////// 00200 // Function: CullableObject::set_next 00201 // Access: Public 00202 // Description: Sets the next object in the decal chain. This next 00203 // object will be destructed when this object destructs. 00204 //////////////////////////////////////////////////////////////////// 00205 INLINE void CullableObject:: 00206 set_next(CullableObject *next) { 00207 make_fancy(); 00208 nassertv(_next == (CullableObject *)NULL); 00209 _next = next; 00210 } 00211 00212 //////////////////////////////////////////////////////////////////// 00213 // Function: CullableObject::get_next 00214 // Access: Public 00215 // Description: Returns the next object in the decal chain, or NULL 00216 // for the end of the chain. 00217 //////////////////////////////////////////////////////////////////// 00218 INLINE CullableObject *CullableObject:: 00219 get_next() const { 00220 if (_fancy) { 00221 return _next; 00222 } 00223 return NULL; 00224 } 00225 00226 //////////////////////////////////////////////////////////////////// 00227 // Function: CullableObject::flush_level 00228 // Access: Public, Static 00229 // Description: Flushes the PStatCollectors used during traversal. 00230 //////////////////////////////////////////////////////////////////// 00231 INLINE void CullableObject:: 00232 flush_level() { 00233 _sw_sprites_pcollector.flush_level(); 00234 } 00235 00236 //////////////////////////////////////////////////////////////////// 00237 // Function: CullableObject::make_fancy 00238 // Access: Private 00239 // Description: Elevates this object to "fancy" status. This means 00240 // that the additional pointers, like _next and 00241 // _draw_callback, have meaningful values and should be 00242 // examined. 00243 //////////////////////////////////////////////////////////////////// 00244 INLINE void CullableObject:: 00245 make_fancy() { 00246 if (!_fancy) { 00247 _fancy = true; 00248 _draw_callback = NULL; 00249 _next = NULL; 00250 } 00251 } 00252 00253 //////////////////////////////////////////////////////////////////// 00254 // Function: CullableObject::draw_inline 00255 // Access: Private 00256 // Description: Draws the cullable object on the GSG immediately, in 00257 // the GSG's current state. This should only be called 00258 // from the draw thread. Assumes the GSG has already 00259 // been set to the appropriate state. 00260 //////////////////////////////////////////////////////////////////// 00261 INLINE void CullableObject:: 00262 draw_inline(GraphicsStateGuardianBase *gsg, bool force, Thread *current_thread) { 00263 _geom->draw(gsg, _munger, _munged_data, force, current_thread); 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: CullableObject::SortPoints::Constructor 00268 // Access: Public 00269 // Description: 00270 //////////////////////////////////////////////////////////////////// 00271 INLINE CullableObject::SortPoints:: 00272 SortPoints(const CullableObject::PointData *array) : 00273 _array(array) 00274 { 00275 } 00276 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: CullableObject::SortPoints::operator () 00279 // Access: Public 00280 // Description: Orders the points from back-to-front for correct 00281 // transparency sorting in munge_points_to_quads 00282 //////////////////////////////////////////////////////////////////// 00283 INLINE bool CullableObject::SortPoints:: 00284 operator () (unsigned short a, unsigned short b) const { 00285 return _array[a]._dist > _array[b]._dist; 00286 } 00287 00288 //////////////////////////////////////////////////////////////////// 00289 // Function: CullableObject::SourceFormat::operator < 00290 // Access: Public 00291 // Description: 00292 //////////////////////////////////////////////////////////////////// 00293 INLINE bool CullableObject::SourceFormat:: 00294 operator < (const CullableObject::SourceFormat &other) const { 00295 if (_format != other._format) { 00296 return _format < other._format; 00297 } 00298 if (_sprite_texcoord != other._sprite_texcoord) { 00299 return (int)_sprite_texcoord < (int)other._sprite_texcoord; 00300 } 00301 if (_retransform_sprites != other._retransform_sprites) { 00302 return (int)_retransform_sprites < (int)other._retransform_sprites; 00303 } 00304 return false; 00305 }