Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pgraph/pandaNode.h

Go to the documentation of this file.
00001 // Filename: pandaNode.h
00002 // Created by:  drose (20Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef PANDANODE_H
00020 #define PANDANODE_H
00021 
00022 #include "pandabase.h"
00023 
00024 #include "cycleData.h"
00025 #include "cycleDataReader.h"
00026 #include "cycleDataWriter.h"
00027 #include "pipelineCycler.h"
00028 #include "renderState.h"
00029 #include "renderEffects.h"
00030 #include "transformState.h"
00031 #include "drawMask.h"
00032 #include "typedWritable.h"
00033 #include "boundedObject.h"
00034 #include "collideMask.h"
00035 #include "namable.h"
00036 #include "referenceCount.h"
00037 #include "luse.h"
00038 #include "ordered_vector.h"
00039 #include "pointerTo.h"
00040 #include "pointerToArray.h"
00041 #include "notify.h"
00042 
00043 class NodePathComponent;
00044 class CullTraverser;
00045 class CullTraverserData;
00046 class Light;
00047 class FactoryParams;
00048 class AccumulatedAttribs;
00049 class GeomTransformer;
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //       Class : PandaNode
00053 // Description : A basic node of the scene graph or data graph.  This
00054 //               is the base class of all specialized nodes, and also
00055 //               serves as a generic node with no special properties.
00056 ////////////////////////////////////////////////////////////////////
00057 class EXPCL_PANDA PandaNode : public TypedWritable, public Namable,
00058                               public BoundedObject,
00059                               virtual public ReferenceCount {
00060 PUBLISHED:
00061   PandaNode(const string &name);
00062   virtual ~PandaNode();
00063 
00064 protected:
00065   PandaNode(const PandaNode &copy);
00066 private:
00067   void operator = (const PandaNode &copy);
00068 
00069 public:
00070   virtual PandaNode *make_copy() const;
00071 
00072   virtual bool safe_to_flatten() const;
00073   virtual bool safe_to_transform() const;
00074   virtual bool safe_to_modify_transform() const;
00075   virtual bool safe_to_combine() const;
00076   virtual bool safe_to_flatten_below() const;
00077   virtual bool preserve_name() const;
00078   virtual int get_unsafe_to_apply_attribs() const;
00079   virtual void apply_attribs_to_vertices(const AccumulatedAttribs &attribs,
00080                                          int attrib_types,
00081                                          GeomTransformer &transformer);
00082   virtual void xform(const LMatrix4f &mat);
00083   virtual PandaNode *combine_with(PandaNode *other); 
00084   virtual CPT(TransformState)
00085     calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
00086                       bool &found_any,
00087                       const TransformState *transform) const;
00088   
00089   virtual bool has_cull_callback() const;
00090   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
00091   virtual bool has_selective_visibility() const;
00092   virtual int get_first_visible_child() const;
00093   virtual int get_next_visible_child(int n) const;
00094   virtual bool has_single_child_visibility() const;
00095   virtual int get_visible_child() const;
00096 
00097 PUBLISHED:
00098   PT(PandaNode) copy_subgraph() const;
00099 
00100   INLINE int get_num_parents() const;
00101   INLINE PandaNode *get_parent(int n) const;
00102   INLINE int find_parent(PandaNode *node) const;
00103 
00104   INLINE int get_num_children() const;
00105   INLINE PandaNode *get_child(int n) const;
00106   INLINE int get_child_sort(int n) const;
00107   int find_child(PandaNode *node) const;
00108 
00109   void add_child(PandaNode *child_node, int sort = 0);
00110   void remove_child(int n);
00111   bool remove_child(PandaNode *child_node);
00112   bool replace_child(PandaNode *orig_child, PandaNode *new_child);
00113 
00114   INLINE bool stash_child(PandaNode *child_node);
00115   void stash_child(int child_index);
00116   INLINE bool unstash_child(PandaNode *child_node);
00117   void unstash_child(int stashed_index);
00118 
00119   INLINE int get_num_stashed() const;
00120   INLINE PandaNode *get_stashed(int n) const;
00121   INLINE int get_stashed_sort(int n) const;
00122   int find_stashed(PandaNode *node) const;
00123 
00124   void add_stashed(PandaNode *child_node, int sort = 0);
00125   void remove_stashed(int n);
00126 
00127   void remove_all_children();
00128   void steal_children(PandaNode *other);
00129   void copy_children(PandaNode *other);
00130 
00131   INLINE void set_attrib(const RenderAttrib *attrib, int override = 0);
00132   INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
00133   INLINE bool has_attrib(TypeHandle type) const;
00134   INLINE void clear_attrib(TypeHandle type);
00135 
00136   INLINE void set_effect(const RenderEffect *effect);
00137   INLINE const RenderEffect *get_effect(TypeHandle type) const;
00138   INLINE bool has_effect(TypeHandle type) const;
00139   INLINE void clear_effect(TypeHandle type);
00140 
00141   INLINE void set_state(const RenderState *state);
00142   INLINE const RenderState *get_state() const;
00143   INLINE void clear_state();
00144 
00145   INLINE void set_effects(const RenderEffects *effects);
00146   INLINE const RenderEffects *get_effects() const;
00147   INLINE void clear_effects();
00148 
00149   INLINE void set_transform(const TransformState *transform);
00150   INLINE const TransformState *get_transform() const;
00151   INLINE void clear_transform();
00152 
00153   INLINE void set_draw_mask(DrawMask mask);
00154   INLINE DrawMask get_draw_mask() const;
00155 
00156   INLINE CollideMask get_net_collide_mask() const;
00157 
00158   virtual void output(ostream &out) const;
00159   virtual void write(ostream &out, int indent_level) const;
00160 
00161   INLINE void ls(ostream &out, int indent_level) const;
00162 
00163   // A node has two bounding volumes: the BoundedObject it inherits
00164   // from is the "external" bound and represents the node and all of
00165   // its children, while the _internal_bound object is the "internal"
00166   // bounds and represents only the node itself.
00167 
00168   // We remap the inherited set_bound() and get_bound() functions so
00169   // that set_bound() to a type sets the type of the external bound,
00170   // while set_bound() to a specific bounding volume sets the volume
00171   // of the *internal* bound.  At the same time, get_bound() returns
00172   // the external bound.  Although it might seem strange and confusing
00173   // to do this, this is actually the natural way the user thinks
00174   // about nodes and bounding volumes.
00175   INLINE void set_bound(BoundingVolumeType type);
00176   INLINE void set_bound(const BoundingVolume &volume);
00177   INLINE const BoundingVolume &get_bound() const;
00178   INLINE const BoundingVolume &get_internal_bound() const;
00179 
00180 public:
00181   virtual bool is_geom_node() const;
00182   virtual Light *as_light();
00183   virtual void set_velocity(const LVector3f &vel);
00184 
00185 protected:
00186   // Inherited from BoundedObject
00187   virtual void propagate_stale_bound();
00188   virtual BoundingVolume *recompute_bound();
00189 
00190   // Local to PandaNode
00191   virtual BoundingVolume *recompute_internal_bound();
00192   INLINE void changed_internal_bound();
00193   virtual void parents_changed();
00194   virtual void children_changed();
00195   virtual void transform_changed();
00196   INLINE void add_net_collide_mask(CollideMask mask);
00197 
00198   typedef pmap<PandaNode *, PandaNode *> InstanceMap;
00199   virtual PT(PandaNode) r_copy_subgraph(InstanceMap &inst_map) const;
00200   virtual void r_copy_children(const PandaNode *from, InstanceMap &inst_map);
00201 
00202   // This is the bounding volume around the contents of the node
00203   // itself (without including all of the node's children).
00204   // BoundedObject is itself cycled, so we don't need to protect it.
00205   BoundedObject _internal_bound;
00206 
00207 private:
00208   class CData;
00209 
00210   // parent-child manipulation for NodePath support.  Don't try to
00211   // call these directly.
00212   static PT(NodePathComponent) attach(NodePathComponent *parent, 
00213                                        PandaNode *child, int sort);
00214   static void detach(NodePathComponent *child);
00215   static void reparent(NodePathComponent *new_parent,
00216                        NodePathComponent *child, int sort);
00217   static PT(NodePathComponent) get_component(NodePathComponent *parent,
00218                                               PandaNode *child);
00219   static PT(NodePathComponent) get_top_component(PandaNode *child,
00220                                                    bool force);
00221   PT(NodePathComponent) get_generic_component(bool accept_ambiguity);
00222   PT(NodePathComponent) r_get_generic_component(bool accept_ambiguity, bool &ambiguity_detected);
00223   void delete_component(NodePathComponent *component);
00224   static void sever_connection(PandaNode *parent_node, PandaNode *child_node);
00225   static void new_connection(PandaNode *parent_node, PandaNode *child_node);
00226   void fix_path_lengths(const CData *cdata);
00227   void r_list_descendants(ostream &out, int indent_level) const;
00228 
00229 private:
00230   class EXPCL_PANDA DownConnection {
00231   public:
00232     INLINE DownConnection(PandaNode *child, int sort);
00233     INLINE bool operator < (const DownConnection &other) const;
00234     INLINE PandaNode *get_child() const;
00235     INLINE void set_child(PandaNode *child);
00236     INLINE int get_sort() const;
00237 
00238   private:
00239     // Child pointers are reference counted.  That way, holding a
00240     // pointer to the root of a subgraph keeps the entire subgraph
00241     // around.
00242     PT(PandaNode) _child;
00243     int _sort;
00244   };
00245   typedef ov_multiset<DownConnection> Down;
00246 
00247   class EXPCL_PANDA UpConnection {
00248   public:
00249     INLINE UpConnection(PandaNode *child);
00250     INLINE bool operator < (const UpConnection &other) const;
00251     INLINE PandaNode *get_parent() const;
00252 
00253   private:
00254     // Parent pointers are not reference counted.  That way, parents and
00255     // children do not circularly reference each other.
00256     PandaNode *_parent;
00257   };
00258   typedef ov_set<UpConnection> Up;
00259 
00260   // We also maintain a set of NodePathComponents in the node.  This
00261   // represents the set of instances of this node that we have
00262   // requested a NodePath for.  We don't keep reference counts; when
00263   // each NodePathComponent destructs, it removes itself from this
00264   // set.
00265   typedef pset<NodePathComponent *> Paths;
00266   
00267   // This is the data that must be cycled between pipeline stages.
00268   class EXPCL_PANDA CData : public CycleData {
00269   public:
00270     INLINE CData();
00271     INLINE CData(const CData &copy);
00272     virtual CycleData *make_copy() const;
00273     virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
00274     virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
00275     virtual void fillin(DatagramIterator &scan, BamReader *manager);
00276 
00277     void write_up_list(const Up &up_list,
00278                        BamWriter *manager, Datagram &dg) const;
00279     void write_down_list(const Down &down_list,
00280                          BamWriter *manager, Datagram &dg) const;
00281     int complete_up_list(Up &up_list,
00282                          TypedWritable **p_list, BamReader *manager);
00283     int complete_down_list(Down &down_list,
00284                            TypedWritable **p_list, BamReader *manager);
00285     void fillin_up_list(Up &up_list,
00286                         DatagramIterator &scan, BamReader *manager);
00287     void fillin_down_list(Down &down_list,
00288                           DatagramIterator &scan, BamReader *manager);
00289 
00290     Down _down;
00291     Down _stashed;
00292     Up _up;
00293     Paths _paths;
00294 
00295     CPT(RenderState) _state;
00296     CPT(RenderEffects) _effects;
00297     CPT(TransformState) _transform;
00298 
00299     // This is the draw_mask of this particular node.
00300     DrawMask _draw_mask;
00301 
00302     // This is the union of all into_collide_mask bits for any
00303     // CollisionNodes at and below this level.  It's conceptually
00304     // similar to a bounding volume--it represents the bounding volume
00305     // of this node in the space of collision bits--and it needs to be
00306     // updated for the same reasons the bounding volume needs to be
00307     // updated.  So we update them together.
00308     CollideMask _net_collide_mask;
00309 
00310     bool _fixed_internal_bound;
00311   };
00312 
00313   PipelineCycler<CData> _cycler;
00314   typedef CycleDataReader<CData> CDReader;
00315   typedef CycleDataWriter<CData> CDWriter;
00316 
00317 public:
00318   // Use this interface when you want to walk through the list of
00319   // children.  This saves a tiny bit of overhead between each step,
00320   // by keeping the PipelineCycler open for reading the whole time.
00321   // However, it does not protect you from self-modifying loops.
00322   class EXPCL_PANDA Children {
00323   public:
00324     INLINE Children(const CDReader &cdata);
00325     INLINE Children(const Children &copy);
00326     INLINE void operator = (const Children &copy);
00327 
00328     INLINE int get_num_children() const;
00329     INLINE PandaNode *get_child(int n) const;
00330 
00331   private:
00332     CDReader _cdata;
00333   };
00334 
00335   INLINE Children get_children() const;
00336 
00337   // This interface *does* protect you from self-modifying loops, by
00338   // copying the list of children.
00339   class EXPCL_PANDA ChildrenCopy {
00340   public:
00341     ChildrenCopy(const CDReader &cdata);
00342     INLINE ChildrenCopy(const ChildrenCopy &copy);
00343     INLINE void operator = (const ChildrenCopy &copy);
00344 
00345     INLINE int get_num_children() const;
00346     INLINE PandaNode *get_child(int n) const;
00347 
00348   private:
00349     typedef PTA(PT(PandaNode)) List;
00350     List _list;
00351   };
00352 
00353   INLINE ChildrenCopy get_children_copy() const;
00354 
00355 public:
00356   static void register_with_read_factory();
00357   virtual void write_datagram(BamWriter *manager, Datagram &dg);
00358 
00359 protected:
00360   static TypedWritable *make_from_bam(const FactoryParams &params);
00361   void fillin(DatagramIterator &scan, BamReader *manager);
00362   
00363 public:
00364   static TypeHandle get_class_type() {
00365     return _type_handle;
00366   }
00367   static void init_type() {
00368     TypedWritable::init_type();
00369     BoundedObject::init_type();
00370     ReferenceCount::init_type();
00371     register_type(_type_handle, "PandaNode",
00372                   TypedWritable::get_class_type(),
00373                   BoundedObject::get_class_type(),
00374                   ReferenceCount::get_class_type());
00375   }
00376   virtual TypeHandle get_type() const {
00377     return get_class_type();
00378   }
00379   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00380 
00381 private:
00382   static TypeHandle _type_handle;
00383 
00384   friend class PandaNode::Children;
00385   friend class NodePath;
00386   friend class NodePathComponent;
00387   friend class WorkingNodePath;
00388 };
00389 
00390 INLINE ostream &operator << (ostream &out, const PandaNode &node) {
00391   node.output(out);
00392   return out;
00393 }
00394 
00395 #include "pandaNode.I"
00396 
00397 #endif
00398 

Generated on Fri May 2 00:42:09 2003 for Panda by doxygen1.3