Panda3D
 All Classes Functions Variables Enumerations
lodNode.I
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 &copy) :
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 &center) {
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 &copy) :
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 }
 All Classes Functions Variables Enumerations