Panda3D
 All Classes Functions Variables Enumerations
lodNode.I
1 // Filename: lodNode.I
2 // Created by: drose (06Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 
17 ////////////////////////////////////////////////////////////////////
18 // Function: LODNode::Constructor
19 // Access: Published
20 // Description:
21 ////////////////////////////////////////////////////////////////////
22 INLINE LODNode::
23 LODNode(const string &name) :
24  PandaNode(name)
25 {
26  set_cull_callback();
27 }
28 
29 ////////////////////////////////////////////////////////////////////
30 // Function: LODNode::Copy Constructor
31 // Access: Protected
32 // Description:
33 ////////////////////////////////////////////////////////////////////
34 INLINE LODNode::
35 LODNode(const LODNode &copy) :
36  PandaNode(copy),
37  _cycler(copy._cycler)
38 {
39 }
40 
41 ////////////////////////////////////////////////////////////////////
42 // Function: LODNode::add_switch
43 // Access: Published
44 // Description: Adds a switch range to the LODNode. This implies
45 // that the corresponding child node has been parented
46 // to the node.
47 //
48 // The sense of in vs. out distances is as if the object
49 // were coming towards you from far away: it switches
50 // "in" at the far distance, and switches "out" at the
51 // close distance. Thus, "in" should be larger than
52 // "out".
53 ////////////////////////////////////////////////////////////////////
54 INLINE void LODNode::
55 add_switch(PN_stdfloat in, PN_stdfloat out) {
56  nassertv(in >= out);
57 
58  CDWriter cdata(_cycler);
59  cdata->_switch_vector.push_back(Switch(in, out));
60  cdata->check_limits();
61 
62  if (cdata->_num_shown != 0) {
64  }
65 }
66 
67 ////////////////////////////////////////////////////////////////////
68 // Function: LODNode::set_switch
69 // Access: Published
70 // Description: Changes the switching range of a particular child of
71 // the LODNode. See add_switch().
72 ////////////////////////////////////////////////////////////////////
73 INLINE bool LODNode::
74 set_switch(int index, PN_stdfloat in, PN_stdfloat out) {
75  nassertr(in >= out, false);
76 
77  CDWriter cdata(_cycler);
78  nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), false);
79  cdata->_switch_vector[index].set_range(in, out);
80  cdata->check_limits();
81 
82  if (cdata->_num_shown != 0) {
84  }
85 
86  return true;
87 }
88 
89 ////////////////////////////////////////////////////////////////////
90 // Function: LODNode::clear_switches
91 // Access: Published
92 // Description: Removes the set of switching ranges for the LODNode,
93 // presumably in conjunction with removing all of its
94 // children. See add_switch().
95 ////////////////////////////////////////////////////////////////////
96 INLINE void LODNode::
98  CDWriter cdata(_cycler);
99  cdata->_switch_vector.clear();
100  cdata->_lowest = 0;
101  cdata->_highest = 0;
102 
103  if (cdata->_num_shown != 0) {
105  }
106 }
107 
108 ////////////////////////////////////////////////////////////////////
109 // Function: LODNode::get_num_switches
110 // Access: Published
111 // Description: Returns the number of switch ranges added to the
112 // LODNode. This should correspond to the number of
113 // children of the node in order for the LODNode to
114 // function correctly.
115 ////////////////////////////////////////////////////////////////////
116 INLINE int LODNode::
118  CDReader cdata(_cycler);
119  return cdata->_switch_vector.size();
120 }
121 
122 ////////////////////////////////////////////////////////////////////
123 // Function: LODNode::get_lod_scale
124 // Access: Published
125 // Description: Returns the multiplier for lod distances
126 ////////////////////////////////////////////////////////////////////
127 INLINE PN_stdfloat LODNode::
128 get_lod_scale() const {
129  CDReader cdata(_cycler);
130  return cdata->_lod_scale;
131 }
132 
133 ////////////////////////////////////////////////////////////////////
134 // Function: LODNode::set_lod_scale
135 // Access: Published
136 // Description: Sets the multiplier for lod distances. A higher
137 // value means you'll see farther switchs than normal
138 ////////////////////////////////////////////////////////////////////
139 INLINE void LODNode::
140 set_lod_scale(PN_stdfloat value) {
141  CDWriter cdata(_cycler);
142  cdata->_lod_scale = value;
143 }
144 
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: LODNode::get_in
148 // Access: Published
149 // Description: Returns the "in" distance of the indicated switch
150 // range. This should be larger than the "out" distance
151 // of the same range.
152 ////////////////////////////////////////////////////////////////////
153 INLINE PN_stdfloat LODNode::
154 get_in(int index) const {
155  CDReader cdata(_cycler);
156  nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), 0.0);
157  return cdata->_switch_vector[index].get_in();
158 }
159 
160 ////////////////////////////////////////////////////////////////////
161 // Function: LODNode::get_out
162 // Access: Published
163 // Description: Returns the "out" distance of the indicated switch
164 // range. This should be smaller than the "in" distance
165 // of the same range.
166 ////////////////////////////////////////////////////////////////////
167 INLINE PN_stdfloat LODNode::
168 get_out(int index) const {
169  CDReader cdata(_cycler);
170  nassertr(index >= 0 && index < (int)cdata->_switch_vector.size(), 0.0);
171  return cdata->_switch_vector[index].get_out();
172 }
173 
174 ////////////////////////////////////////////////////////////////////
175 // Function: LODNode::get_lowest_switch
176 // Access: Published
177 // Description: Returns the index number of the child with the lowest
178 // level of detail; that is, the one that is designed to
179 // be seen from the farthest away. This is usually the
180 // first child, but it is not necessarily so.
181 ////////////////////////////////////////////////////////////////////
182 INLINE int LODNode::
184  CDReader cdata(_cycler);
185  return cdata->_lowest;
186 }
187 
188 ////////////////////////////////////////////////////////////////////
189 // Function: LODNode::get_highest_switch
190 // Access: Published
191 // Description: Returns the index number of the child with the highest
192 // level of detail; that is, the one that is designed to
193 // be seen from the closest to the camera. This is
194 // usually the last child, but it is not necessarily so.
195 ////////////////////////////////////////////////////////////////////
196 INLINE int LODNode::
198  CDReader cdata(_cycler);
199  return cdata->_highest;
200 }
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: LODNode::force_switch
204 // Access: Published
205 // Description: Forces the LODNode to show the indicated level
206 // instead of the level that would normally be shown
207 // based on the distance from the camera.
208 ////////////////////////////////////////////////////////////////////
209 INLINE void LODNode::
210 force_switch(int index) {
211  CDWriter cdata(_cycler);
212  cdata->_force_switch = index;
213  cdata->_got_force_switch = true;
214 }
215 
216 ////////////////////////////////////////////////////////////////////
217 // Function: LODNode::clear_force_switch
218 // Access: Published
219 // Description: Undoes the effect of a previous call to
220 // force_switch() and releases the LODNode to once again
221 // display the normal level.
222 ////////////////////////////////////////////////////////////////////
223 INLINE void LODNode::
225  CDWriter cdata(_cycler);
226  cdata->_got_force_switch = false;
227 }
228 
229 ////////////////////////////////////////////////////////////////////
230 // Function: LODNode::set_center
231 // Access: Published
232 // Description: Specifies the center of the LOD. This is the point
233 // that is compared to the camera (in camera space) to
234 // determine the particular LOD that should be chosen.
235 ////////////////////////////////////////////////////////////////////
236 INLINE void LODNode::
237 set_center(const LPoint3 &center) {
238  CDWriter cdata(_cycler);
239  cdata->_center = center;
240 
241  if (cdata->_num_shown != 0) {
243  }
244 }
245 
246 ////////////////////////////////////////////////////////////////////
247 // Function: LODNode::get_center
248 // Access: Published
249 // Description: Returns the center of the LOD. This is the point
250 // that is compared to the camera (in camera space) to
251 // determine the particular LOD that should be chosen.
252 ////////////////////////////////////////////////////////////////////
253 INLINE const LPoint3 &LODNode::
254 get_center() const {
255  CDReader cdata(_cycler);
256  return cdata->_center;
257 }
258 
259 ////////////////////////////////////////////////////////////////////
260 // Function: LODNode::is_any_shown
261 // Access: Published
262 // Description: Returns true if any switch has been shown with
263 // show_switch(), indicating the LODNode is in debug
264 // show mode; or false if it is in the normal mode.
265 ////////////////////////////////////////////////////////////////////
266 INLINE bool LODNode::
267 is_any_shown() const {
268  CDReader cdata(_cycler);
269  return (cdata->_num_shown != 0);
270 }
271 
272 ////////////////////////////////////////////////////////////////////
273 // Function: LODNode::consider_verify_lods
274 // Access: Protected
275 // Description: To be called internally when the node is rendered,
276 // this will raise an assertion if verify-lods is
277 // configured true, and verify_child_bounds() returns
278 // false.
279 ////////////////////////////////////////////////////////////////////
280 INLINE void LODNode::
281 consider_verify_lods(CullTraverser *trav, CullTraverserData &data) {
282 #ifndef NDEBUG
283  if (verify_lods) {
284  do_auto_verify_lods(trav, data);
285  }
286 #endif // NDEBUG
287 }
288 
289 ////////////////////////////////////////////////////////////////////
290 // Function: LODNode::CData::Constructor
291 // Access: Public
292 // Description:
293 ////////////////////////////////////////////////////////////////////
294 INLINE LODNode::CData::
295 CData() :
296  _center(0.0f, 0.0f, 0.0f),
297  _lowest(0),
298  _highest(0),
299  _got_force_switch(false),
300  _force_switch(0),
301  _num_shown(0),
302  _lod_scale(1)
303 {
304 }
305 
306 ////////////////////////////////////////////////////////////////////
307 // Function: LODNode::CData::Copy Constructor
308 // Access: Public
309 // Description:
310 ////////////////////////////////////////////////////////////////////
311 INLINE LODNode::CData::
312 CData(const LODNode::CData &copy) :
313  _center(copy._center),
314  _switch_vector(copy._switch_vector),
315  _lowest(copy._lowest),
316  _highest(copy._highest),
317  _bounds_seq(UpdateSeq::old()),
318  _got_force_switch(copy._got_force_switch),
319  _force_switch(copy._force_switch),
320  _num_shown(copy._num_shown),
321  _lod_scale(copy._lod_scale)
322 {
323 }
324 
325 ////////////////////////////////////////////////////////////////////
326 // Function: LODNode::Switch::Constructor
327 // Access: Public
328 // Description:
329 ////////////////////////////////////////////////////////////////////
330 INLINE LODNode::Switch::
331 Switch(PN_stdfloat in, PN_stdfloat out) :
332  _shown(false),
333  _bounds_seq(UpdateSeq::old()),
334  _verify_ok(false)
335 {
336  set_range(in, out);
337 }
338 
339 ////////////////////////////////////////////////////////////////////
340 // Function: LODNode::Switch::get_in
341 // Access: Public
342 // Description:
343 ////////////////////////////////////////////////////////////////////
344 INLINE PN_stdfloat LODNode::Switch::
345 get_in() const {
346  return _in;
347 }
348 
349 ////////////////////////////////////////////////////////////////////
350 // Function: LODNode::Switch::get_out
351 // Access: Public
352 // Description:
353 ////////////////////////////////////////////////////////////////////
354 INLINE PN_stdfloat LODNode::Switch::
355 get_out() const {
356  return _out;
357 }
358 
359 ////////////////////////////////////////////////////////////////////
360 // Function: LODNode::Switch::set_range
361 // Access: Public
362 // Description:
363 ////////////////////////////////////////////////////////////////////
364 INLINE void LODNode::Switch::
365 set_range(PN_stdfloat in, PN_stdfloat out) {
366  _in = in;
367  _out = out;
368  clear_ring_viz();
369 }
370 
371 ////////////////////////////////////////////////////////////////////
372 // Function: LODNode::Switch::in_range
373 // Access: Public
374 // Description: Returns true if the indicated distance is within the
375 // range for the LOD.
376 ////////////////////////////////////////////////////////////////////
377 INLINE bool LODNode::Switch::
378 in_range(PN_stdfloat dist) const {
379  return (dist >= _out && dist < _in);
380 }
381 
382 ////////////////////////////////////////////////////////////////////
383 // Function: LODNode::Switch::in_range_2
384 // Access: Public
385 // Description: Returns true if the indicated distance squared is
386 // within the range for the LOD. (The distance value is
387 // understood to be the square of the distance from the
388 // camera to the object.)
389 ////////////////////////////////////////////////////////////////////
390 INLINE bool LODNode::Switch::
391 in_range_2(PN_stdfloat dist2) const {
392  return (dist2 >= _out * _out && dist2 < _in * _in);
393 }
394 
395 ////////////////////////////////////////////////////////////////////
396 // Function: LODNode::Switch::rescale
397 // Access: Public
398 // Description: Scales the switching distances by the indicated factor.
399 ////////////////////////////////////////////////////////////////////
400 INLINE void LODNode::Switch::
401 rescale(PN_stdfloat factor) {
402  _in *= factor;
403  _out *= factor;
404  clear_ring_viz();
405 }
406 
407 ////////////////////////////////////////////////////////////////////
408 // Function: LODNode::Switch::is_shown
409 // Access: Public
410 // Description: Returns true if show() has been called.
411 ////////////////////////////////////////////////////////////////////
412 INLINE bool LODNode::Switch::
413 is_shown() const {
414  return _shown;
415 }
416 
417 ////////////////////////////////////////////////////////////////////
418 // Function: LODNode::Switch::show
419 // Access: Public
420 // Description: Shows this ring in debug mode using the indicated
421 // color.
422 ////////////////////////////////////////////////////////////////////
423 INLINE void LODNode::Switch::
424 show(const LColor &color) {
425  _shown = true;
426  _show_color = color;
427 }
428 
429 ////////////////////////////////////////////////////////////////////
430 // Function: LODNode::Switch::hide
431 // Access: Public
432 // Description: Undoes a previous call to show().
433 ////////////////////////////////////////////////////////////////////
434 INLINE void LODNode::Switch::
435 hide() {
436  _shown = false;
437 }
438 
439 ////////////////////////////////////////////////////////////////////
440 // Function: LODNode::Switch::get_ring_viz
441 // Access: Public
442 // Description: Returns a PandaNode suitable for rendering the ring
443 // associated with this switch.
444 ////////////////////////////////////////////////////////////////////
445 INLINE PandaNode *LODNode::Switch::
446 get_ring_viz() const {
447  if (_ring_viz.is_null()) {
448  ((Switch *)this)->compute_ring_viz();
449  }
450 
451  return _ring_viz;
452 }
453 
454 ////////////////////////////////////////////////////////////////////
455 // Function: LODNode::Switch::get_spindle_viz
456 // Access: Public
457 // Description: Returns a PandaNode suitable for rendering the center
458 // spindle of the LODNode, in the color of this switch.
459 ////////////////////////////////////////////////////////////////////
460 INLINE PandaNode *LODNode::Switch::
461 get_spindle_viz() const {
462  if (_spindle_viz.is_null()) {
463  ((Switch *)this)->compute_spindle_viz();
464  }
465 
466  return _spindle_viz;
467 }
468 
469 ////////////////////////////////////////////////////////////////////
470 // Function: LODNode::Switch::get_viz_model_state
471 // Access: Public
472 // Description: Returns a RenderState suitable for drawing the
473 // visible children of this switch level when the
474 // show_switch() debugging mode is enabled.
475 ////////////////////////////////////////////////////////////////////
476 INLINE const RenderState *LODNode::Switch::
477 get_viz_model_state() const {
478  if (_viz_model_state.is_null()) {
479  ((Switch *)this)->compute_viz_model_state();
480  }
481 
482  return _viz_model_state;
483 }
484 
485 ////////////////////////////////////////////////////////////////////
486 // Function: LODNode::Switch::write_datagram
487 // Access: Public
488 // Description: Writes the contents of the Switch out to the
489 // datagram, presumably in preparation to writing to a
490 // Bam file.
491 ////////////////////////////////////////////////////////////////////
492 INLINE void LODNode::Switch::
493 write_datagram(Datagram &destination) const {
494  destination.add_stdfloat(_in);
495  destination.add_stdfloat(_out);
496 }
497 
498 ////////////////////////////////////////////////////////////////////
499 // Function: LODNode::Switch::read_datagram
500 // Access: Public
501 // Description: Reads the contents of the Switch from the datagram,
502 // presumably in response to reading a Bam file.
503 ////////////////////////////////////////////////////////////////////
504 INLINE void LODNode::Switch::
505 read_datagram(DatagramIterator &source) {
506  _in = source.get_stdfloat();
507  _out = source.get_stdfloat();
508 }
509 
510 ////////////////////////////////////////////////////////////////////
511 // Function: LODNode::Switch::clear_ring_viz
512 // Access: Private
513 // Description: Resets the internal cache values for the ring and
514 // spindle viz, and related pointers, for the
515 // set_switch() debugging mode.
516 ////////////////////////////////////////////////////////////////////
517 INLINE void LODNode::Switch::
518 clear_ring_viz() {
519  _ring_viz.clear();
520  _spindle_viz.clear();
521  _viz_model_state.clear();
522  _bounds_seq = UpdateSeq::old();
523 }
PN_stdfloat get_lod_scale() const
Returns the multiplier for lod distances.
Definition: lodNode.I:128
const LPoint3 & get_center() const
Returns the center of the LOD.
Definition: lodNode.I:254
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
PN_stdfloat get_in(int index) const
Returns the &quot;in&quot; distance of the indicated switch range.
Definition: lodNode.I:154
bool is_any_shown() const
Returns true if any switch has been shown with show_switch(), indicating the LODNode is in debug show...
Definition: lodNode.I:267
void set_lod_scale(PN_stdfloat value)
Sets the multiplier for lod distances.
Definition: lodNode.I:140
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
void clear_switches()
Removes the set of switching ranges for the LODNode, presumably in conjunction with removing all of i...
Definition: lodNode.I:97
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:240
void force_switch(int index)
Forces the LODNode to show the indicated level instead of the level that would normally be shown base...
Definition: lodNode.I:210
int get_num_switches() const
Returns the number of switch ranges added to the LODNode.
Definition: lodNode.I:117
PN_stdfloat get_out(int index) const
Returns the &quot;out&quot; distance of the indicated switch range.
Definition: lodNode.I:168
void add_switch(PN_stdfloat in, PN_stdfloat out)
Adds a switch range to the LODNode.
Definition: lodNode.I:55
void mark_internal_bounds_stale(Thread *current_thread=Thread::get_current_thread())
Should be called by a derived class to mark the internal bounding volume stale, so that compute_inter...
Definition: pandaNode.cxx:2467
A Level-of-Detail node.
Definition: lodNode.h:31
int get_lowest_switch() const
Returns the index number of the child with the lowest level of detail; that is, the one that is desig...
Definition: lodNode.I:183
bool set_switch(int index, PN_stdfloat in, PN_stdfloat out)
Changes the switching range of a particular child of the LODNode.
Definition: lodNode.I:74
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
static UpdateSeq old()
Returns an UpdateSeq in the &#39;old&#39; state.
Definition: updateSeq.I:42
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
A class to retrieve the individual data elements previously stored in a Datagram. ...
This is a sequence number that increments monotonically.
Definition: updateSeq.h:43
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
void clear_force_switch()
Undoes the effect of a previous call to force_switch() and releases the LODNode to once again display...
Definition: lodNode.I:224
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: cullTraverser.h:48
int get_highest_switch() const
Returns the index number of the child with the highest level of detail; that is, the one that is desi...
Definition: lodNode.I:197
void set_center(const LPoint3 &center)
Specifies the center of the LOD.
Definition: lodNode.I:237