Panda3D
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"
23 #include "cycleDataStageReader.h"
24 #include "cycleDataStageWriter.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 
50 class NodePathComponent;
51 class CullTraverser;
52 class CullTraverserData;
53 class Light;
54 class FactoryParams;
55 class AccumulatedAttribs;
56 class 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  */
64 class EXPCL_PANDA_PGRAPH PandaNode : public TypedWritableReferenceCount,
65  public Namable, public LinkedListNode {
66 PUBLISHED:
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 
72 protected:
73  PandaNode(const PandaNode &copy);
74 
75  PandaNode &operator = (const PandaNode &copy) = delete;
76 
77 public:
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 
108 PUBLISHED:
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 
201 public:
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 
206 PUBLISHED:
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);
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 
332 PUBLISHED:
333  static PT(PandaNode) decode_from_bam_stream(vector_uchar data, BamReader *reader = nullptr);
334 
335 protected:
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();
368 public:
369  virtual void r_prepare_scene(GraphicsStateGuardianBase *gsg,
370  const RenderState *node_state,
371  GeomTransformer &transformer,
372  Thread *current_thread);
373 
374 protected:
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 
395 private:
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 
445 public:
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 
463 private:
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 #ifndef NDEBUG
536  unsigned int _unexpected_change_flags;
537 #endif // !NDEBUG
538 
539  // This is the data that must be cycled between pipeline stages.
540 
541  class EXPCL_PANDA_PGRAPH CData : public BoundsData {
542  public:
543  CData();
544  CData(const CData &copy);
545  virtual ~CData();
546  ALLOC_DELETED_CHAIN(CData);
547 
548  virtual CycleData *make_copy() const;
549  virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
550  void update_bam_nested(BamWriter *manager) const;
551  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
552  virtual void fillin(DatagramIterator &scan, BamReader *manager);
553  virtual TypeHandle get_parent_type() const {
554  return PandaNode::get_class_type();
555  }
556 
557  public:
558  // This section contains the lightweight parts of the node that are likely
559  // to change fairly often: transform and state.
560 
561  NCPT(RenderState) _state;
562  NCPT(TransformState) _transform;
563  NCPT(TransformState) _prev_transform;
564 
565  public:
566  // This section contains the heavierweight parts of the node that are less
567  // likely to change as often: tags, collide mask.
568 
569  INLINE void set_fancy_bit(int bits, bool value);
570 
571 #ifdef HAVE_PYTHON
572  void inc_py_refs();
573  void dec_py_refs();
574 #endif
575 
576  CPT(RenderEffects) _effects;
577 
578  TagData _tag_data;
579 
580  // These two together determine the per-camera visibility of this node.
581  // See adjust_draw_mask() for details.
582  DrawMask _draw_control_mask, _draw_show_mask;
583 
584  // This is the mask that indicates which CollisionNodes may detect a
585  // collision with this particular node. By default it is zero for an
586  // ordinary PandaNode, and all bits on for a CollisionNode or GeomNode.
587  CollideMask _into_collide_mask;
588 
589  // The requested bounding volume type.
590  BoundingVolume::BoundsType _bounds_type;
591 
592  // This is the user bounding volume, which is only specified by a user.
593  // It defaults to NULL, which means an empty volume.
594  CPT(BoundingVolume) _user_bounds;
595 
596  // See BoundsData, above, for _internal_bounds.
597 
598  // This is true if the external bounds of this node should be deemed
599  // "final". See set_final().
600  bool _final_bounds;
601 
602  // This bitmask is maintained automatically by the internal PandaNode
603  // code; it contains a 1 for each "fancy" attribute that is set on the
604  // node. See enum FancyBits, above.
605  int _fancy_bits;
606 
607  public:
608  // This section contains the data that is accumulated upward from the
609  // node's children: that is, the external bounding volume, and
610  // conceptually similar things like the net_collide_mask, etc. None of
611  // the data in this object is preserved in a bam file.
612 
613  // This is the union of all into_collide_mask bits for any nodes at and
614  // below this level.
615  CollideMask _net_collide_mask;
616 
617  // These are similar, for the draw mask.
618  DrawMask _net_draw_control_mask, _net_draw_show_mask;
619 
620  // This is a ClipPlaneAttrib that represents the union of all clip planes
621  // that have been turned *off* at and below this level. TODO: fix the
622  // circular reference counts involved here.
623  CPT(RenderAttrib) _off_clip_planes;
624 
625  // The number of vertices rendered by this node and all child nodes.
626  int _nested_vertices;
627 
628  // This is the bounding volume around the _user_bounds, the
629  // _internal_bounds, and all of the children's external bounding volumes.
630  CPT(BoundingVolume) _external_bounds;
631 
632  // When _last_update != _next_update, this cache is stale.
633  UpdateSeq _last_update, _next_update;
634 
635  // We don't always update the bounding volume and number of nested
636  // vertices. This indicates the last time they were changed. It is never
637  // higher than _last_update.
638  UpdateSeq _last_bounds_update;
639 
640  public:
641  // This section stores the links to other nodes above and below this node
642  // in the graph.
643 
644  void write_up_list(const Up &up_list,
645  BamWriter *manager, Datagram &dg) const;
646  void write_down_list(const Down &down_list,
647  BamWriter *manager, Datagram &dg) const;
648  void update_up_list(const Up &up_list, BamWriter *manager) const;
649  void update_down_list(const Down &down_list, BamWriter *manager) const;
650  int complete_up_list(Up &up_list, const std::string &tag,
651  TypedWritable **p_list, BamReader *manager);
652  int complete_down_list(Down &down_list, const std::string &tag,
653  TypedWritable **p_list, BamReader *manager);
654  void fillin_up_list(Up &up_list, const std::string &tag,
655  DatagramIterator &scan, BamReader *manager);
656  void fillin_down_list(Down &down_list, const std::string &tag,
657  DatagramIterator &scan, BamReader *manager);
658 
659  INLINE CPT(Down) get_down() const;
660  INLINE PT(Down) modify_down();
661  INLINE CPT(Down) get_stashed() const;
662  INLINE PT(Down) modify_stashed();
663  INLINE CPT(Up) get_up() const;
664  INLINE PT(Up) modify_up();
665 
666  private:
667  // We store the child lists by reference, so we can copy them quickly. We
668  // perform copy-on-write when necessary.
669  COWPT(Down) _down;
670  COWPT(Down) _stashed;
671  COWPT(Up) _up;
672 
673  public:
674  static TypeHandle get_class_type() {
675  return _type_handle;
676  }
677  static void init_type() {
678  register_type(_type_handle, "PandaNode::CData");
679  }
680 
681  private:
682  static TypeHandle _type_handle;
683  };
684 
685  PipelineCycler<CData> _cycler;
686  typedef CycleDataReader<CData> CDReader;
687  typedef CycleDataWriter<CData> CDWriter;
688  typedef CycleDataLockedStageReader<CData> CDLockedStageReader;
689  typedef CycleDataStageReader<CData> CDStageReader;
690  typedef CycleDataStageWriter<CData> CDStageWriter;
691 
692  int do_find_child(PandaNode *node, const Down *down) const;
693  CDStageWriter update_cached(bool update_bounds, int pipeline_stage,
694  CDLockedStageReader &cdata);
695 
696  static DrawMask _overall_bit;
697 
698  static PStatCollector _reset_prev_pcollector;
699  static PStatCollector _update_bounds_pcollector;
700 
701 PUBLISHED:
702  // This class is returned from get_children(). Use it to walk through the
703  // list of children. This is faster, and safer, than walking through the
704  // children one at a time via get_num_children()/get_child(), since the list
705  // of children is saved out ahead of time, rather than having to reacquire
706  // the lock with each iteration, or to keep the lock held for the entire
707  // pass.
708  class EXPCL_PANDA_PGRAPH Children {
709  public:
710  INLINE Children();
711  INLINE Children(const CData *cdata);
712  INLINE Children(const Children &copy);
713  INLINE Children(Children &&from) noexcept;
714 
715  INLINE void operator = (const Children &copy);
716  INLINE void operator = (Children &&from) noexcept;
717 
718  INLINE size_t get_num_children() const;
719  INLINE PandaNode *get_child(size_t n) const;
720  INLINE int get_child_sort(size_t n) const;
721 
722  PUBLISHED:
723  INLINE PandaNode *operator [](size_t n) const { return get_child(n); }
724  INLINE size_t size() const { return get_num_children(); }
725 
726  private:
727  CPT(Down) _down;
728  };
729 
730  // Similarly for stashed children.
731  class EXPCL_PANDA_PGRAPH Stashed {
732  public:
733  INLINE Stashed();
734  INLINE Stashed(const CData *cdata);
735  INLINE Stashed(const Stashed &copy);
736  INLINE Stashed(Stashed &&from) noexcept;
737 
738  INLINE void operator = (const Stashed &copy);
739  INLINE void operator = (Stashed &&from) noexcept;
740 
741  INLINE size_t get_num_stashed() const;
742  INLINE PandaNode *get_stashed(size_t n) const;
743  INLINE int get_stashed_sort(size_t n) const;
744 
745  PUBLISHED:
746  INLINE PandaNode *operator [](size_t n) const { return get_stashed(n); }
747  INLINE size_t size() const { return get_num_stashed(); }
748 
749  private:
750  CPT(Down) _stashed;
751  };
752 
753  // This class is returned from get_parents().
754  class EXPCL_PANDA_PGRAPH Parents {
755  public:
756  INLINE Parents();
757  INLINE Parents(const CData *cdata);
758  INLINE Parents(const Parents &copy);
759  INLINE Parents(Parents &&from) noexcept;
760 
761  INLINE void operator = (const Parents &copy);
762  INLINE void operator = (Parents &&from) noexcept;
763 
764  INLINE size_t get_num_parents() const;
765  INLINE PandaNode *get_parent(size_t n) const;
766 
767  PUBLISHED:
768  INLINE PandaNode *operator [](size_t n) const { return get_parent(n); }
769  INLINE size_t size() const { return get_num_parents(); }
770 
771  private:
772  CPT(Up) _up;
773  };
774 
775 public:
776  INLINE Children get_children(Thread *current_thread = Thread::get_current_thread()) const;
777  INLINE Stashed get_stashed(Thread *current_thread = Thread::get_current_thread()) const;
778  INLINE Parents get_parents(Thread *current_thread = Thread::get_current_thread()) const;
779 
780  typedef bool SceneRootFunc(const PandaNode *);
781  static void set_scene_root_func(SceneRootFunc *func);
782 
783 PUBLISHED:
784  MAKE_PROPERTY(children, get_children);
785  MAKE_PROPERTY(stashed, get_stashed);
786  MAKE_PROPERTY(parents, get_parents);
787 
788 private:
789  static SceneRootFunc *_scene_root_func;
790 
791 public:
792  static void register_with_read_factory();
793  virtual void write_datagram(BamWriter *manager, Datagram &dg);
794  virtual void update_bam_nested(BamWriter *manager);
795  void write_recorder(BamWriter *manager, Datagram &dg);
796 
797 protected:
798  static TypedWritable *make_from_bam(const FactoryParams &params);
799  void fillin(DatagramIterator &scan, BamReader *manager);
800  void fillin_recorder(DatagramIterator &scan, BamReader *manager);
801 
802 public:
803  static TypeHandle get_class_type() {
804  return _type_handle;
805  }
806  static void init_type() {
807  TypedWritableReferenceCount::init_type();
808  Namable::init_type();
809  register_type(_type_handle, "PandaNode",
810  TypedWritableReferenceCount::get_class_type(),
811  Namable::get_class_type());
812  CData::init_type();
813  Down::init_type();
814  Up::init_type();
815  BamReaderAuxDataDown::init_type();
816  }
817  virtual TypeHandle get_type() const {
818  return get_class_type();
819  }
820  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
821 
822 private:
823  static TypeHandle _type_handle;
824 
825 #ifndef DO_PIPELINING
826  friend class PandaNode::Children;
827  friend class PandaNode::Stashed;
828 #endif
829  friend class NodePath;
830  friend class NodePathComponent;
831  friend class WorkingNodePath;
832  friend class PandaNodePipelineReader;
833  friend class EggLoader;
834  friend class Extension<PandaNode>;
835  friend class CullTraverserData;
836 };
837 
838 /**
839  * Encapsulates the data from a PandaNode, pre-fetched for one stage of the
840  * pipeline.
841  */
842 class EXPCL_PANDA_PGRAPH PandaNodePipelineReader {
843 public:
844  INLINE PandaNodePipelineReader(const PandaNode *object, Thread *current_thread);
846  INLINE void operator = (const PandaNodePipelineReader &copy);
847 
848 public:
849  INLINE ~PandaNodePipelineReader();
850  ALLOC_DELETED_CHAIN(PandaNodePipelineReader);
851 
852  INLINE const PandaNode *get_node() const;
853  INLINE Thread *get_current_thread() const;
854 
855  INLINE void release();
856 
857  void check_cached(bool update_bounds) const;
858 
859  INLINE void compose_draw_mask(DrawMask &running_draw_mask) const;
860  INLINE bool compare_draw_mask(DrawMask running_draw_mask,
861  DrawMask camera_mask) const;
862 
863  INLINE int get_num_parents() const;
864  INLINE PandaNode *get_parent(int n) const;
865  INLINE int find_parent(PandaNode *node) const;
866 
867  INLINE int get_num_children() const;
868  INLINE PandaNode *get_child(int n) const;
869  INLINE int get_child_sort(int n) const;
870  INLINE int find_child(PandaNode *node) const;
871 
872  INLINE int get_num_stashed() const;
873  INLINE PandaNode *get_stashed(int n) const;
874  INLINE int get_stashed_sort(int n) const;
875  INLINE int find_stashed(PandaNode *node) const;
876 
877  INLINE const RenderState *get_state() const;
878  INLINE const RenderEffects *get_effects() const;
879  INLINE const TransformState *get_transform() const;
880  INLINE const TransformState *get_prev_transform() const;
881 
882  INLINE std::string get_tag(const std::string &key) const;
883  INLINE bool has_tag(const std::string &key) const;
884 
885  INLINE CollideMask get_net_collide_mask() const;
886  INLINE const RenderAttrib *get_off_clip_planes() const;
887  INLINE const BoundingVolume *get_bounds() const;
888  INLINE int get_nested_vertices() const;
889  INLINE bool is_final() const;
890  INLINE int get_fancy_bits() const;
891 
892  INLINE PandaNode::Children get_children() const;
893  INLINE PandaNode::Stashed get_stashed() const;
894  INLINE PandaNode::Parents get_parents() const;
895 
896 private:
897  const PandaNode *_node;
898  Thread *_current_thread;
899 
900  const PandaNode::CData *_cdata;
901 
902 public:
903  static TypeHandle get_class_type() {
904  return _type_handle;
905  }
906  static void init_type() {
907  register_type(_type_handle, "PandaNodePipelineReader");
908  }
909 
910 private:
911  static TypeHandle _type_handle;
912 
913 };
914 
915 // We can safely redefine this as a no-op.
916 template<>
917 INLINE void PointerToBase<PandaNode>::update_type(To *ptr) {}
918 
919 INLINE std::ostream &operator << (std::ostream &out, const PandaNode &node) {
920  node.output(out);
921  return out;
922 }
923 
924 #include "pandaNode.I"
925 
926 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
The abstract interface to all kinds of lights.
Definition: light.h:38
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
Indicates a coordinate-system transform on vertices.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
Stores auxiliary data that may be piggybacked on the BamReader during each object's read pass.
Definition: bamReader.h:61
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
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.
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:47
This is the base class for PointerTo and ConstPointerTo.
Definition: pointerToBase.h:29
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight reentrant mutex.
Definition: lightReMutex.h:30
This collects together the pieces of data that are accumulated for each node while walking the scene ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
This is the base class for a number of special render effects that may be set on scene graph nodes to...
Definition: renderEffect.h:48
This is our own Panda specialization on the default STL list.
Definition: plist.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a class designed to support low-overhead traversals of the complete scene graph,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A specialization of ordered_vector that emulates a standard STL set: one copy of each element is allo...
This just stores the pointers to implement a doubly-linked list of some kind of object.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void output(std::ostream &out) const
Outputs the Namable.
Definition: namable.I:61
A lightweight class that represents a single element that may be timed and/or counted via stats.
A base class for all things which can have a name.
Definition: namable.h:26
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A specialization of ordered_vector that emulates a standard STL set: many copies of each element are ...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
The default class template does not define any methods.
Definition: extension.h:34
This class is similar to CycleDataLockedReader, except it allows reading from a particular stage of t...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
This class is similar to CycleDataReader, except it allows reading from a particular stage of the pip...
A base class for all things that want to be reference-counted.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A thread; that is, a lightweight process.
Definition: thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Encapsulates the data from a PandaNode, pre-fetched for one stage of the pipeline.
Definition: pandaNode.h:842
A class to retrieve the individual data elements previously stored in a Datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This is a sequence number that increments monotonically.
Definition: updateSeq.h:37
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a unique collection of RenderEffect objects that correspond to a particular renderabl...
Definition: renderEffects.h:41
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class maintains a linked list of PandaNodes.
Converts an egg data structure, possibly read from an egg file but not necessarily,...
Definition: eggLoader.h:67
This is one component of a NodePath.
An object specifically designed to transform the vertices of a Geom without disturbing indexing or af...