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

panda/src/pgraph/transformState.h

Go to the documentation of this file.
00001 // Filename: transformState.h
00002 // Created by:  drose (25Feb02)
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 TRANSFORMSTATE_H
00020 #define TRANSFORMSTATE_H
00021 
00022 #include "pandabase.h"
00023 
00024 #include "typedWritableReferenceCount.h"
00025 #include "pointerTo.h"
00026 #include "indirectLess.h"
00027 #include "luse.h"
00028 #include "pset.h"
00029 #include "event.h"
00030 
00031 class GraphicsStateGuardianBase;
00032 class FactoryParams;
00033 
00034 ////////////////////////////////////////////////////////////////////
00035 //       Class : TransformState
00036 // Description : Indicates a coordinate-system transform on vertices.
00037 //               TransformStates are the primary means for storing
00038 //               transformations on the scene graph.
00039 //
00040 //               Transforms may be specified in one of two ways:
00041 //               componentwise, with a pos-hpr-scale, or with an
00042 //               arbitrary transform matrix.  If you specify a
00043 //               transform componentwise, it will remember its
00044 //               original components.
00045 //
00046 //               TransformState objects are managed very much like
00047 //               RenderState objects.  They are immutable and
00048 //               reference-counted automatically.
00049 //
00050 //               You should not attempt to create or modify a
00051 //               TransformState object directly.  Instead, call one of
00052 //               the make() functions to create one for you.  And
00053 //               instead of modifying a TransformState object, create a
00054 //               new one.
00055 ////////////////////////////////////////////////////////////////////
00056 class EXPCL_PANDA TransformState : public TypedWritableReferenceCount {
00057 protected:
00058   TransformState();
00059 
00060 private:
00061   TransformState(const TransformState &copy);
00062   void operator = (const TransformState &copy);
00063 
00064 public:
00065   virtual ~TransformState();
00066 
00067   bool operator < (const TransformState &other) const;
00068 
00069 PUBLISHED:
00070   static CPT(TransformState) make_identity();
00071   static CPT(TransformState) make_invalid();
00072   INLINE static CPT(TransformState) make_pos(const LVecBase3f &pos);
00073   INLINE static CPT(TransformState) make_hpr(const LVecBase3f &hpr);
00074   INLINE static CPT(TransformState) make_quat(const LQuaternionf &quat);
00075   INLINE static CPT(TransformState) make_pos_hpr(const LVecBase3f &pos,
00076                                                  const LVecBase3f &hpr);
00077   INLINE static CPT(TransformState) make_scale(float scale);
00078   INLINE static CPT(TransformState) make_scale(const LVecBase3f &scale);
00079   static CPT(TransformState) make_pos_hpr_scale(const LVecBase3f &pos,
00080                                                 const LVecBase3f &hpr, 
00081                                                 const LVecBase3f &scale);
00082   static CPT(TransformState) make_pos_quat_scale(const LVecBase3f &pos,
00083                                                  const LQuaternionf &quat, 
00084                                                  const LVecBase3f &scale);
00085   static CPT(TransformState) make_mat(const LMatrix4f &mat);
00086 
00087   INLINE bool is_identity() const;
00088   INLINE bool is_invalid() const;
00089   INLINE bool is_singular() const;
00090   INLINE bool has_components() const;
00091   INLINE bool components_given() const;
00092   INLINE bool hpr_given() const;
00093   INLINE bool quat_given() const;
00094   INLINE bool has_pos() const;
00095   INLINE bool has_hpr() const;
00096   INLINE bool has_quat() const;
00097   INLINE bool has_scale() const;
00098   INLINE bool has_uniform_scale() const;
00099   INLINE bool has_mat() const;
00100   INLINE const LVecBase3f &get_pos() const;
00101   INLINE const LVecBase3f &get_hpr() const;
00102   INLINE const LQuaternionf &get_quat() const;
00103   INLINE const LVecBase3f &get_scale() const;
00104   INLINE float get_uniform_scale() const;
00105   INLINE const LMatrix4f &get_mat() const;
00106 
00107   CPT(TransformState) set_pos(const LVecBase3f &pos) const;
00108   CPT(TransformState) set_hpr(const LVecBase3f &hpr) const;
00109   CPT(TransformState) set_quat(const LQuaternionf &quat) const;
00110   CPT(TransformState) set_scale(const LVecBase3f &scale) const;
00111 
00112   CPT(TransformState) compose(const TransformState *other) const;
00113   CPT(TransformState) invert_compose(const TransformState *other) const;
00114 
00115   void output(ostream &out) const;
00116   void write(ostream &out, int indent_level) const;
00117 
00118   static int get_num_states();
00119   static int get_num_unused_states();
00120   static int clear_cache();
00121 
00122 private:
00123   static CPT(TransformState) return_new(TransformState *state);
00124   CPT(TransformState) do_compose(const TransformState *other) const;
00125   CPT(TransformState) do_invert_compose(const TransformState *other) const;
00126 
00127 private:
00128   typedef pset<const TransformState *, IndirectLess<TransformState> > States;
00129   static States *_states;
00130   static CPT(TransformState) _identity_state;
00131 
00132   // This iterator records the entry corresponding to this TransformState
00133   // object in the above global set.  We keep the iterator around so
00134   // we can remove it when the TransformState destructs.
00135   States::iterator _saved_entry;
00136 
00137   // This data structure manages the job of caching the composition of
00138   // two TransformStates.  It's complicated because we have to be sure to
00139   // remove the entry if *either* of the input TransformStates destructs.
00140   // To implement this, we always record Composition entries in pairs,
00141   // one in each of the two involved TransformState objects.
00142   class Composition {
00143   public:
00144     INLINE Composition();
00145     INLINE Composition(const Composition &copy);
00146 
00147     CPT(TransformState) _result;
00148   };
00149     
00150   typedef pmap<const TransformState *, Composition> CompositionCache;
00151   CompositionCache _composition_cache;
00152   CompositionCache _invert_composition_cache;
00153 
00154   // Thise pointer is used to cache the result of compose(this).  This
00155   // has to be a special case, because we have to handle the reference
00156   // counts carefully so that we don't leak.
00157   const TransformState *_self_compose;
00158 
00159 private:
00160   // This is the actual data within the TransformState.
00161   INLINE void check_singular() const;
00162   INLINE void check_components() const;
00163   INLINE void check_hpr() const;
00164   INLINE void check_quat() const;
00165   INLINE void check_mat() const;
00166   void calc_singular();
00167   void calc_components();
00168   void calc_hpr();
00169   void calc_quat();
00170   void calc_mat();
00171 
00172   INLINE void check_uniform_scale();
00173 
00174   INLINE void set_destructing();
00175   INLINE bool is_destructing() const;
00176 
00177   enum Flags {
00178     F_is_identity      = 0x0001,
00179     F_is_singular      = 0x0002,
00180     F_singular_known   = 0x0004,  // set if we know F_is_singular
00181     F_components_given = 0x0008,
00182     F_components_known = 0x0010,  // set if we know F_has_components
00183     F_has_components   = 0x0020,
00184     F_mat_known        = 0x0040,  // set if _mat is defined
00185     F_is_invalid       = 0x0080,
00186     F_quat_given       = 0x0100,
00187     F_quat_known       = 0x0200,  // set if _quat is defined
00188     F_hpr_given        = 0x0400,
00189     F_hpr_known        = 0x0800,  // set if _hpr is defined
00190     F_uniform_scale    = 0x1000,
00191     F_is_destructing   = 0x8000,
00192   };
00193   LVecBase3f _pos, _hpr, _scale;
00194   LQuaternionf _quat;
00195   LMatrix4f _mat;
00196   LMatrix4f *_inv_mat;
00197   
00198   unsigned short _flags;
00199 
00200 public:
00201   static void register_with_read_factory();
00202   virtual void write_datagram(BamWriter *manager, Datagram &dg);
00203   static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
00204   virtual void finalize();
00205 
00206 protected:
00207   static TypedWritable *make_from_bam(const FactoryParams &params);
00208   void fillin(DatagramIterator &scan, BamReader *manager);
00209   
00210 public:
00211   static TypeHandle get_class_type() {
00212     return _type_handle;
00213   }
00214   static void init_type() {
00215     TypedWritableReferenceCount::init_type();
00216     register_type(_type_handle, "TransformState",
00217                   TypedWritableReferenceCount::get_class_type());
00218   }
00219   virtual TypeHandle get_type() const {
00220     return get_class_type();
00221   }
00222   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00223 
00224 private:
00225   static TypeHandle _type_handle;
00226 };
00227 
00228 INLINE ostream &operator << (ostream &out, const TransformState &state) {
00229   state.output(out);
00230   return out;
00231 }
00232 
00233 
00234 ////////////////////////////////////////////////////////////////////
00235 //       Class : EventStoreTransform
00236 // Description : This class is used to pass TransformState pointers as
00237 //               parameters to events, or as elements on a data graph.
00238 ////////////////////////////////////////////////////////////////////
00239 class EXPCL_PANDA EventStoreTransform : public EventStoreValueBase {
00240 public:
00241   INLINE EventStoreTransform(const TransformState *value);
00242   INLINE void set_value(const TransformState *value);
00243   INLINE const TransformState *get_value() const;
00244 
00245   virtual void output(ostream &out) const;
00246 
00247   CPT(TransformState) _value;
00248 
00249 public:
00250   virtual TypeHandle get_type() const {
00251     return get_class_type();
00252   }
00253   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00254   static TypeHandle get_class_type() {
00255     return _type_handle;
00256   }
00257   static void init_type() {
00258     EventStoreValueBase::init_type();
00259     register_type(_type_handle, "EventStoreTransform",
00260                   EventStoreValueBase::get_class_type());
00261   }
00262 
00263 private:
00264   static TypeHandle _type_handle;
00265 };
00266 
00267 #include "transformState.I"
00268 
00269 #endif
00270 

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