Panda3D
|
00001 // Filename: lodNode.I 00002 // Created by: drose (06Mar02) 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 00017 //////////////////////////////////////////////////////////////////// 00018 // Function: LODNode::Constructor 00019 // Access: Published 00020 // Description: 00021 //////////////////////////////////////////////////////////////////// 00022 INLINE LODNode:: 00023 LODNode(const string &name) : 00024 PandaNode(name) 00025 { 00026 set_cull_callback(); 00027 } 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: LODNode::Copy Constructor 00031 // Access: Protected 00032 // Description: 00033 //////////////////////////////////////////////////////////////////// 00034 INLINE LODNode:: 00035 LODNode(const LODNode ©) : 00036 PandaNode(copy), 00037 _cycler(copy._cycler) 00038 { 00039 } 00040 00041 //////////////////////////////////////////////////////////////////// 00042 // Function: LODNode::add_switch 00043 // Access: Published 00044 // Description: Adds a switch range to the LODNode. This implies 00045 // that the corresponding child node has been parented 00046 // to the node. 00047 // 00048 // The sense of in vs. out distances is as if the object 00049 // were coming towards you from far away: it switches 00050 // "in" at the far distance, and switches "out" at the 00051 // close distance. Thus, "in" should be larger than 00052 // "out". 00053 //////////////////////////////////////////////////////////////////// 00054 INLINE void LODNode:: 00055 add_switch(PN_stdfloat in, PN_stdfloat out) { 00056 nassertv(in >= out); 00057 00058 CDWriter cdata(_cycler); 00059 cdata->_switch_vector.push_back(Switch(in, out)); 00060 cdata->check_limits(); 00061 00062 if (cdata->_num_shown != 0) { 00063 mark_internal_bounds_stale(); 00064 } 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function: LODNode::set_switch 00069 // Access: Published 00070 // Description: Changes the switching range of a particular child of 00071 // the LODNode. See add_switch(). 00072 //////////////////////////////////////////////////////////////////// 00073 INLINE bool LODNode:: 00074 set_switch(int index, PN_stdfloat in, PN_stdfloat out) { 00075 nassertr(in >= out, false); 00076 00077 CDWriter cdata(_cycler); 00078 nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), false); 00079 cdata->_switch_vector[index].set_range(in, out); 00080 cdata->check_limits(); 00081 00082 if (cdata->_num_shown != 0) { 00083 mark_internal_bounds_stale(); 00084 } 00085 00086 return true; 00087 } 00088 00089 //////////////////////////////////////////////////////////////////// 00090 // Function: LODNode::clear_switches 00091 // Access: Published 00092 // Description: Removes the set of switching ranges for the LODNode, 00093 // presumably in conjunction with removing all of its 00094 // children. See add_switch(). 00095 //////////////////////////////////////////////////////////////////// 00096 INLINE void LODNode:: 00097 clear_switches() { 00098 CDWriter cdata(_cycler); 00099 cdata->_switch_vector.clear(); 00100 cdata->_lowest = 0; 00101 cdata->_highest = 0; 00102 00103 if (cdata->_num_shown != 0) { 00104 mark_internal_bounds_stale(); 00105 } 00106 } 00107 00108 //////////////////////////////////////////////////////////////////// 00109 // Function: LODNode::get_num_switches 00110 // Access: Published 00111 // Description: Returns the number of switch ranges added to the 00112 // LODNode. This should correspond to the number of 00113 // children of the node in order for the LODNode to 00114 // function correctly. 00115 //////////////////////////////////////////////////////////////////// 00116 INLINE int LODNode:: 00117 get_num_switches() const { 00118 CDReader cdata(_cycler); 00119 return cdata->_switch_vector.size(); 00120 } 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Function: LODNode::get_lod_scale 00124 // Access: Published 00125 // Description: Returns the multiplier for lod distances 00126 //////////////////////////////////////////////////////////////////// 00127 INLINE PN_stdfloat LODNode:: 00128 get_lod_scale() const { 00129 CDReader cdata(_cycler); 00130 return cdata->_lod_scale; 00131 } 00132 00133 //////////////////////////////////////////////////////////////////// 00134 // Function: LODNode::set_lod_scale 00135 // Access: Published 00136 // Description: Sets the multiplier for lod distances. A higher 00137 // value means you'll see farther switchs than normal 00138 //////////////////////////////////////////////////////////////////// 00139 INLINE void LODNode:: 00140 set_lod_scale(PN_stdfloat value) { 00141 CDWriter cdata(_cycler); 00142 cdata->_lod_scale = value; 00143 } 00144 00145 00146 //////////////////////////////////////////////////////////////////// 00147 // Function: LODNode::get_in 00148 // Access: Published 00149 // Description: Returns the "in" distance of the indicated switch 00150 // range. This should be larger than the "out" distance 00151 // of the same range. 00152 //////////////////////////////////////////////////////////////////// 00153 INLINE PN_stdfloat LODNode:: 00154 get_in(int index) const { 00155 CDReader cdata(_cycler); 00156 nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), 0.0); 00157 return cdata->_switch_vector[index].get_in(); 00158 } 00159 00160 //////////////////////////////////////////////////////////////////// 00161 // Function: LODNode::get_out 00162 // Access: Published 00163 // Description: Returns the "out" distance of the indicated switch 00164 // range. This should be smaller than the "in" distance 00165 // of the same range. 00166 //////////////////////////////////////////////////////////////////// 00167 INLINE PN_stdfloat LODNode:: 00168 get_out(int index) const { 00169 CDReader cdata(_cycler); 00170 nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), 0.0); 00171 return cdata->_switch_vector[index].get_out(); 00172 } 00173 00174 //////////////////////////////////////////////////////////////////// 00175 // Function: LODNode::get_lowest_switch 00176 // Access: Published 00177 // Description: Returns the index number of the child with the lowest 00178 // level of detail; that is, the one that is designed to 00179 // be seen from the farthest away. This is usually the 00180 // first child, but it is not necessarily so. 00181 //////////////////////////////////////////////////////////////////// 00182 INLINE int LODNode:: 00183 get_lowest_switch() const { 00184 CDReader cdata(_cycler); 00185 return cdata->_lowest; 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: LODNode::get_highest_switch 00190 // Access: Published 00191 // Description: Returns the index number of the child with the highest 00192 // level of detail; that is, the one that is designed to 00193 // be seen from the closest to the camera. This is 00194 // usually the last child, but it is not necessarily so. 00195 //////////////////////////////////////////////////////////////////// 00196 INLINE int LODNode:: 00197 get_highest_switch() const { 00198 CDReader cdata(_cycler); 00199 return cdata->_highest; 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: LODNode::force_switch 00204 // Access: Published 00205 // Description: Forces the LODNode to show the indicated level 00206 // instead of the level that would normally be shown 00207 // based on the distance from the camera. 00208 //////////////////////////////////////////////////////////////////// 00209 INLINE void LODNode:: 00210 force_switch(int index) { 00211 CDWriter cdata(_cycler); 00212 cdata->_force_switch = index; 00213 cdata->_got_force_switch = true; 00214 } 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: LODNode::clear_force_switch 00218 // Access: Published 00219 // Description: Undoes the effect of a previous call to 00220 // force_switch() and releases the LODNode to once again 00221 // display the normal level. 00222 //////////////////////////////////////////////////////////////////// 00223 INLINE void LODNode:: 00224 clear_force_switch() { 00225 CDWriter cdata(_cycler); 00226 cdata->_got_force_switch = false; 00227 } 00228 00229 //////////////////////////////////////////////////////////////////// 00230 // Function: LODNode::set_center 00231 // Access: Published 00232 // Description: Specifies the center of the LOD. This is the point 00233 // that is compared to the camera (in camera space) to 00234 // determine the particular LOD that should be chosen. 00235 //////////////////////////////////////////////////////////////////// 00236 INLINE void LODNode:: 00237 set_center(const LPoint3 ¢er) { 00238 CDWriter cdata(_cycler); 00239 cdata->_center = center; 00240 00241 if (cdata->_num_shown != 0) { 00242 mark_internal_bounds_stale(); 00243 } 00244 } 00245 00246 //////////////////////////////////////////////////////////////////// 00247 // Function: LODNode::get_center 00248 // Access: Published 00249 // Description: Returns the center of the LOD. This is the point 00250 // that is compared to the camera (in camera space) to 00251 // determine the particular LOD that should be chosen. 00252 //////////////////////////////////////////////////////////////////// 00253 INLINE const LPoint3 &LODNode:: 00254 get_center() const { 00255 CDReader cdata(_cycler); 00256 return cdata->_center; 00257 } 00258 00259 //////////////////////////////////////////////////////////////////// 00260 // Function: LODNode::is_any_shown 00261 // Access: Published 00262 // Description: Returns true if any switch has been shown with 00263 // show_switch(), indicating the LODNode is in debug 00264 // show mode; or false if it is in the normal mode. 00265 //////////////////////////////////////////////////////////////////// 00266 INLINE bool LODNode:: 00267 is_any_shown() const { 00268 CDReader cdata(_cycler); 00269 return (cdata->_num_shown != 0); 00270 } 00271 00272 //////////////////////////////////////////////////////////////////// 00273 // Function: LODNode::consider_verify_lods 00274 // Access: Protected 00275 // Description: To be called internally when the node is rendered, 00276 // this will raise an assertion if verify-lods is 00277 // configured true, and verify_child_bounds() returns 00278 // false. 00279 //////////////////////////////////////////////////////////////////// 00280 INLINE void LODNode:: 00281 consider_verify_lods(CullTraverser *trav, CullTraverserData &data) { 00282 #ifndef NDEBUG 00283 if (verify_lods) { 00284 do_auto_verify_lods(trav, data); 00285 } 00286 #endif // NDEBUG 00287 } 00288 00289 //////////////////////////////////////////////////////////////////// 00290 // Function: LODNode::CData::Constructor 00291 // Access: Public 00292 // Description: 00293 //////////////////////////////////////////////////////////////////// 00294 INLINE LODNode::CData:: 00295 CData() : 00296 _center(0.0f, 0.0f, 0.0f), 00297 _lowest(0), 00298 _highest(0), 00299 _got_force_switch(false), 00300 _force_switch(0), 00301 _num_shown(0), 00302 _lod_scale(1) 00303 { 00304 } 00305 00306 //////////////////////////////////////////////////////////////////// 00307 // Function: LODNode::CData::Copy Constructor 00308 // Access: Public 00309 // Description: 00310 //////////////////////////////////////////////////////////////////// 00311 INLINE LODNode::CData:: 00312 CData(const LODNode::CData ©) : 00313 _center(copy._center), 00314 _switch_vector(copy._switch_vector), 00315 _lowest(copy._lowest), 00316 _highest(copy._highest), 00317 _bounds_seq(UpdateSeq::old()), 00318 _got_force_switch(copy._got_force_switch), 00319 _force_switch(copy._force_switch), 00320 _num_shown(copy._num_shown), 00321 _lod_scale(copy._lod_scale) 00322 { 00323 } 00324 00325 //////////////////////////////////////////////////////////////////// 00326 // Function: LODNode::Switch::Constructor 00327 // Access: Public 00328 // Description: 00329 //////////////////////////////////////////////////////////////////// 00330 INLINE LODNode::Switch:: 00331 Switch(PN_stdfloat in, PN_stdfloat out) : 00332 _shown(false), 00333 _bounds_seq(UpdateSeq::old()), 00334 _verify_ok(false) 00335 { 00336 set_range(in, out); 00337 } 00338 00339 //////////////////////////////////////////////////////////////////// 00340 // Function: LODNode::Switch::get_in 00341 // Access: Public 00342 // Description: 00343 //////////////////////////////////////////////////////////////////// 00344 INLINE PN_stdfloat LODNode::Switch:: 00345 get_in() const { 00346 return _in; 00347 } 00348 00349 //////////////////////////////////////////////////////////////////// 00350 // Function: LODNode::Switch::get_out 00351 // Access: Public 00352 // Description: 00353 //////////////////////////////////////////////////////////////////// 00354 INLINE PN_stdfloat LODNode::Switch:: 00355 get_out() const { 00356 return _out; 00357 } 00358 00359 //////////////////////////////////////////////////////////////////// 00360 // Function: LODNode::Switch::set_range 00361 // Access: Public 00362 // Description: 00363 //////////////////////////////////////////////////////////////////// 00364 INLINE void LODNode::Switch:: 00365 set_range(PN_stdfloat in, PN_stdfloat out) { 00366 _in = in; 00367 _out = out; 00368 clear_ring_viz(); 00369 } 00370 00371 //////////////////////////////////////////////////////////////////// 00372 // Function: LODNode::Switch::in_range 00373 // Access: Public 00374 // Description: Returns true if the indicated distance is within the 00375 // range for the LOD. 00376 //////////////////////////////////////////////////////////////////// 00377 INLINE bool LODNode::Switch:: 00378 in_range(PN_stdfloat dist) const { 00379 return (dist >= _out && dist < _in); 00380 } 00381 00382 //////////////////////////////////////////////////////////////////// 00383 // Function: LODNode::Switch::in_range_2 00384 // Access: Public 00385 // Description: Returns true if the indicated distance squared is 00386 // within the range for the LOD. (The distance value is 00387 // understood to be the square of the distance from the 00388 // camera to the object.) 00389 //////////////////////////////////////////////////////////////////// 00390 INLINE bool LODNode::Switch:: 00391 in_range_2(PN_stdfloat dist2) const { 00392 return (dist2 >= _out * _out && dist2 < _in * _in); 00393 } 00394 00395 //////////////////////////////////////////////////////////////////// 00396 // Function: LODNode::Switch::rescale 00397 // Access: Public 00398 // Description: Scales the switching distances by the indicated factor. 00399 //////////////////////////////////////////////////////////////////// 00400 INLINE void LODNode::Switch:: 00401 rescale(PN_stdfloat factor) { 00402 _in *= factor; 00403 _out *= factor; 00404 clear_ring_viz(); 00405 } 00406 00407 //////////////////////////////////////////////////////////////////// 00408 // Function: LODNode::Switch::is_shown 00409 // Access: Public 00410 // Description: Returns true if show() has been called. 00411 //////////////////////////////////////////////////////////////////// 00412 INLINE bool LODNode::Switch:: 00413 is_shown() const { 00414 return _shown; 00415 } 00416 00417 //////////////////////////////////////////////////////////////////// 00418 // Function: LODNode::Switch::show 00419 // Access: Public 00420 // Description: Shows this ring in debug mode using the indicated 00421 // color. 00422 //////////////////////////////////////////////////////////////////// 00423 INLINE void LODNode::Switch:: 00424 show(const LColor &color) { 00425 _shown = true; 00426 _show_color = color; 00427 } 00428 00429 //////////////////////////////////////////////////////////////////// 00430 // Function: LODNode::Switch::hide 00431 // Access: Public 00432 // Description: Undoes a previous call to show(). 00433 //////////////////////////////////////////////////////////////////// 00434 INLINE void LODNode::Switch:: 00435 hide() { 00436 _shown = false; 00437 } 00438 00439 //////////////////////////////////////////////////////////////////// 00440 // Function: LODNode::Switch::get_ring_viz 00441 // Access: Public 00442 // Description: Returns a PandaNode suitable for rendering the ring 00443 // associated with this switch. 00444 //////////////////////////////////////////////////////////////////// 00445 INLINE PandaNode *LODNode::Switch:: 00446 get_ring_viz() const { 00447 if (_ring_viz.is_null()) { 00448 ((Switch *)this)->compute_ring_viz(); 00449 } 00450 00451 return _ring_viz; 00452 } 00453 00454 //////////////////////////////////////////////////////////////////// 00455 // Function: LODNode::Switch::get_spindle_viz 00456 // Access: Public 00457 // Description: Returns a PandaNode suitable for rendering the center 00458 // spindle of the LODNode, in the color of this switch. 00459 //////////////////////////////////////////////////////////////////// 00460 INLINE PandaNode *LODNode::Switch:: 00461 get_spindle_viz() const { 00462 if (_spindle_viz.is_null()) { 00463 ((Switch *)this)->compute_spindle_viz(); 00464 } 00465 00466 return _spindle_viz; 00467 } 00468 00469 //////////////////////////////////////////////////////////////////// 00470 // Function: LODNode::Switch::get_viz_model_state 00471 // Access: Public 00472 // Description: Returns a RenderState suitable for drawing the 00473 // visible children of this switch level when the 00474 // show_switch() debugging mode is enabled. 00475 //////////////////////////////////////////////////////////////////// 00476 INLINE const RenderState *LODNode::Switch:: 00477 get_viz_model_state() const { 00478 if (_viz_model_state.is_null()) { 00479 ((Switch *)this)->compute_viz_model_state(); 00480 } 00481 00482 return _viz_model_state; 00483 } 00484 00485 //////////////////////////////////////////////////////////////////// 00486 // Function: LODNode::Switch::write_datagram 00487 // Access: Public 00488 // Description: Writes the contents of the Switch out to the 00489 // datagram, presumably in preparation to writing to a 00490 // Bam file. 00491 //////////////////////////////////////////////////////////////////// 00492 INLINE void LODNode::Switch:: 00493 write_datagram(Datagram &destination) const { 00494 destination.add_stdfloat(_in); 00495 destination.add_stdfloat(_out); 00496 } 00497 00498 //////////////////////////////////////////////////////////////////// 00499 // Function: LODNode::Switch::read_datagram 00500 // Access: Public 00501 // Description: Reads the contents of the Switch from the datagram, 00502 // presumably in response to reading a Bam file. 00503 //////////////////////////////////////////////////////////////////// 00504 INLINE void LODNode::Switch:: 00505 read_datagram(DatagramIterator &source) { 00506 _in = source.get_stdfloat(); 00507 _out = source.get_stdfloat(); 00508 } 00509 00510 //////////////////////////////////////////////////////////////////// 00511 // Function: LODNode::Switch::clear_ring_viz 00512 // Access: Private 00513 // Description: Resets the internal cache values for the ring and 00514 // spindle viz, and related pointers, for the 00515 // set_switch() debugging mode. 00516 //////////////////////////////////////////////////////////////////// 00517 INLINE void LODNode::Switch:: 00518 clear_ring_viz() { 00519 _ring_viz.clear(); 00520 _spindle_viz.clear(); 00521 _viz_model_state.clear(); 00522 _bounds_seq = UpdateSeq::old(); 00523 }