Panda3D
Loading...
Searching...
No Matches
pandaNode.h
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 pandaNode.h
10 * @author drose
11 * @date 2002-02-20
12 */
13
14#ifndef PANDANODE_H
15#define PANDANODE_H
16
17#include "pandabase.h"
18
19#include "cycleData.h"
20#include "cycleDataReader.h"
21#include "cycleDataWriter.h"
25#include "pipelineCycler.h"
26#include "renderState.h"
27#include "renderEffects.h"
28#include "transformState.h"
29#include "drawMask.h"
30#include "typedWritable.h"
31#include "collideMask.h"
32#include "namable.h"
33#include "referenceCount.h"
34#include "luse.h"
35#include "ordered_vector.h"
36#include "pointerTo.h"
37#include "nodePointerTo.h"
38#include "pointerToArray.h"
39#include "pnotify.h"
40#include "updateSeq.h"
41#include "deletedChain.h"
42#include "pandaNodeChain.h"
43#include "pStatCollector.h"
44#include "copyOnWriteObject.h"
45#include "copyOnWritePointer.h"
46#include "lightReMutex.h"
47#include "extension.h"
48#include "simpleHashMap.h"
49
51class CullTraverser;
53class Light;
54class FactoryParams;
56class GeomTransformer;
58
59/**
60 * A basic node of the scene graph or data graph. This is the base class of
61 * all specialized nodes, and also serves as a generic node with no special
62 * properties.
63 */
64class EXPCL_PANDA_PGRAPH PandaNode : public TypedWritableReferenceCount,
65 public Namable, public LinkedListNode {
66PUBLISHED:
67 explicit PandaNode(const std::string &name);
68 virtual ~PandaNode();
69 // published so that characters can be combined.
70 virtual PandaNode *combine_with(PandaNode *other);
71
72protected:
73 PandaNode(const PandaNode &copy);
74
75 PandaNode &operator = (const PandaNode &copy) = delete;
76
77public:
78 virtual PandaNode *dupe_for_flatten() const;
79
80 virtual bool safe_to_flatten() const;
81 virtual bool safe_to_transform() const;
82 virtual bool safe_to_modify_transform() const;
83 virtual bool safe_to_combine() const;
84 virtual bool safe_to_combine_children() const;
85 virtual bool safe_to_flatten_below() const;
86 virtual bool preserve_name() const;
87 virtual int get_unsafe_to_apply_attribs() const;
88 virtual void apply_attribs_to_vertices(const AccumulatedAttribs &attribs,
89 int attrib_types,
90 GeomTransformer &transformer);
91 virtual void xform(const LMatrix4 &mat);
92
93 virtual CPT(TransformState)
94 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
95 bool &found_any,
96 const TransformState *transform,
97 Thread *current_thread = Thread::get_current_thread()) const;
98
99 virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
100 virtual bool has_selective_visibility() const;
101 virtual int get_first_visible_child() const;
102 virtual int get_next_visible_child(int n) const;
103 virtual bool has_single_child_visibility() const;
104 virtual int get_visible_child() const;
105 virtual bool is_renderable() const;
106 virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data);
107
108PUBLISHED:
109 virtual PandaNode *make_copy() const;
110 PT(PandaNode) copy_subgraph(Thread *current_thread = Thread::get_current_thread()) const;
111
112 EXTENSION(PT(PandaNode) __copy__() const);
113 EXTENSION(PyObject *__deepcopy__(PyObject *self, PyObject *memo) const);
114
115 INLINE int get_num_parents(Thread *current_thread = Thread::get_current_thread()) const;
116 INLINE PandaNode *get_parent(int n, Thread *current_thread = Thread::get_current_thread()) const;
117 INLINE int find_parent(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
118 MAKE_SEQ(get_parents, get_num_parents, get_parent);
119
120 INLINE int get_num_children(Thread *current_thread = Thread::get_current_thread()) const;
121 INLINE PandaNode *get_child(int n, Thread *current_thread = Thread::get_current_thread()) const;
122 INLINE int get_child_sort(int n, Thread *current_thread = Thread::get_current_thread()) const;
123 INLINE int find_child(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
124 MAKE_SEQ(get_children, get_num_children, get_child);
125
126 int count_num_descendants() const;
127
128 void add_child(PandaNode *child_node, int sort = 0,
129 Thread *current_thread = Thread::get_current_thread());
130 void remove_child(int child_index, Thread *current_thread = Thread::get_current_thread());
131 bool remove_child(PandaNode *child_node, Thread *current_thread = Thread::get_current_thread());
132 bool replace_child(PandaNode *orig_child, PandaNode *new_child,
133 Thread *current_thread = Thread::get_current_thread());
134
135 INLINE bool stash_child(PandaNode *child_node,
136 Thread *current_thread = Thread::get_current_thread());
137 void stash_child(int child_index,
138 Thread *current_thread = Thread::get_current_thread());
139 INLINE bool unstash_child(PandaNode *child_node,
140 Thread *current_thread = Thread::get_current_thread());
141 void unstash_child(int stashed_index,
142 Thread *current_thread = Thread::get_current_thread());
143
144 INLINE int get_num_stashed(Thread *current_thread = Thread::get_current_thread()) const;
145 INLINE PandaNode *get_stashed(int n, Thread *current_thread = Thread::get_current_thread()) const;
146 INLINE int get_stashed_sort(int n, Thread *current_thread = Thread::get_current_thread()) const;
147 INLINE int find_stashed(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
148 MAKE_SEQ(get_stashed, get_num_stashed, get_stashed);
149
150 void add_stashed(PandaNode *child_node, int sort = 0, Thread *current_thread = Thread::get_current_thread());
151 void remove_stashed(int child_index, Thread *current_thread = Thread::get_current_thread());
152
153 void remove_all_children(Thread *current_thread = Thread::get_current_thread());
154 void steal_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread());
155 void copy_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread());
156
157 void set_attrib(const RenderAttrib *attrib, int override = 0);
158 INLINE CPT(RenderAttrib) get_attrib(TypeHandle type) const;
159 INLINE CPT(RenderAttrib) get_attrib(int slot) const;
160 INLINE bool has_attrib(TypeHandle type) const;
161 INLINE bool has_attrib(int slot) const;
162 INLINE void clear_attrib(TypeHandle type);
163 void clear_attrib(int slot);
164
165 void set_effect(const RenderEffect *effect);
166 INLINE CPT(RenderEffect) get_effect(TypeHandle type) const;
167 INLINE bool has_effect(TypeHandle type) const;
168 void clear_effect(TypeHandle type);
169
170 void set_state(const RenderState *state, Thread *current_thread = Thread::get_current_thread());
171 INLINE CPT(RenderState) get_state(Thread *current_thread = Thread::get_current_thread()) const;
172 INLINE void clear_state(Thread *current_thread = Thread::get_current_thread());
173 MAKE_PROPERTY(state, get_state, set_state);
174
175 void set_effects(const RenderEffects *effects, Thread *current_thread = Thread::get_current_thread());
176 INLINE CPT(RenderEffects) get_effects(Thread *current_thread = Thread::get_current_thread()) const;
177 INLINE void clear_effects(Thread *current_thread = Thread::get_current_thread());
178 MAKE_PROPERTY(effects, get_effects, set_effects);
179
180 void set_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
181 INLINE CPT(TransformState) get_transform(Thread *current_thread = Thread::get_current_thread()) const;
182 INLINE void clear_transform(Thread *current_thread = Thread::get_current_thread());
183 MAKE_PROPERTY(transform, get_transform, set_transform);
184
185 void set_prev_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
186 INLINE CPT(TransformState) get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const;
187 void reset_prev_transform(Thread *current_thread = Thread::get_current_thread());
188 INLINE bool has_dirty_prev_transform() const;
189 static void reset_all_prev_transform(Thread *current_thread = Thread::get_current_thread());
190 MAKE_PROPERTY(prev_transform, get_prev_transform);
191
192 void set_tag(const std::string &key, const std::string &value,
193 Thread *current_thread = Thread::get_current_thread());
194 INLINE std::string get_tag(const std::string &key,
195 Thread *current_thread = Thread::get_current_thread()) const;
196 INLINE bool has_tag(const std::string &key,
197 Thread *current_thread = Thread::get_current_thread()) const;
198 void clear_tag(const std::string &key,
199 Thread *current_thread = Thread::get_current_thread());
200
201public:
202 void get_tag_keys(vector_string &keys) const;
203 INLINE size_t get_num_tags() const;
204 INLINE std::string get_tag_key(size_t i) const;
205
206PUBLISHED:
207 MAKE_MAP_PROPERTY(tags, has_tag, get_tag, set_tag, clear_tag);
208 MAKE_MAP_KEYS_SEQ(tags, get_num_tags, get_tag_key);
209
210 EXTENSION(PyObject *get_tag_keys() const);
211
212 EXTENSION(PyObject *get_python_tags());
213 EXTENSION(void set_python_tag(PyObject *key, PyObject *value));
214 EXTENSION(PyObject *get_python_tag(PyObject *key) const);
215 EXTENSION(bool has_python_tag(PyObject *key) const);
216 EXTENSION(void clear_python_tag(PyObject *key));
217 EXTENSION(PyObject *get_python_tag_keys() const);
218 MAKE_PROPERTY(python_tags, get_python_tags);
219
220 EXTENSION(int __traverse__(visitproc visit, void *arg));
221
222 INLINE bool has_tags() const;
223 void copy_tags(PandaNode *other);
224 void list_tags(std::ostream &out, const std::string &separator = "\n") const;
225
226 int compare_tags(const PandaNode *other) const;
227
228 void copy_all_properties(PandaNode *other);
229 void replace_node(PandaNode *other);
230
231 enum UnexpectedChange {
232 UC_parents = 0x001,
233 UC_children = 0x002,
234 UC_transform = 0x004,
235 UC_state = 0x008,
236 UC_draw_mask = 0x010,
237 };
238 void set_unexpected_change(unsigned int flags);
239 unsigned int get_unexpected_change(unsigned int flags) const;
240 void clear_unexpected_change(unsigned int flags);
241
242 INLINE static DrawMask get_overall_bit();
243 INLINE static DrawMask get_all_camera_mask();
244 INLINE bool is_overall_hidden() const;
245 INLINE void set_overall_hidden(bool overall_hidden);
246 MAKE_PROPERTY(overall_bit, get_overall_bit);
247 MAKE_PROPERTY(all_camera_mask, get_all_camera_mask);
248 MAKE_PROPERTY(overall_hidden, is_overall_hidden, set_overall_hidden);
249
250 void adjust_draw_mask(DrawMask show_mask,
251 DrawMask hide_mask,
252 DrawMask clear_mask);
253 INLINE DrawMask get_draw_control_mask() const;
254 INLINE DrawMask get_draw_show_mask() const;
255 MAKE_PROPERTY(draw_control_mask, get_draw_control_mask);
256 MAKE_PROPERTY(draw_show_mask, get_draw_show_mask);
257
258 DrawMask get_net_draw_control_mask() const;
259 DrawMask get_net_draw_show_mask() const;
260
261 void set_into_collide_mask(CollideMask mask);
262 INLINE CollideMask get_into_collide_mask() const;
263 virtual CollideMask get_legal_collide_mask() const;
264 MAKE_PROPERTY(into_collide_mask, get_into_collide_mask, set_into_collide_mask);
265 MAKE_PROPERTY(legal_collide_mask, get_legal_collide_mask);
266
267 CollideMask get_net_collide_mask(Thread *current_thread = Thread::get_current_thread()) const;
268 CPT(RenderAttrib) get_off_clip_planes(Thread *current_thread = Thread::get_current_thread()) const;
269
270 void prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state);
271
272 bool is_scene_root() const;
273 bool is_under_scene_root() const;
274
275 virtual void output(std::ostream &out) const;
276 virtual void write(std::ostream &out, int indent_level) const;
277
278 INLINE void ls(std::ostream &out, int indent_level) const;
279
280 // A node has three bounding volumes: an "external" bounding volume that
281 // represents the node and all of its children, an "internal" bounding
282 // volume which represents only the node itself (and is usually empty,
283 // unless a specific node type sets it otherwise), and a "user" bounding
284 // volume which is specified by the user.
285
286 // We define set_bounds() and get_bounds() functions so that set_bounds()
287 // sets the user bounding volume, while get_bounds() returns the external
288 // bounding volume. Although it might seem strange and confusing to do
289 // this, this is actually the natural way the user thinks about nodes and
290 // bounding volumes.
291 void set_bounds_type(BoundingVolume::BoundsType bounds_type);
292 BoundingVolume::BoundsType get_bounds_type() const;
293 MAKE_PROPERTY(bounds_type, get_bounds_type, set_bounds_type);
294
295 void set_bounds(const BoundingVolume *volume);
296 void set_bound(const BoundingVolume *volume);
297 INLINE void clear_bounds();
298 CPT(BoundingVolume) get_bounds(Thread *current_thread = Thread::get_current_thread()) const;
299 CPT(BoundingVolume) get_bounds(UpdateSeq &seq, Thread *current_thread = Thread::get_current_thread()) const;
300 int get_nested_vertices(Thread *current_thread = Thread::get_current_thread()) const;
301 INLINE CPT(BoundingVolume) get_internal_bounds(Thread *current_thread = Thread::get_current_thread()) const;
302 INLINE int get_internal_vertices(Thread *current_thread = Thread::get_current_thread()) const;
303 MAKE_PROPERTY(nested_vertices, get_nested_vertices);
304 MAKE_PROPERTY(internal_bounds, get_internal_bounds);
305 MAKE_PROPERTY(internal_vertices, get_internal_vertices);
306
307 void mark_bounds_stale(Thread *current_thread = Thread::get_current_thread()) const;
308 void mark_internal_bounds_stale(Thread *current_thread = Thread::get_current_thread());
309 INLINE bool is_bounds_stale() const;
310 MAKE_PROPERTY(bounds_stale, is_bounds_stale);
311
312 INLINE void set_final(bool flag);
313 INLINE bool is_final(Thread *current_thread = Thread::get_current_thread()) const;
314 MAKE_PROPERTY(final, is_final, set_final);
315
316 virtual bool is_geom_node() const;
317 virtual bool is_lod_node() const;
318 virtual bool is_collision_node() const;
319 virtual Light *as_light();
320 virtual bool is_ambient_light() const;
321
322 enum FancyBits {
323 FB_transform = 0x0001,
324 FB_state = 0x0002,
325 FB_effects = 0x0004,
326 FB_tag = 0x0010,
327 FB_draw_mask = 0x0020,
328 FB_cull_callback = 0x0040,
329 };
330 INLINE int get_fancy_bits(Thread *current_thread = Thread::get_current_thread()) const;
331
332PUBLISHED:
333 static PT(PandaNode) decode_from_bam_stream(vector_uchar data, BamReader *reader = nullptr);
334
335protected:
336 class BoundsData;
337
338 INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage, Thread *current_thread) const;
339 CPT(BoundingVolume) get_internal_bounds(int pipeline_stage, Thread *current_thread) const;
340 int get_internal_vertices(int pipeline_stage, Thread *current_thread) const;
341 void set_internal_bounds(const BoundingVolume *volume);
342
343 INLINE void mark_bounds_stale(int pipeline_stage, Thread *current_thread) const;
344 void force_bounds_stale(Thread *current_thread = Thread::get_current_thread());
345 void force_bounds_stale(int pipeline_stage, Thread *current_thread);
346 INLINE void mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread);
347
348 virtual void r_mark_geom_bounds_stale(Thread *current_thread);
349
350 virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
351 int &internal_vertices,
352 int pipeline_stage,
353 Thread *current_thread) const;
354 virtual void parents_changed();
355 virtual void children_changed();
356 virtual void transform_changed();
357 virtual void state_changed();
358 virtual void draw_mask_changed();
359
360 typedef pmap<PandaNode *, PandaNode *> InstanceMap;
361 virtual PT(PandaNode) r_copy_subgraph(InstanceMap &inst_map,
362 Thread *current_thread) const;
363 virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map,
364 Thread *current_thread);
365
366 void set_cull_callback();
367 void disable_cull_callback();
368public:
369 virtual void r_prepare_scene(GraphicsStateGuardianBase *gsg,
370 const RenderState *node_state,
371 GeomTransformer &transformer,
372 Thread *current_thread);
373
374protected:
375 // This is a base class of CData, defined below. It contains just the
376 // protected (not private) part of CData that will be needed by derived
377 // classes to implement compute_internal_bounds().
378 class EXPCL_PANDA_PGRAPH BoundsData : public CycleData {
379 protected:
380 INLINE BoundsData();
381 INLINE BoundsData(const BoundsData &copy);
382 INLINE void copy_bounds(const BoundsData &copy);
383
384 public:
385 // This is the "internal" bounding volume, which is normally empty, but
386 // which a particular PandaNode subclass may define to be any arbitrary
387 // volume, by calling set_internal_bounds() or by overriding
388 // compute_internal_bounds().
389 CPT(BoundingVolume) _internal_bounds;
390 int _internal_vertices;
391 UpdateSeq _internal_bounds_mark; // incremented on mark_stale
392 UpdateSeq _internal_bounds_computed; // set to above when computing
393 };
394
395private:
396 class CData;
397
398 INLINE int do_find_parent(PandaNode *node, const CData *cdata) const;
399 bool stage_remove_child(PandaNode *child_node, int pipeline_stage,
400 Thread *current_thread);
401 bool stage_replace_child(PandaNode *orig_child, PandaNode *new_child,
402 int pipeline_stage, Thread *current_thread);
403
404 void quick_add_new_child(PandaNode *child_node, int sort,
405 Thread *current_thread);
406
407 INLINE bool verify_child_no_cycles(PandaNode *child_node);
408 void report_cycle(PandaNode *node);
409 bool find_node_above(PandaNode *node);
410
411 // parent-child manipulation for NodePath support. Don't try to call these
412 // directly.
413 static PT(NodePathComponent) attach(NodePathComponent *parent,
414 PandaNode *child, int sort,
415 int pipeline_stage, Thread *current_thread);
416 static void detach(NodePathComponent *child, int pipeline_stage, Thread *current_thread);
417 static void detach_one_stage(NodePathComponent *child, int pipeline_stage, Thread *current_thread);
418 static bool reparent(NodePathComponent *new_parent,
419 NodePathComponent *child, int sort, bool as_stashed,
420 int pipeline_stage, Thread *current_thread);
421 static bool reparent_one_stage(NodePathComponent *new_parent,
422 NodePathComponent *child, int sort,
423 bool as_stashed, int pipeline_stage, Thread *current_thread);
424 static PT(NodePathComponent) get_component(NodePathComponent *parent,
425 PandaNode *child,
426 int pipeline_stage, Thread *current_thread);
427 static PT(NodePathComponent) get_top_component(PandaNode *child, bool force,
428 int pipeline_stage, Thread *current_thread);
429 PT(NodePathComponent) get_generic_component(bool accept_ambiguity,
430 int pipeline_stage, Thread *current_thread);
431 PT(NodePathComponent) r_get_generic_component(bool accept_ambiguity,
432 bool &ambiguity_detected,
433 int pipeline_stage, Thread *current_thread);
434 void delete_component(NodePathComponent *component);
435 static void sever_connection(PandaNode *parent_node, PandaNode *child_node,
436 int pipeline_stage, Thread *current_thread);
437 static void new_connection(PandaNode *parent_node, PandaNode *child_node,
438 int pipeline_stage, Thread *current_thread);
439 void fix_path_lengths(int pipeline_stage, Thread *current_thread);
440 void r_list_descendants(std::ostream &out, int indent_level) const;
441
442 INLINE void do_set_dirty_prev_transform();
443 INLINE void do_clear_dirty_prev_transform();
444
445public:
446 // This must be declared public so that VC6 will allow the nested CData
447 // class to access it.
448 class EXPCL_PANDA_PGRAPH DownConnection {
449 public:
450 INLINE DownConnection(PandaNode *child, int sort);
451 INLINE bool operator < (const DownConnection &other) const;
452 INLINE PandaNode *get_child() const;
453 INLINE void set_child(PandaNode *child);
454 INLINE int get_sort() const;
455
456 private:
457 // Child pointers are reference counted. That way, holding a pointer to
458 // the root of a subgraph keeps the entire subgraph around.
459 PT(PandaNode) _child;
460 int _sort;
461 };
462
463private:
466
467 // Store a pointer to the down_list during the bam read pass.
468 class EXPCL_PANDA_PGRAPH BamReaderAuxDataDown : public BamReaderAuxData {
469 public:
470 INLINE BamReaderAuxDataDown();
471 Down _down_list;
472 public:
473 virtual TypeHandle get_type() const {
474 return get_class_type();
475 }
476 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
477 static TypeHandle get_class_type() {
478 return _type_handle;
479 }
480
481 public:
482 static void init_type() {
483 BamReaderAuxData::init_type();
484 register_type(_type_handle, "BamReaderAuxDataDown",
485 BamReaderAuxData::get_class_type());
486 }
487
488 private:
489 static TypeHandle _type_handle;
490 };
491
492 class EXPCL_PANDA_PGRAPH UpConnection {
493 public:
494 INLINE UpConnection(PandaNode *child);
495 INLINE bool operator < (const UpConnection &other) const;
496 INLINE PandaNode *get_parent() const;
497
498 private:
499 // Parent pointers are not reference counted. That way, parents and
500 // children do not circularly reference each other.
501 PandaNode *_parent;
502 };
503 typedef ov_set<UpConnection> UpList;
505
506 // We also maintain a set of NodePathComponents in the node. This
507 // represents the set of instances of this node that we have requested a
508 // NodePath for. We don't keep reference counts; when each
509 // NodePathComponent destructs, it removes itself from this set.
510 typedef phash_set<NodePathComponent *, pointer_hash> Paths;
511
512 // We don't cycle the set of Paths, since these are across all threads. A
513 // NodePathComponent, once created, is always associated with the same node.
514 // We do, however, protect the Paths under a mutex.
515 Paths _paths;
516 LightReMutex _paths_lock;
517
518 bool _dirty_prev_transform;
519 static PandaNodeChain _dirty_prev_transforms;
520
521 // This is used to maintain a table of keyed data on each node, for the
522 // user's purposes.
524
525 // This is actually implemented in pandaNode_ext.h, but defined here so
526 // that we can destruct it from the C++ side. Note that it isn't cycled,
527 // because I imagine it's rare to see a Python thread on a stage other than
528 // stage 0, and let's not make things unnecessarily complicated.
529 class PythonTagData : public ReferenceCount {
530 public:
531 virtual ~PythonTagData() {};
532 };
533 PT(PythonTagData) _python_tag_data;
534
535 unsigned int _unexpected_change_flags = 0;
536
537 // This is the data that must be cycled between pipeline stages.
538
539 class EXPCL_PANDA_PGRAPH CData : public BoundsData {
540 public:
541 CData();
542 CData(const CData &copy);
543 virtual ~CData();
544 ALLOC_DELETED_CHAIN(CData);
545
546 virtual CycleData *make_copy() const;
547 virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
548 void update_bam_nested(BamWriter *manager) const;
549 virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
550 virtual void fillin(DatagramIterator &scan, BamReader *manager);
551 virtual TypeHandle get_parent_type() const {
552 return PandaNode::get_class_type();
553 }
554
555 public:
556 // This section contains the lightweight parts of the node that are likely
557 // to change fairly often: transform and state.
558
559 NCPT(RenderState) _state;
560 NCPT(TransformState) _transform;
561 NCPT(TransformState) _prev_transform;
562
563 public:
564 // This section contains the heavierweight parts of the node that are less
565 // likely to change as often: tags, collide mask.
566
567 INLINE void set_fancy_bit(int bits, bool value);
568
569#ifdef HAVE_PYTHON
570 void inc_py_refs();
571 void dec_py_refs();
572#endif
573
574 CPT(RenderEffects) _effects;
575
576 TagData _tag_data;
577
578 // These two together determine the per-camera visibility of this node.
579 // See adjust_draw_mask() for details.
580 DrawMask _draw_control_mask, _draw_show_mask;
581
582 // This is the mask that indicates which CollisionNodes may detect a
583 // collision with this particular node. By default it is zero for an
584 // ordinary PandaNode, and all bits on for a CollisionNode or GeomNode.
585 CollideMask _into_collide_mask;
586
587 // The requested bounding volume type.
588 BoundingVolume::BoundsType _bounds_type;
589
590 // This is the user bounding volume, which is only specified by a user.
591 // It defaults to NULL, which means an empty volume.
592 CPT(BoundingVolume) _user_bounds;
593
594 // See BoundsData, above, for _internal_bounds.
595
596 // This is true if the external bounds of this node should be deemed
597 // "final". See set_final().
598 bool _final_bounds;
599
600 // This bitmask is maintained automatically by the internal PandaNode
601 // code; it contains a 1 for each "fancy" attribute that is set on the
602 // node. See enum FancyBits, above.
603 int _fancy_bits;
604
605 public:
606 // This section contains the data that is accumulated upward from the
607 // node's children: that is, the external bounding volume, and
608 // conceptually similar things like the net_collide_mask, etc. None of
609 // the data in this object is preserved in a bam file.
610
611 // This is the union of all into_collide_mask bits for any nodes at and
612 // below this level.
613 CollideMask _net_collide_mask;
614
615 // These are similar, for the draw mask.
616 DrawMask _net_draw_control_mask, _net_draw_show_mask;
617
618 // This is a ClipPlaneAttrib that represents the union of all clip planes
619 // that have been turned *off* at and below this level. TODO: fix the
620 // circular reference counts involved here.
621 CPT(RenderAttrib) _off_clip_planes;
622
623 // The number of vertices rendered by this node and all child nodes.
624 int _nested_vertices;
625
626 // This is the bounding volume around the _user_bounds, the
627 // _internal_bounds, and all of the children's external bounding volumes.
628 CPT(BoundingVolume) _external_bounds;
629
630 // When _last_update != _next_update, this cache is stale.
631 UpdateSeq _last_update, _next_update;
632
633 // We don't always update the bounding volume and number of nested
634 // vertices. This indicates the last time they were changed. It is never
635 // higher than _last_update.
636 UpdateSeq _last_bounds_update;
637
638 public:
639 // This section stores the links to other nodes above and below this node
640 // in the graph.
641
642 void write_up_list(const Up &up_list,
643 BamWriter *manager, Datagram &dg) const;
644 void write_down_list(const Down &down_list,
645 BamWriter *manager, Datagram &dg) const;
646 void update_up_list(const Up &up_list, BamWriter *manager) const;
647 void update_down_list(const Down &down_list, BamWriter *manager) const;
648 int complete_up_list(Up &up_list, const std::string &tag,
649 TypedWritable **p_list, BamReader *manager);
650 int complete_down_list(Down &down_list, const std::string &tag,
651 TypedWritable **p_list, BamReader *manager);
652 void fillin_up_list(Up &up_list, const std::string &tag,
653 DatagramIterator &scan, BamReader *manager);
654 void fillin_down_list(Down &down_list, const std::string &tag,
655 DatagramIterator &scan, BamReader *manager);
656
657 INLINE CPT(Down) get_down() const;
658 INLINE PT(Down) modify_down();
659 INLINE CPT(Down) get_stashed() const;
660 INLINE PT(Down) modify_stashed();
661 INLINE CPT(Up) get_up() const;
662 INLINE PT(Up) modify_up();
663
664 private:
665 // We store the child lists by reference, so we can copy them quickly. We
666 // perform copy-on-write when necessary.
667 COWPT(Down) _down;
668 COWPT(Down) _stashed;
669 COWPT(Up) _up;
670
671 public:
672 static TypeHandle get_class_type() {
673 return _type_handle;
674 }
675 static void init_type() {
676 register_type(_type_handle, "PandaNode::CData");
677 }
678
679 private:
680 static TypeHandle _type_handle;
681 };
682
683 PipelineCycler<CData> _cycler;
684 typedef CycleDataReader<CData> CDReader;
685 typedef CycleDataWriter<CData> CDWriter;
686 typedef CycleDataLockedStageReader<CData> CDLockedStageReader;
687 typedef CycleDataStageReader<CData> CDStageReader;
688 typedef CycleDataStageWriter<CData> CDStageWriter;
689
690 int do_find_child(PandaNode *node, const Down *down) const;
691 CDStageWriter update_cached(bool update_bounds, int pipeline_stage,
692 CDLockedStageReader &cdata);
693
694 static DrawMask _overall_bit;
695
696 static PStatCollector _reset_prev_pcollector;
697 static PStatCollector _update_bounds_pcollector;
698
699PUBLISHED:
700 // This class is returned from get_children(). Use it to walk through the
701 // list of children. This is faster, and safer, than walking through the
702 // children one at a time via get_num_children()/get_child(), since the list
703 // of children is saved out ahead of time, rather than having to reacquire
704 // the lock with each iteration, or to keep the lock held for the entire
705 // pass.
706 class EXPCL_PANDA_PGRAPH Children {
707 public:
708 INLINE Children();
709 INLINE Children(const CData *cdata);
710 INLINE Children(const Children &copy);
711 INLINE Children(Children &&from) noexcept;
712
713 INLINE void operator = (const Children &copy);
714 INLINE void operator = (Children &&from) noexcept;
715
716 INLINE size_t get_num_children() const;
717 INLINE PandaNode *get_child(size_t n) const;
718 INLINE int get_child_sort(size_t n) const;
719
720 PUBLISHED:
721 INLINE PandaNode *operator [](size_t n) const { return get_child(n); }
722 INLINE size_t size() const { return get_num_children(); }
723
724 private:
725 CPT(Down) _down;
726 };
727
728 // Similarly for stashed children.
729 class EXPCL_PANDA_PGRAPH Stashed {
730 public:
731 INLINE Stashed();
732 INLINE Stashed(const CData *cdata);
733 INLINE Stashed(const Stashed &copy);
734 INLINE Stashed(Stashed &&from) noexcept;
735
736 INLINE void operator = (const Stashed &copy);
737 INLINE void operator = (Stashed &&from) noexcept;
738
739 INLINE size_t get_num_stashed() const;
740 INLINE PandaNode *get_stashed(size_t n) const;
741 INLINE int get_stashed_sort(size_t n) const;
742
743 PUBLISHED:
744 INLINE PandaNode *operator [](size_t n) const { return get_stashed(n); }
745 INLINE size_t size() const { return get_num_stashed(); }
746
747 private:
748 CPT(Down) _stashed;
749 };
750
751 // This class is returned from get_parents().
752 class EXPCL_PANDA_PGRAPH Parents {
753 public:
754 INLINE Parents();
755 INLINE Parents(const CData *cdata);
756 INLINE Parents(const Parents &copy);
757 INLINE Parents(Parents &&from) noexcept;
758
759 INLINE void operator = (const Parents &copy);
760 INLINE void operator = (Parents &&from) noexcept;
761
762 INLINE size_t get_num_parents() const;
763 INLINE PandaNode *get_parent(size_t n) const;
764
765 PUBLISHED:
766 INLINE PandaNode *operator [](size_t n) const { return get_parent(n); }
767 INLINE size_t size() const { return get_num_parents(); }
768
769 private:
770 CPT(Up) _up;
771 };
772
773public:
774 INLINE Children get_children(Thread *current_thread = Thread::get_current_thread()) const;
775 INLINE Stashed get_stashed(Thread *current_thread = Thread::get_current_thread()) const;
776 INLINE Parents get_parents(Thread *current_thread = Thread::get_current_thread()) const;
777
778 typedef bool SceneRootFunc(const PandaNode *);
779 static void set_scene_root_func(SceneRootFunc *func);
780
781PUBLISHED:
782 MAKE_PROPERTY(children, get_children);
783 MAKE_PROPERTY(stashed, get_stashed);
784 MAKE_PROPERTY(parents, get_parents);
785
786private:
787 static SceneRootFunc *_scene_root_func;
788
789public:
790 static void register_with_read_factory();
791 virtual void write_datagram(BamWriter *manager, Datagram &dg);
792 virtual void update_bam_nested(BamWriter *manager);
793 void write_recorder(BamWriter *manager, Datagram &dg);
794
795protected:
796 static TypedWritable *make_from_bam(const FactoryParams &params);
797 void fillin(DatagramIterator &scan, BamReader *manager);
798 void fillin_recorder(DatagramIterator &scan, BamReader *manager);
799
800public:
801 static TypeHandle get_class_type() {
802 return _type_handle;
803 }
804 static void init_type() {
805 TypedWritableReferenceCount::init_type();
806 Namable::init_type();
807 register_type(_type_handle, "PandaNode",
808 TypedWritableReferenceCount::get_class_type(),
809 Namable::get_class_type());
810 CData::init_type();
811 Down::init_type();
812 Up::init_type();
813 BamReaderAuxDataDown::init_type();
814 }
815 virtual TypeHandle get_type() const {
816 return get_class_type();
817 }
818 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
819
820private:
821 static TypeHandle _type_handle;
822
823#ifndef DO_PIPELINING
824 friend class PandaNode::Children;
825 friend class PandaNode::Stashed;
826#endif
827 friend class NodePath;
828 friend class NodePathComponent;
829 friend class WorkingNodePath;
830 friend class PandaNodePipelineReader;
831 friend class EggLoader;
832 friend class Extension<PandaNode>;
833 friend class CullTraverserData;
834};
835
836/**
837 * Encapsulates the data from a PandaNode, pre-fetched for one stage of the
838 * pipeline.
839 */
840class EXPCL_PANDA_PGRAPH PandaNodePipelineReader {
841public:
842 INLINE PandaNodePipelineReader(const PandaNode *object, Thread *current_thread);
844 INLINE void operator = (const PandaNodePipelineReader &copy);
845
846public:
848 ALLOC_DELETED_CHAIN(PandaNodePipelineReader);
849
850 INLINE const PandaNode *get_node() const;
851 INLINE Thread *get_current_thread() const;
852
853 INLINE void release();
854
855 void check_cached(bool update_bounds) const;
856
857 INLINE void compose_draw_mask(DrawMask &running_draw_mask) const;
858 INLINE bool compare_draw_mask(DrawMask running_draw_mask,
859 DrawMask camera_mask) const;
860
861 INLINE int get_num_parents() const;
862 INLINE PandaNode *get_parent(int n) const;
863 INLINE int find_parent(PandaNode *node) const;
864
865 INLINE int get_num_children() const;
866 INLINE PandaNode *get_child(int n) const;
867 INLINE int get_child_sort(int n) const;
868 INLINE int find_child(PandaNode *node) const;
869
870 INLINE int get_num_stashed() const;
871 INLINE PandaNode *get_stashed(int n) const;
872 INLINE int get_stashed_sort(int n) const;
873 INLINE int find_stashed(PandaNode *node) const;
874
875 INLINE const RenderState *get_state() const;
876 INLINE const RenderEffects *get_effects() const;
877 INLINE const TransformState *get_transform() const;
878 INLINE const TransformState *get_prev_transform() const;
879
880 INLINE std::string get_tag(const std::string &key) const;
881 INLINE bool has_tag(const std::string &key) const;
882
883 INLINE CollideMask get_into_collide_mask() const;
884 INLINE CollideMask get_net_collide_mask() const;
885 INLINE const RenderAttrib *get_off_clip_planes() const;
886 INLINE const BoundingVolume *get_bounds() const;
887 INLINE int get_nested_vertices() const;
888 INLINE bool is_final() const;
889 INLINE int get_fancy_bits() const;
890
891 INLINE PandaNode::Children get_children() const;
892 INLINE PandaNode::Stashed get_stashed() const;
893 INLINE PandaNode::Parents get_parents() const;
894
895private:
896 const PandaNode *_node;
897 Thread *_current_thread;
898
899 const PandaNode::CData *_cdata;
900
901public:
902 static TypeHandle get_class_type() {
903 return _type_handle;
904 }
905 static void init_type() {
906 register_type(_type_handle, "PandaNodePipelineReader");
907 }
908
909private:
910 static TypeHandle _type_handle;
911
912};
913
914// We can safely redefine this as a no-op.
915template<>
916INLINE void PointerToBase<PandaNode>::update_type(To *ptr) {}
917
918INLINE std::ostream &operator << (std::ostream &out, const PandaNode &node) {
919 node.output(out);
920 return out;
921}
922
923#include "pandaNode.I"
924
925#endif
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
Stores auxiliary data that may be piggybacked on the BamReader during each object's read pass.
Definition bamReader.h:61
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
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 class is similar to CycleDataLockedReader, except it allows reading from a particular stage of t...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A single page of data maintained by a PipelineCycler.
Definition cycleData.h:50
A class to retrieve the individual data elements previously stored in a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
Converts an egg data structure, possibly read from an egg file but not necessarily,...
Definition eggLoader.h:67
The default class template does not define any methods.
Definition extension.h:34
An instance of this class is passed to the Factory when requesting it to do its business and construc...
An object specifically designed to transform the vertices of a Geom without disturbing indexing or af...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A lightweight reentrant mutex.
The abstract interface to all kinds of lights.
Definition light.h:38
This just stores the pointers to implement a doubly-linked list of some kind of object.
A base class for all things which can have a name.
Definition namable.h:26
void output(std::ostream &out) const
Outputs the Namable.
Definition namable.I:61
This is one component of a NodePath.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
A lightweight class that represents a single element that may be timed and/or counted via stats.
This class maintains a linked list of PandaNodes.
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
Definition pandaNode.h:840
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
This is the base class for PointerTo and ConstPointerTo.
A base class for all things that want to be reference-counted.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
This is the base class for a number of special render effects that may be set on scene graph nodes to...
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition renderState.h:47
This template class implements an unordered map of keys to data, implemented as a hashtable.
A thread; that is, a lightweight process.
Definition thread.h:46
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
Indicates a coordinate-system transform on vertices.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
Base class for objects that can be written to and read from Bam files.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
virtual void update_bam_nested(BamWriter *manager)
Called by the BamWriter when this object has not itself been modified recently, but it should check i...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
This is a class designed to support low-overhead traversals of the complete scene graph,...
A specialization of ordered_vector that emulates a standard STL set: many copies of each element are ...
A specialization of ordered_vector that emulates a standard STL set: one copy of each element is allo...
This is our own Panda specialization on the default STL list.
Definition plist.h:35
This is our own Panda specialization on the default STL map.
Definition pmap.h:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class maintains different copies of a page of data between stages of the graphics pipeline (or a...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.