Panda3D

lodNode.h

00001 // Filename: lodNode.h
00002 // Created by:  drose (06Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef LODNODE_H
00016 #define LODNODE_H
00017 
00018 #include "pandabase.h"
00019 
00020 #include "pandaNode.h"
00021 #include "luse.h"
00022 #include "pvector.h"
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //       Class : LODNode
00026 // Description : A Level-of-Detail node.  This selects only one of its
00027 //               children for rendering, according to the distance
00028 //               from the camera and the table indicated in the
00029 //               associated LOD object.
00030 ////////////////////////////////////////////////////////////////////
00031 class EXPCL_PANDA_PGRAPHNODES LODNode : public PandaNode {
00032 PUBLISHED:
00033   INLINE LODNode(const string &name);
00034 
00035   static PT(LODNode) make_default_lod(const string &name);
00036 
00037 protected:
00038   INLINE LODNode(const LODNode &copy);
00039 public:
00040   virtual PandaNode *make_copy() const;
00041   virtual bool safe_to_combine() const;
00042   virtual bool safe_to_combine_children() const;
00043   virtual void xform(const LMatrix4 &mat);
00044   virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
00045 
00046   virtual void output(ostream &out) const;
00047 
00048   virtual bool is_lod_node() const;
00049 
00050 PUBLISHED:
00051   // The sense of in vs. out distances is as if the object were coming
00052   // towards you from far away: it switches "in" at the far distance,
00053   // and switches "out" at the close distance.  Thus, "in" should be
00054   // larger than "out".
00055 
00056   INLINE void add_switch(PN_stdfloat in, PN_stdfloat out);
00057   INLINE bool set_switch(int index, PN_stdfloat in, PN_stdfloat out);
00058   INLINE void clear_switches();
00059 
00060   INLINE int get_num_switches() const;
00061   INLINE PN_stdfloat get_in(int index) const;
00062   MAKE_SEQ(get_ins, get_num_switches, get_in);
00063   INLINE PN_stdfloat get_out(int index) const;
00064   MAKE_SEQ(get_outs, get_num_switches, get_out);
00065 
00066   INLINE int get_lowest_switch() const;
00067   INLINE int get_highest_switch() const;
00068 
00069   INLINE void force_switch(int index);
00070   INLINE void clear_force_switch();
00071 
00072   //for performance tuning, increasing this value should improve performance
00073   //at the cost of model quality
00074   INLINE void set_lod_scale(PN_stdfloat value);
00075   INLINE PN_stdfloat get_lod_scale() const;
00076 
00077 
00078   INLINE void set_center(const LPoint3 &center);
00079   INLINE const LPoint3 &get_center() const;
00080 
00081   void show_switch(int index);
00082   void show_switch(int index, const LColor &color);
00083   void hide_switch(int index);
00084   void show_all_switches();
00085   void hide_all_switches();
00086   INLINE bool is_any_shown() const;
00087 
00088   bool verify_child_bounds() const;
00089 
00090 protected:
00091   int compute_child(CullTraverser *trav, CullTraverserData &data);
00092 
00093   bool show_switches_cull_callback(CullTraverser *trav, CullTraverserData &data);
00094   virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
00095                                        int &internal_vertices,
00096                                        int pipeline_stage,
00097                                        Thread *current_thread) const;
00098 
00099   INLINE void consider_verify_lods(CullTraverser *trav, CullTraverserData &data);
00100 
00101   CPT(TransformState) get_rel_transform(CullTraverser *trav, CullTraverserData &data);
00102 
00103 private:
00104   class CData;
00105   void do_show_switch(CData *cdata, int index, const LColor &color);
00106   void do_hide_switch(CData *cdata, int index);
00107   bool do_verify_child_bounds(const CData *cdata, int index,
00108                               PN_stdfloat &suggested_radius) const;
00109   void do_auto_verify_lods(CullTraverser *trav, CullTraverserData &data);
00110 
00111   static const LColor &get_default_show_color(int index);
00112 
00113 protected:
00114   class Switch {
00115   public:
00116     INLINE Switch(PN_stdfloat in, PN_stdfloat out);
00117     INLINE PN_stdfloat get_in() const;
00118     INLINE PN_stdfloat get_out() const;
00119 
00120     INLINE void set_range(PN_stdfloat in, PN_stdfloat out);
00121     INLINE bool in_range(PN_stdfloat dist) const;
00122     INLINE bool in_range_2(PN_stdfloat dist2) const;
00123 
00124     INLINE void rescale(PN_stdfloat factor);
00125 
00126     INLINE bool is_shown() const;
00127     INLINE void show(const LColor &color);
00128     INLINE void hide();
00129 
00130     INLINE PandaNode *get_ring_viz() const;
00131     INLINE PandaNode *get_spindle_viz() const;
00132     INLINE const RenderState *get_viz_model_state() const;
00133 
00134     INLINE void write_datagram(Datagram &destination) const;
00135     INLINE void read_datagram(DatagramIterator &source);
00136 
00137   private:
00138     INLINE void clear_ring_viz();
00139 
00140     void compute_ring_viz();
00141     void compute_spindle_viz();
00142     void compute_viz_model_state();
00143 
00144   private:
00145     PN_stdfloat _in;
00146     PN_stdfloat _out;
00147     bool _shown;
00148     UnalignedLVecBase4 _show_color;
00149     PT(PandaNode) _ring_viz;
00150     PT(PandaNode) _spindle_viz;
00151     CPT(RenderState) _viz_model_state;
00152 
00153   public:
00154     UpdateSeq _bounds_seq;
00155     bool _verify_ok;
00156   };
00157   typedef pvector<Switch> SwitchVector;
00158 
00159 private:
00160   class EXPCL_PANDA_PGRAPH CData : public CycleData {
00161   public:
00162     INLINE CData();
00163     INLINE CData(const CData &copy);
00164     virtual CycleData *make_copy() const;
00165 
00166     void check_limits();
00167 
00168     virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
00169     virtual void fillin(DatagramIterator &scan, BamReader *manager);
00170     virtual TypeHandle get_parent_type() const {
00171       return LODNode::get_class_type();
00172     }
00173 
00174     LPoint3 _center;
00175     SwitchVector _switch_vector;
00176     size_t _lowest, _highest;
00177     UpdateSeq _bounds_seq;
00178 
00179     bool _got_force_switch;
00180     int _force_switch;
00181     int _num_shown;
00182     PN_stdfloat _lod_scale;
00183   };
00184 
00185   PipelineCycler<CData> _cycler;
00186   typedef CycleDataReader<CData> CDReader;
00187   typedef CycleDataWriter<CData> CDWriter;
00188   typedef CycleDataLockedReader<CData> CDLockedReader;
00189   typedef CycleDataStageReader<CData> CDStageReader;
00190   typedef CycleDataStageWriter<CData> CDStageWriter;
00191 
00192 public:
00193   static void register_with_read_factory();
00194   virtual void write_datagram(BamWriter *manager, Datagram &dg);
00195 
00196 protected:
00197   static TypedWritable *make_from_bam(const FactoryParams &params);
00198   void fillin(DatagramIterator &scan, BamReader *manager);
00199 
00200 public:
00201   static TypeHandle get_class_type() {
00202     return _type_handle;
00203   }
00204   static void init_type() {
00205     PandaNode::init_type();
00206     register_type(_type_handle, "LODNode",
00207                   PandaNode::get_class_type());
00208   }
00209   virtual TypeHandle get_type() const {
00210     return get_class_type();
00211   }
00212   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00213 
00214 private:
00215   static TypeHandle _type_handle;
00216 };
00217 
00218 #include "lodNode.I"
00219 
00220 #endif
 All Classes Functions Variables Enumerations