Panda3D
Loading...
Searching...
No Matches
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 */
17INLINE LODNode::
18LODNode(const std::string &name) :
19 PandaNode(name)
20{
21 set_cull_callback();
22}
23
24/**
25 *
26 */
27INLINE LODNode::
28LODNode(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 */
42INLINE void LODNode::
43add_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 */
59INLINE bool LODNode::
60set_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 */
79INLINE void LODNode::
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 */
96INLINE int LODNode::
97get_num_switches() const {
98 CDReader cdata(_cycler);
99 return cdata->_switch_vector.size();
100}
101
102/**
103 * Returns the multiplier for lod distances
104 */
105INLINE PN_stdfloat LODNode::
106get_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 */
115INLINE void LODNode::
116set_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 */
126INLINE PN_stdfloat LODNode::
127get_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 */
137INLINE PN_stdfloat LODNode::
138get_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 */
149INLINE int LODNode::
150get_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 */
160INLINE int LODNode::
161get_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 */
170INLINE void LODNode::
171force_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 */
181INLINE void LODNode::
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 */
192INLINE void LODNode::
193set_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 */
207INLINE const LPoint3 &LODNode::
208get_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 */
217INLINE bool LODNode::
218is_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 */
228INLINE void LODNode::
229consider_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 */
240INLINE LODNode::CData::
241CData() :
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 */
255INLINE LODNode::CData::
256CData(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 */
272INLINE LODNode::Switch::
273Switch(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 */
284INLINE PN_stdfloat LODNode::Switch::
285get_in() const {
286 return _in;
287}
288
289/**
290 *
291 */
292INLINE PN_stdfloat LODNode::Switch::
293get_out() const {
294 return _out;
295}
296
297/**
298 *
299 */
300INLINE void LODNode::Switch::
301set_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 */
310INLINE bool LODNode::Switch::
311in_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 */
320INLINE bool LODNode::Switch::
321in_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 */
328INLINE void LODNode::Switch::
329rescale(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 */
338INLINE bool LODNode::Switch::
339is_shown() const {
340 return _shown;
341}
342
343/**
344 * Shows this ring in debug mode using the indicated color.
345 */
346INLINE void LODNode::Switch::
347show(const LColor &color) {
348 _shown = true;
349 _show_color = color;
350}
351
352/**
353 * Undoes a previous call to show().
354 */
355INLINE void LODNode::Switch::
356hide() {
357 _shown = false;
358}
359
360/**
361 * Returns a PandaNode suitable for rendering the ring associated with this
362 * switch.
363 */
364INLINE PandaNode *LODNode::Switch::
365get_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 */
377INLINE PandaNode *LODNode::Switch::
378get_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 */
390INLINE const RenderState *LODNode::Switch::
391get_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 */
403INLINE void LODNode::Switch::
404write_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 */
413INLINE void LODNode::Switch::
414read_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 */
423INLINE void LODNode::Switch::
424clear_ring_viz() {
425 _ring_viz.clear();
426 _spindle_viz.clear();
427 _viz_model_state.clear();
428 _bounds_seq = UpdateSeq::old();
429}
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A class to retrieve the individual data elements previously stored in a Datagram.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
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
A Level-of-Detail node.
Definition lodNode.h:28
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
get_out
Returns the "out" distance of the indicated switch range.
Definition lodNode.h:61
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
get_in
Returns the "in" distance of the indicated switch range.
Definition lodNode.h:59
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
set_center
Specifies the center of the LOD.
Definition lodNode.h:83
get_center
Returns the center of the LOD.
Definition lodNode.h:83
void add_switch(PN_stdfloat in, PN_stdfloat out)
Adds a switch range to the LODNode.
Definition lodNode.I: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:182
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
get_lod_scale
Returns the multiplier for lod distances.
Definition lodNode.h:82
get_num_switches
Returns the number of switch ranges added to the LODNode.
Definition lodNode.h:59
void clear_switches()
Removes the set of switching ranges for the LODNode, presumably in conjunction with removing all of i...
Definition lodNode.I:80
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
set_lod_scale
Sets the multiplier for lod distances.
Definition lodNode.h:82
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition renderState.h:47
This is a sequence number that increments monotonically.
Definition updateSeq.h:37