Panda3D

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