00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef PANDANODE_H
00016 #define PANDANODE_H
00017
00018 #include "pandabase.h"
00019
00020 #include "cycleData.h"
00021 #include "cycleDataReader.h"
00022 #include "cycleDataWriter.h"
00023 #include "cycleDataLockedStageReader.h"
00024 #include "cycleDataStageReader.h"
00025 #include "cycleDataStageWriter.h"
00026 #include "pipelineCycler.h"
00027 #include "renderState.h"
00028 #include "renderEffects.h"
00029 #include "transformState.h"
00030 #include "drawMask.h"
00031 #include "typedWritable.h"
00032 #include "collideMask.h"
00033 #include "namable.h"
00034 #include "referenceCount.h"
00035 #include "luse.h"
00036 #include "ordered_vector.h"
00037 #include "pointerTo.h"
00038 #include "nodePointerTo.h"
00039 #include "pointerToArray.h"
00040 #include "pnotify.h"
00041 #include "updateSeq.h"
00042 #include "deletedChain.h"
00043 #include "pandaNodeChain.h"
00044 #include "pStatCollector.h"
00045 #include "copyOnWriteObject.h"
00046 #include "copyOnWritePointer.h"
00047 #include "lightReMutex.h"
00048
00049 #ifdef HAVE_PYTHON
00050
00051 #undef _POSIX_C_SOURCE
00052 #include <Python.h>
00053
00054 #endif // HAVE_PYTHON
00055
00056 class NodePathComponent;
00057 class CullTraverser;
00058 class CullTraverserData;
00059 class Light;
00060 class FactoryParams;
00061 class AccumulatedAttribs;
00062 class GeomTransformer;
00063 class GraphicsStateGuardianBase;
00064
00065
00066
00067
00068
00069
00070
00071 class EXPCL_PANDA_PGRAPH PandaNode : public TypedWritable, public Namable,
00072 public LinkedListNode,
00073 virtual public ReferenceCount {
00074 PUBLISHED:
00075 PandaNode(const string &name);
00076 virtual ~PandaNode();
00077
00078 virtual PandaNode *combine_with(PandaNode *other);
00079
00080 protected:
00081 PandaNode(const PandaNode ©);
00082 private:
00083 void operator = (const PandaNode ©);
00084
00085 public:
00086 virtual ReferenceCount *as_reference_count();
00087 virtual PandaNode *dupe_for_flatten() const;
00088
00089 virtual bool safe_to_flatten() const;
00090 virtual bool safe_to_transform() const;
00091 virtual bool safe_to_modify_transform() const;
00092 virtual bool safe_to_combine() const;
00093 virtual bool safe_to_combine_children() const;
00094 virtual bool safe_to_flatten_below() const;
00095 virtual bool preserve_name() const;
00096 virtual int get_unsafe_to_apply_attribs() const;
00097 virtual void apply_attribs_to_vertices(const AccumulatedAttribs &attribs,
00098 int attrib_types,
00099 GeomTransformer &transformer);
00100 virtual void xform(const LMatrix4 &mat);
00101
00102 virtual CPT(TransformState)
00103 calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
00104 bool &found_any,
00105 const TransformState *transform,
00106 Thread *current_thread = Thread::get_current_thread()) const;
00107
00108 virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
00109 virtual bool has_selective_visibility() const;
00110 virtual int get_first_visible_child() const;
00111 virtual int get_next_visible_child(int n) const;
00112 virtual bool has_single_child_visibility() const;
00113 virtual int get_visible_child() const;
00114 virtual bool is_renderable() const;
00115 virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data);
00116
00117 PUBLISHED:
00118 virtual PandaNode *make_copy() const;
00119 PT(PandaNode) copy_subgraph(Thread *current_thread = Thread::get_current_thread()) const;
00120
00121 #ifdef HAVE_PYTHON
00122 PT(PandaNode) __copy__() const;
00123 PyObject *__deepcopy__(PyObject *self, PyObject *memo) const;
00124 #endif
00125
00126 INLINE int get_num_parents(Thread *current_thread = Thread::get_current_thread()) const;
00127 INLINE PandaNode *get_parent(int n, Thread *current_thread = Thread::get_current_thread()) const;
00128 INLINE int find_parent(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
00129
00130 INLINE int get_num_children(Thread *current_thread = Thread::get_current_thread()) const;
00131 INLINE PandaNode *get_child(int n, Thread *current_thread = Thread::get_current_thread()) const;
00132 INLINE int get_child_sort(int n, Thread *current_thread = Thread::get_current_thread()) const;
00133 INLINE int find_child(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
00134
00135 int count_num_descendants() const;
00136
00137 void add_child(PandaNode *child_node, int sort = 0,
00138 Thread *current_thread = Thread::get_current_thread());
00139 void remove_child(int child_index, Thread *current_thread = Thread::get_current_thread());
00140 bool remove_child(PandaNode *child_node, Thread *current_thread = Thread::get_current_thread());
00141 bool replace_child(PandaNode *orig_child, PandaNode *new_child,
00142 Thread *current_thread = Thread::get_current_thread());
00143
00144 INLINE bool stash_child(PandaNode *child_node,
00145 Thread *current_thread = Thread::get_current_thread());
00146 void stash_child(int child_index,
00147 Thread *current_thread = Thread::get_current_thread());
00148 INLINE bool unstash_child(PandaNode *child_node,
00149 Thread *current_thread = Thread::get_current_thread());
00150 void unstash_child(int stashed_index,
00151 Thread *current_thread = Thread::get_current_thread());
00152
00153 INLINE int get_num_stashed(Thread *current_thread = Thread::get_current_thread()) const;
00154 INLINE PandaNode *get_stashed(int n, Thread *current_thread = Thread::get_current_thread()) const;
00155 INLINE int get_stashed_sort(int n, Thread *current_thread = Thread::get_current_thread()) const;
00156 INLINE int find_stashed(PandaNode *node, Thread *current_thread = Thread::get_current_thread()) const;
00157
00158 void add_stashed(PandaNode *child_node, int sort = 0, Thread *current_thread = Thread::get_current_thread());
00159 void remove_stashed(int child_index, Thread *current_thread = Thread::get_current_thread());
00160
00161 void remove_all_children(Thread *current_thread = Thread::get_current_thread());
00162 void steal_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread());
00163 void copy_children(PandaNode *other, Thread *current_thread = Thread::get_current_thread());
00164
00165 void set_attrib(const RenderAttrib *attrib, int override = 0);
00166 INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
00167 INLINE const RenderAttrib *get_attrib(int slot) const;
00168 INLINE bool has_attrib(TypeHandle type) const;
00169 INLINE bool has_attrib(int slot) const;
00170 INLINE void clear_attrib(TypeHandle type);
00171 void clear_attrib(int slot);
00172
00173 void set_effect(const RenderEffect *effect);
00174 INLINE const RenderEffect *get_effect(TypeHandle type) const;
00175 INLINE bool has_effect(TypeHandle type) const;
00176 void clear_effect(TypeHandle type);
00177
00178 void set_state(const RenderState *state, Thread *current_thread = Thread::get_current_thread());
00179 INLINE const RenderState *get_state(Thread *current_thread = Thread::get_current_thread()) const;
00180 INLINE void clear_state(Thread *current_thread = Thread::get_current_thread());
00181
00182 void set_effects(const RenderEffects *effects, Thread *current_thread = Thread::get_current_thread());
00183 INLINE const RenderEffects *get_effects(Thread *current_thread = Thread::get_current_thread()) const;
00184 INLINE void clear_effects(Thread *current_thread = Thread::get_current_thread());
00185
00186 void set_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
00187 INLINE const TransformState *get_transform(Thread *current_thread = Thread::get_current_thread()) const;
00188 INLINE void clear_transform(Thread *current_thread = Thread::get_current_thread());
00189
00190 void set_prev_transform(const TransformState *transform, Thread *current_thread = Thread::get_current_thread());
00191 INLINE const TransformState *get_prev_transform(Thread *current_thread = Thread::get_current_thread()) const;
00192 void reset_prev_transform(Thread *current_thread = Thread::get_current_thread());
00193 INLINE bool has_dirty_prev_transform() const;
00194 static void reset_all_prev_transform(Thread *current_thread = Thread::get_current_thread());
00195
00196 void set_tag(const string &key, const string &value,
00197 Thread *current_thread = Thread::get_current_thread());
00198 INLINE string get_tag(const string &key,
00199 Thread *current_thread = Thread::get_current_thread()) const;
00200 INLINE bool has_tag(const string &key,
00201 Thread *current_thread = Thread::get_current_thread()) const;
00202 void clear_tag(const string &key,
00203 Thread *current_thread = Thread::get_current_thread());
00204
00205 #ifdef HAVE_PYTHON
00206 void set_python_tag(const string &key, PyObject *value);
00207 PyObject *get_python_tag(const string &key) const;
00208 bool has_python_tag(const string &key) const;
00209 void clear_python_tag(const string &key);
00210 #endif // HAVE_PYTHON
00211
00212 INLINE bool has_tags() const;
00213 void copy_tags(PandaNode *other);
00214 void list_tags(ostream &out, const string &separator = "\n") const;
00215
00216 int compare_tags(const PandaNode *other) const;
00217
00218 void copy_all_properties(PandaNode *other);
00219 void replace_node(PandaNode *other);
00220
00221 enum UnexpectedChange {
00222 UC_parents = 0x001,
00223 UC_children = 0x002,
00224 UC_transform = 0x004,
00225 UC_state = 0x008,
00226 UC_draw_mask = 0x010,
00227 };
00228 void set_unexpected_change(unsigned int flags);
00229 unsigned int get_unexpected_change(unsigned int flags) const;
00230 void clear_unexpected_change(unsigned int flags);
00231
00232 INLINE static DrawMask get_overall_bit();
00233 INLINE static DrawMask get_all_camera_mask();
00234 INLINE bool is_overall_hidden() const;
00235 INLINE void set_overall_hidden(bool overall_hidden);
00236
00237 void adjust_draw_mask(DrawMask show_mask,
00238 DrawMask hide_mask,
00239 DrawMask clear_mask);
00240 INLINE DrawMask get_draw_control_mask() const;
00241 INLINE DrawMask get_draw_show_mask() const;
00242
00243 DrawMask get_net_draw_control_mask() const;
00244 DrawMask get_net_draw_show_mask() const;
00245
00246 void set_into_collide_mask(CollideMask mask);
00247 INLINE CollideMask get_into_collide_mask() const;
00248 virtual CollideMask get_legal_collide_mask() const;
00249
00250 CollideMask get_net_collide_mask(Thread *current_thread = Thread::get_current_thread()) const;
00251 CPT(RenderAttrib) get_off_clip_planes(Thread *current_thread = Thread::get_current_thread()) const;
00252
00253 void prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state);
00254
00255 bool is_scene_root() const;
00256 bool is_under_scene_root() const;
00257
00258 virtual void output(ostream &out) const;
00259 virtual void write(ostream &out, int indent_level) const;
00260
00261 INLINE void ls(ostream &out, int indent_level) const;
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 void set_bounds_type(BoundingVolume::BoundsType bounds_type);
00275 BoundingVolume::BoundsType get_bounds_type() const;
00276
00277 void set_bounds(const BoundingVolume *volume);
00278 void set_bound(const BoundingVolume *volume);
00279 INLINE void clear_bounds();
00280 CPT(BoundingVolume) get_bounds(Thread *current_thread = Thread::get_current_thread()) const;
00281 CPT(BoundingVolume) get_bounds(UpdateSeq &seq, Thread *current_thread = Thread::get_current_thread()) const;
00282 int get_nested_vertices(Thread *current_thread = Thread::get_current_thread()) const;
00283 INLINE CPT(BoundingVolume) get_internal_bounds(Thread *current_thread = Thread::get_current_thread()) const;
00284 INLINE int get_internal_vertices(Thread *current_thread = Thread::get_current_thread()) const;
00285
00286 void mark_bounds_stale(Thread *current_thread = Thread::get_current_thread()) const;
00287 void mark_internal_bounds_stale(Thread *current_thread = Thread::get_current_thread());
00288 INLINE bool is_bounds_stale() const;
00289
00290 INLINE void set_final(bool flag);
00291 INLINE bool is_final(Thread *current_thread = Thread::get_current_thread()) const;
00292
00293 virtual bool is_geom_node() const;
00294 virtual bool is_lod_node() const;
00295 virtual bool is_collision_node() const;
00296 virtual Light *as_light();
00297 virtual bool is_ambient_light() const;
00298
00299 enum FancyBits {
00300 FB_transform = 0x0001,
00301 FB_state = 0x0002,
00302 FB_effects = 0x0004,
00303 FB_tag = 0x0010,
00304 FB_draw_mask = 0x0020,
00305 FB_cull_callback = 0x0040,
00306 };
00307 INLINE int get_fancy_bits(Thread *current_thread = Thread::get_current_thread()) const;
00308
00309
00310 PUBLISHED:
00311 static PT(PandaNode) decode_from_bam_stream(const string &data, BamReader *reader = NULL);
00312
00313 protected:
00314 class BoundsData;
00315
00316 INLINE CPT(BoundingVolume) get_user_bounds(int pipeline_stage, Thread *current_thread) const;
00317 CPT(BoundingVolume) get_internal_bounds(int pipeline_stage, Thread *current_thread) const;
00318 int get_internal_vertices(int pipeline_stage, Thread *current_thread) const;
00319 void set_internal_bounds(const BoundingVolume *volume);
00320
00321 INLINE void mark_bounds_stale(int pipeline_stage, Thread *current_thread) const;
00322 void force_bounds_stale(Thread *current_thread = Thread::get_current_thread());
00323 void force_bounds_stale(int pipeline_stage, Thread *current_thread);
00324 INLINE void mark_internal_bounds_stale(int pipeline_stage, Thread *current_thread);
00325
00326 virtual void r_mark_geom_bounds_stale(Thread *current_thread);
00327
00328 virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
00329 int &internal_vertices,
00330 int pipeline_stage,
00331 Thread *current_thread) const;
00332 virtual void parents_changed();
00333 virtual void children_changed();
00334 virtual void transform_changed();
00335 virtual void state_changed();
00336 virtual void draw_mask_changed();
00337
00338 typedef pmap<PandaNode *, PandaNode *> InstanceMap;
00339 virtual PT(PandaNode) r_copy_subgraph(InstanceMap &inst_map,
00340 Thread *current_thread) const;
00341 virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map,
00342 Thread *current_thread);
00343
00344 void set_cull_callback();
00345 void disable_cull_callback();
00346 public:
00347 virtual void r_prepare_scene(GraphicsStateGuardianBase *gsg,
00348 const RenderState *node_state,
00349 GeomTransformer &transformer,
00350 Thread *current_thread);
00351
00352 protected:
00353
00354
00355
00356 class EXPCL_PANDA_PGRAPH BoundsData : public CycleData {
00357 protected:
00358 INLINE BoundsData();
00359 INLINE BoundsData(const BoundsData ©);
00360 INLINE void copy_bounds(const BoundsData ©);
00361
00362 public:
00363
00364
00365
00366
00367 CPT(BoundingVolume) _internal_bounds;
00368 int _internal_vertices;
00369 UpdateSeq _internal_bounds_mark;
00370 UpdateSeq _internal_bounds_computed;
00371 };
00372
00373 private:
00374 class CData;
00375
00376 INLINE int do_find_parent(PandaNode *node, const CData *cdata) const;
00377 bool stage_remove_child(PandaNode *child_node, int pipeline_stage,
00378 Thread *current_thread);
00379 bool stage_replace_child(PandaNode *orig_child, PandaNode *new_child,
00380 int pipeline_stage, Thread *current_thread);
00381
00382 void quick_add_new_child(PandaNode *child_node, int sort,
00383 Thread *current_thread);
00384
00385 INLINE bool verify_child_no_cycles(PandaNode *child_node);
00386 void report_cycle(PandaNode *node);
00387 bool find_node_above(PandaNode *node);
00388
00389
00390
00391 static PT(NodePathComponent) attach(NodePathComponent *parent,
00392 PandaNode *child, int sort,
00393 int pipeline_stage, Thread *current_thread);
00394 static void detach(NodePathComponent *child, int pipeline_stage, Thread *current_thread);
00395 static void detach_one_stage(NodePathComponent *child, int pipeline_stage, Thread *current_thread);
00396 static bool reparent(NodePathComponent *new_parent,
00397 NodePathComponent *child, int sort, bool as_stashed,
00398 int pipeline_stage, Thread *current_thread);
00399 static bool reparent_one_stage(NodePathComponent *new_parent,
00400 NodePathComponent *child, int sort,
00401 bool as_stashed, int pipeline_stage, Thread *current_thread);
00402 static PT(NodePathComponent) get_component(NodePathComponent *parent,
00403 PandaNode *child,
00404 int pipeline_stage, Thread *current_thread);
00405 static PT(NodePathComponent) get_top_component(PandaNode *child, bool force,
00406 int pipeline_stage, Thread *current_thread);
00407 PT(NodePathComponent) get_generic_component(bool accept_ambiguity,
00408 int pipeline_stage, Thread *current_thread);
00409 PT(NodePathComponent) r_get_generic_component(bool accept_ambiguity,
00410 bool &ambiguity_detected,
00411 int pipeline_stage, Thread *current_thread);
00412 void delete_component(NodePathComponent *component);
00413 static void sever_connection(PandaNode *parent_node, PandaNode *child_node,
00414 int pipeline_stage, Thread *current_thread);
00415 static void new_connection(PandaNode *parent_node, PandaNode *child_node,
00416 int pipeline_stage, Thread *current_thread);
00417 void fix_path_lengths(int pipeline_stage, Thread *current_thread);
00418 void r_list_descendants(ostream &out, int indent_level) const;
00419
00420 INLINE void do_set_dirty_prev_transform();
00421 INLINE void do_clear_dirty_prev_transform();
00422
00423 public:
00424
00425
00426 class EXPCL_PANDA_PGRAPH DownConnection {
00427 public:
00428 INLINE DownConnection(PandaNode *child, int sort);
00429 INLINE bool operator < (const DownConnection &other) const;
00430 INLINE PandaNode *get_child() const;
00431 INLINE void set_child(PandaNode *child);
00432 INLINE int get_sort() const;
00433
00434 private:
00435
00436
00437
00438 PT(PandaNode) _child;
00439 int _sort;
00440 };
00441
00442 private:
00443 typedef ov_multiset<DownConnection> DownList;
00444 typedef CopyOnWriteObj1< DownList, TypeHandle > Down;
00445
00446
00447 class EXPCL_PANDA_PGRAPH BamReaderAuxDataDown : public BamReaderAuxData {
00448 public:
00449 INLINE BamReaderAuxDataDown();
00450 Down _down_list;
00451 public:
00452 virtual TypeHandle get_type() const {
00453 return get_class_type();
00454 }
00455 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00456 static TypeHandle get_class_type() {
00457 return _type_handle;
00458 }
00459
00460 public:
00461 static void init_type() {
00462 BamReaderAuxData::init_type();
00463 register_type(_type_handle, "BamReaderAuxDataDown",
00464 BamReaderAuxData::get_class_type());
00465 }
00466
00467 private:
00468 static TypeHandle _type_handle;
00469 };
00470
00471 class EXPCL_PANDA_PGRAPH UpConnection {
00472 public:
00473 INLINE UpConnection(PandaNode *child);
00474 INLINE bool operator < (const UpConnection &other) const;
00475 INLINE PandaNode *get_parent() const;
00476
00477 private:
00478
00479
00480 PandaNode *_parent;
00481 };
00482 typedef ov_set<UpConnection> UpList;
00483 typedef CopyOnWriteObj1< UpList, TypeHandle > Up;
00484
00485
00486
00487
00488
00489
00490 typedef phash_set<NodePathComponent *, pointer_hash> Paths;
00491
00492
00493
00494
00495 Paths _paths;
00496 LightReMutex _paths_lock;
00497
00498 bool _dirty_prev_transform;
00499 static PandaNodeChain _dirty_prev_transforms;
00500
00501
00502
00503 typedef phash_map<string, string, string_hash> TagData;
00504 #ifdef HAVE_PYTHON
00505 typedef phash_map<string, PyObject *, string_hash> PythonTagData;
00506 #endif // HAVE_PYTHON
00507
00508 #ifndef NDEBUG
00509 unsigned int _unexpected_change_flags;
00510 #endif // !NDEBUG
00511
00512
00513
00514 class EXPCL_PANDA_PGRAPH CData : public BoundsData {
00515 public:
00516 CData();
00517 CData(const CData ©);
00518 virtual ~CData();
00519 ALLOC_DELETED_CHAIN(CData);
00520
00521 virtual CycleData *make_copy() const;
00522 virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
00523 void update_bam_nested(BamWriter *manager) const;
00524 virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
00525 virtual void fillin(DatagramIterator &scan, BamReader *manager);
00526 virtual TypeHandle get_parent_type() const {
00527 return PandaNode::get_class_type();
00528 }
00529
00530 public:
00531
00532
00533
00534 NCPT(RenderState) _state;
00535 NCPT(TransformState) _transform;
00536 NCPT(TransformState) _prev_transform;
00537
00538 public:
00539
00540
00541
00542 INLINE void set_fancy_bit(int bits, bool value);
00543
00544 #ifdef HAVE_PYTHON
00545 void inc_py_refs();
00546 void dec_py_refs();
00547 #endif
00548
00549 CPT(RenderEffects) _effects;
00550
00551 TagData _tag_data;
00552 #ifdef HAVE_PYTHON
00553 PythonTagData _python_tag_data;
00554 #endif // HAVE_PYTHON
00555
00556
00557
00558 DrawMask _draw_control_mask, _draw_show_mask;
00559
00560
00561
00562
00563
00564 CollideMask _into_collide_mask;
00565
00566
00567 BoundingVolume::BoundsType _bounds_type;
00568
00569
00570
00571 CPT(BoundingVolume) _user_bounds;
00572
00573
00574
00575
00576
00577 bool _final_bounds;
00578
00579
00580
00581
00582 int _fancy_bits;
00583
00584 public:
00585
00586
00587
00588
00589
00590
00591
00592 CollideMask _net_collide_mask;
00593
00594
00595 DrawMask _net_draw_control_mask, _net_draw_show_mask;
00596
00597
00598
00599
00600 CPT(RenderAttrib) _off_clip_planes;
00601
00602
00603
00604 int _nested_vertices;
00605
00606
00607
00608
00609 CPT(BoundingVolume) _external_bounds;
00610
00611
00612 UpdateSeq _last_update, _next_update;
00613
00614 public:
00615
00616
00617
00618 void write_up_list(const Up &up_list,
00619 BamWriter *manager, Datagram &dg) const;
00620 void write_down_list(const Down &down_list,
00621 BamWriter *manager, Datagram &dg) const;
00622 void update_up_list(const Up &up_list, BamWriter *manager) const;
00623 void update_down_list(const Down &down_list, BamWriter *manager) const;
00624 int complete_up_list(Up &up_list, const string &tag,
00625 TypedWritable **p_list, BamReader *manager);
00626 int complete_down_list(Down &down_list, const string &tag,
00627 TypedWritable **p_list, BamReader *manager);
00628 void fillin_up_list(Up &up_list, const string &tag,
00629 DatagramIterator &scan, BamReader *manager);
00630 void fillin_down_list(Down &down_list, const string &tag,
00631 DatagramIterator &scan, BamReader *manager);
00632
00633 INLINE CPT(Down) get_down() const;
00634 INLINE PT(Down) modify_down();
00635 INLINE CPT(Down) get_stashed() const;
00636 INLINE PT(Down) modify_stashed();
00637 INLINE CPT(Up) get_up() const;
00638 INLINE PT(Up) modify_up();
00639
00640 private:
00641
00642
00643 COWPT(Down) _down;
00644 COWPT(Down) _stashed;
00645 COWPT(Up) _up;
00646
00647 public:
00648 static TypeHandle get_class_type() {
00649 return _type_handle;
00650 }
00651 static void init_type() {
00652 register_type(_type_handle, "PandaNode::CData");
00653 }
00654
00655 private:
00656 static TypeHandle _type_handle;
00657 };
00658
00659 PipelineCycler<CData> _cycler;
00660 typedef CycleDataReader<CData> CDReader;
00661 typedef CycleDataWriter<CData> CDWriter;
00662 typedef CycleDataLockedStageReader<CData> CDLockedStageReader;
00663 typedef CycleDataStageReader<CData> CDStageReader;
00664 typedef CycleDataStageWriter<CData> CDStageWriter;
00665
00666 int do_find_child(PandaNode *node, const Down *down) const;
00667 CDStageWriter update_bounds(int pipeline_stage, CDLockedStageReader &cdata);
00668
00669 static DrawMask _overall_bit;
00670
00671 static PStatCollector _reset_prev_pcollector;
00672 static PStatCollector _update_bounds_pcollector;
00673
00674 public:
00675
00676
00677
00678
00679
00680
00681
00682 class EXPCL_PANDA_PGRAPH Children {
00683 public:
00684 INLINE Children();
00685 INLINE Children(const CData *cdata);
00686 INLINE Children(const Children ©);
00687 INLINE void operator = (const Children ©);
00688
00689 INLINE int get_num_children() const;
00690 INLINE PandaNode *get_child(int n) const;
00691 INLINE int get_child_sort(int n) const;
00692
00693 private:
00694 CPT(Down) _down;
00695 };
00696
00697
00698 class EXPCL_PANDA_PGRAPH Stashed {
00699 public:
00700 INLINE Stashed();
00701 INLINE Stashed(const CData *cdata);
00702 INLINE Stashed(const Stashed ©);
00703 INLINE void operator = (const Stashed ©);
00704
00705 INLINE int get_num_stashed() const;
00706 INLINE PandaNode *get_stashed(int n) const;
00707 INLINE int get_stashed_sort(int n) const;
00708
00709 private:
00710 CPT(Down) _stashed;
00711 };
00712
00713
00714 class EXPCL_PANDA_PGRAPH Parents {
00715 public:
00716 INLINE Parents();
00717 INLINE Parents(const CData *cdata);
00718 INLINE Parents(const Parents ©);
00719 INLINE void operator = (const Parents ©);
00720
00721 INLINE int get_num_parents() const;
00722 INLINE PandaNode *get_parent(int n) const;
00723
00724 private:
00725 CPT(Up) _up;
00726 };
00727
00728 INLINE Children get_children(Thread *current_thread = Thread::get_current_thread()) const;
00729 INLINE Stashed get_stashed(Thread *current_thread = Thread::get_current_thread()) const;
00730 INLINE Parents get_parents(Thread *current_thread = Thread::get_current_thread()) const;
00731
00732 typedef bool SceneRootFunc(const PandaNode *);
00733 static void set_scene_root_func(SceneRootFunc *func);
00734
00735 private:
00736 static SceneRootFunc *_scene_root_func;
00737
00738 public:
00739 static void register_with_read_factory();
00740 virtual void write_datagram(BamWriter *manager, Datagram &dg);
00741 virtual void update_bam_nested(BamWriter *manager);
00742 void write_recorder(BamWriter *manager, Datagram &dg);
00743
00744 protected:
00745 static TypedWritable *make_from_bam(const FactoryParams ¶ms);
00746 void fillin(DatagramIterator &scan, BamReader *manager);
00747 void fillin_recorder(DatagramIterator &scan, BamReader *manager);
00748
00749 public:
00750 static TypeHandle get_class_type() {
00751 return _type_handle;
00752 }
00753 static void init_type() {
00754 TypedWritable::init_type();
00755 ReferenceCount::init_type();
00756 Namable::init_type();
00757 register_type(_type_handle, "PandaNode",
00758 TypedWritable::get_class_type(),
00759 ReferenceCount::get_class_type(),
00760 Namable::get_class_type());
00761 CData::init_type();
00762 Down::init_type();
00763 Up::init_type();
00764 BamReaderAuxDataDown::init_type();
00765 }
00766 virtual TypeHandle get_type() const {
00767 return get_class_type();
00768 }
00769 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00770
00771 private:
00772 static TypeHandle _type_handle;
00773
00774 #ifndef DO_PIPELINING
00775 friend class PandaNode::Children;
00776 friend class PandaNode::Stashed;
00777 #endif
00778 friend class NodePath;
00779 friend class NodePathComponent;
00780 friend class WorkingNodePath;
00781 friend class PandaNodePipelineReader;
00782 friend class EggLoader;
00783 };
00784
00785
00786
00787
00788
00789
00790 class EXPCL_PANDA_PGRAPH PandaNodePipelineReader {
00791 public:
00792 INLINE PandaNodePipelineReader(const PandaNode *object, Thread *current_thread);
00793 INLINE PandaNodePipelineReader(const PandaNodePipelineReader ©);
00794 INLINE void operator = (const PandaNodePipelineReader ©);
00795
00796 public:
00797 INLINE ~PandaNodePipelineReader();
00798 ALLOC_DELETED_CHAIN(PandaNodePipelineReader);
00799
00800 INLINE const PandaNode *get_object() const;
00801 INLINE Thread *get_current_thread() const;
00802
00803 INLINE void release();
00804
00805 void check_bounds() const;
00806
00807 INLINE void compose_draw_mask(DrawMask &running_draw_mask) const;
00808 INLINE bool compare_draw_mask(DrawMask running_draw_mask,
00809 DrawMask camera_mask) const;
00810
00811 INLINE int get_num_parents() const;
00812 INLINE PandaNode *get_parent(int n) const;
00813 INLINE int find_parent(PandaNode *node) const;
00814
00815 INLINE int get_num_children() const;
00816 INLINE PandaNode *get_child(int n) const;
00817 INLINE int get_child_sort(int n) const;
00818 INLINE int find_child(PandaNode *node) const;
00819
00820 INLINE int get_num_stashed() const;
00821 INLINE PandaNode *get_stashed(int n) const;
00822 INLINE int get_stashed_sort(int n) const;
00823 INLINE int find_stashed(PandaNode *node) const;
00824
00825 INLINE const RenderState *get_state() const;
00826 INLINE const RenderEffects *get_effects() const;
00827 INLINE const TransformState *get_transform() const;
00828 INLINE const TransformState *get_prev_transform() const;
00829
00830 INLINE string get_tag(const string &key) const;
00831 INLINE bool has_tag(const string &key) const;
00832
00833 INLINE CollideMask get_net_collide_mask() const;
00834 INLINE CPT(RenderAttrib) get_off_clip_planes() const;
00835 INLINE CPT(BoundingVolume) get_bounds() const;
00836 INLINE int get_nested_vertices() const;
00837 INLINE bool is_final() const;
00838 INLINE int get_fancy_bits() const;
00839
00840 INLINE PandaNode::Children get_children() const;
00841 INLINE PandaNode::Stashed get_stashed() const;
00842 INLINE PandaNode::Parents get_parents() const;
00843
00844 private:
00845 const PandaNode *_object;
00846 Thread *_current_thread;
00847
00848 const PandaNode::CData *_cdata;
00849
00850 public:
00851 static TypeHandle get_class_type() {
00852 return _type_handle;
00853 }
00854 static void init_type() {
00855 register_type(_type_handle, "PandaNodePipelineReader");
00856 }
00857
00858 private:
00859 static TypeHandle _type_handle;
00860
00861 };
00862
00863 INLINE ostream &operator << (ostream &out, const PandaNode &node) {
00864 node.output(out);
00865 return out;
00866 }
00867
00868 #include "pandaNode.I"
00869
00870 #endif
00871