00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef TRANSFORMSTATE_H
00016 #define TRANSFORMSTATE_H
00017
00018 #include "pandabase.h"
00019
00020 #include "nodeCachedReferenceCount.h"
00021 #include "pointerTo.h"
00022 #include "luse.h"
00023 #include "event.h"
00024 #include "updateSeq.h"
00025 #include "pStatCollector.h"
00026 #include "geomEnums.h"
00027 #include "lightReMutex.h"
00028 #include "lightReMutexHolder.h"
00029 #include "lightMutex.h"
00030 #include "lightMutexHolder.h"
00031 #include "config_pgraph.h"
00032 #include "deletedChain.h"
00033 #include "simpleHashMap.h"
00034 #include "cacheStats.h"
00035
00036 class GraphicsStateGuardianBase;
00037 class FactoryParams;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 class EXPCL_PANDA_PGRAPH TransformState : public NodeCachedReferenceCount {
00062 protected:
00063 TransformState();
00064
00065 private:
00066 TransformState(const TransformState ©);
00067 void operator = (const TransformState ©);
00068
00069 public:
00070 virtual ~TransformState();
00071 ALLOC_DELETED_CHAIN(TransformState);
00072
00073 PUBLISHED:
00074 INLINE bool operator < (const TransformState &other) const;
00075 INLINE int compare_to(const TransformState &other) const;
00076 int compare_to(const TransformState &other, bool uniquify_matrix) const;
00077 INLINE size_t get_hash() const;
00078
00079 static CPT(TransformState) make_identity();
00080 static CPT(TransformState) make_invalid();
00081 INLINE static CPT(TransformState) make_pos(const LVecBase3 &pos);
00082 INLINE static CPT(TransformState) make_hpr(const LVecBase3 &hpr);
00083 INLINE static CPT(TransformState) make_quat(const LQuaternion &quat);
00084 INLINE static CPT(TransformState) make_pos_hpr(const LVecBase3 &pos,
00085 const LVecBase3 &hpr);
00086 INLINE static CPT(TransformState) make_scale(PN_stdfloat scale);
00087 INLINE static CPT(TransformState) make_scale(const LVecBase3 &scale);
00088 INLINE static CPT(TransformState) make_shear(const LVecBase3 &shear);
00089 INLINE static CPT(TransformState) make_pos_hpr_scale(const LVecBase3 &pos,
00090 const LVecBase3 &hpr,
00091 const LVecBase3 &scale);
00092 INLINE static CPT(TransformState) make_pos_quat_scale(const LVecBase3 &pos,
00093 const LQuaternion &quat,
00094 const LVecBase3 &scale);
00095 static CPT(TransformState) make_pos_hpr_scale_shear(const LVecBase3 &pos,
00096 const LVecBase3 &hpr,
00097 const LVecBase3 &scale,
00098 const LVecBase3 &shear);
00099 static CPT(TransformState) make_pos_quat_scale_shear(const LVecBase3 &pos,
00100 const LQuaternion &quat,
00101 const LVecBase3 &scale,
00102 const LVecBase3 &shear);
00103 static CPT(TransformState) make_mat(const LMatrix4 &mat);
00104
00105
00106 INLINE static CPT(TransformState) make_pos2d(const LVecBase2 &pos);
00107 INLINE static CPT(TransformState) make_rotate2d(PN_stdfloat rotate);
00108 INLINE static CPT(TransformState) make_pos_rotate2d(const LVecBase2 &pos,
00109 PN_stdfloat rotate);
00110 INLINE static CPT(TransformState) make_scale2d(PN_stdfloat scale);
00111 INLINE static CPT(TransformState) make_scale2d(const LVecBase2 &scale);
00112 INLINE static CPT(TransformState) make_shear2d(PN_stdfloat shear);
00113 INLINE static CPT(TransformState) make_pos_rotate_scale2d(const LVecBase2 &pos,
00114 PN_stdfloat rotate,
00115 const LVecBase2 &scale);
00116 static CPT(TransformState) make_pos_rotate_scale_shear2d(const LVecBase2 &pos,
00117 PN_stdfloat rotate,
00118 const LVecBase2 &scale,
00119 PN_stdfloat shear);
00120 static CPT(TransformState) make_mat3(const LMatrix3 &mat);
00121
00122
00123 INLINE bool is_identity() const;
00124 INLINE bool is_invalid() const;
00125 INLINE bool is_singular() const;
00126 INLINE bool is_2d() const;
00127
00128 INLINE bool has_components() const;
00129 INLINE bool components_given() const;
00130 INLINE bool hpr_given() const;
00131 INLINE bool quat_given() const;
00132 INLINE bool has_pos() const;
00133 INLINE bool has_hpr() const;
00134 INLINE bool has_quat() const;
00135 INLINE bool has_scale() const;
00136 INLINE bool has_identity_scale() const;
00137 INLINE bool has_uniform_scale() const;
00138 INLINE bool has_shear() const;
00139 INLINE bool has_nonzero_shear() const;
00140 INLINE bool has_mat() const;
00141
00142 INLINE const LPoint3 &get_pos() const;
00143 INLINE const LVecBase3 &get_hpr() const;
00144 INLINE const LQuaternion &get_quat() const;
00145 INLINE const LQuaternion &get_norm_quat() const;
00146 INLINE const LVecBase3 &get_scale() const;
00147 INLINE PN_stdfloat get_uniform_scale() const;
00148 INLINE const LVecBase3 &get_shear() const;
00149 INLINE const LMatrix4 &get_mat() const;
00150
00151 INLINE LVecBase2 get_pos2d() const;
00152 INLINE PN_stdfloat get_rotate2d() const;
00153 INLINE LVecBase2 get_scale2d() const;
00154 INLINE PN_stdfloat get_shear2d() const;
00155 INLINE LMatrix3 get_mat3() const;
00156
00157 CPT(TransformState) set_pos(const LVecBase3 &pos) const;
00158 CPT(TransformState) set_hpr(const LVecBase3 &hpr) const;
00159 CPT(TransformState) set_quat(const LQuaternion &quat) const;
00160 CPT(TransformState) set_scale(const LVecBase3 &scale) const;
00161 CPT(TransformState) set_shear(const LVecBase3 &shear) const;
00162
00163 CPT(TransformState) set_pos2d(const LVecBase2 &pos) const;
00164 CPT(TransformState) set_rotate2d(PN_stdfloat rotate) const;
00165 CPT(TransformState) set_scale2d(const LVecBase2 &scale) const;
00166 CPT(TransformState) set_shear2d(PN_stdfloat shear) const;
00167
00168 CPT(TransformState) compose(const TransformState *other) const;
00169 CPT(TransformState) invert_compose(const TransformState *other) const;
00170
00171 INLINE CPT(TransformState) get_inverse() const;
00172 INLINE CPT(TransformState) get_unique() const;
00173
00174 INLINE int get_geom_rendering(int geom_rendering) const;
00175
00176 virtual bool unref() const;
00177
00178 INLINE void cache_ref() const;
00179 INLINE bool cache_unref() const;
00180 INLINE void node_ref() const;
00181 INLINE bool node_unref() const;
00182
00183 INLINE int get_composition_cache_num_entries() const;
00184 INLINE int get_invert_composition_cache_num_entries() const;
00185
00186 INLINE int get_composition_cache_size() const;
00187 INLINE const TransformState *get_composition_cache_source(int n) const;
00188 INLINE const TransformState *get_composition_cache_result(int n) const;
00189 INLINE int get_invert_composition_cache_size() const;
00190 INLINE const TransformState *get_invert_composition_cache_source(int n) const;
00191 INLINE const TransformState *get_invert_composition_cache_result(int n) const;
00192 bool validate_composition_cache() const;
00193 #ifdef HAVE_PYTHON
00194 PyObject *get_composition_cache() const;
00195 PyObject *get_invert_composition_cache() const;
00196 #endif // HAVE_PYTHON
00197
00198 void output(ostream &out) const;
00199 void write(ostream &out, int indent_level) const;
00200 void write_composition_cache(ostream &out, int indent_level) const;
00201
00202 static int get_num_states();
00203 static int get_num_unused_states();
00204 static int clear_cache();
00205 static int garbage_collect();
00206 static void list_cycles(ostream &out);
00207 static void list_states(ostream &out);
00208 static bool validate_states();
00209 #ifdef HAVE_PYTHON
00210 static PyObject *get_states();
00211 static PyObject *get_unused_states();
00212 #endif // HAVE_PYTHON
00213
00214
00215 public:
00216 static void init_states();
00217
00218 INLINE static void flush_level();
00219
00220 private:
00221 INLINE bool do_cache_unref() const;
00222 INLINE bool do_node_unref() const;
00223
00224 class CompositionCycleDescEntry {
00225 public:
00226 INLINE CompositionCycleDescEntry(const TransformState *obj,
00227 const TransformState *result,
00228 bool inverted);
00229
00230 const TransformState *_obj;
00231 const TransformState *_result;
00232 bool _inverted;
00233 };
00234 typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
00235
00236 static CPT(TransformState) return_new(TransformState *state);
00237 static CPT(TransformState) return_unique(TransformState *state);
00238
00239 CPT(TransformState) do_compose(const TransformState *other) const;
00240 CPT(TransformState) store_compose(const TransformState *other, const TransformState *result);
00241 CPT(TransformState) do_invert_compose(const TransformState *other) const;
00242 CPT(TransformState) store_invert_compose(const TransformState *other, const TransformState *result);
00243 void detect_and_break_cycles();
00244 static bool r_detect_cycles(const TransformState *start_state,
00245 const TransformState *current_state,
00246 int length, UpdateSeq this_seq,
00247 CompositionCycleDesc *cycle_desc);
00248 static bool r_detect_reverse_cycles(const TransformState *start_state,
00249 const TransformState *current_state,
00250 int length, UpdateSeq this_seq,
00251 CompositionCycleDesc *cycle_desc);
00252
00253 void release_new();
00254 void remove_cache_pointers();
00255
00256 private:
00257
00258
00259
00260 static LightReMutex *_states_lock;
00261 class Empty {
00262 };
00263 typedef SimpleHashMap<const TransformState *, Empty, indirect_compare_to_hash<const TransformState *> > States;
00264 static States *_states;
00265 static CPT(TransformState) _identity_state;
00266 static CPT(TransformState) _invalid_state;
00267
00268
00269
00270
00271 int _saved_entry;
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 class Composition {
00284 public:
00285 INLINE Composition();
00286 INLINE Composition(const Composition ©);
00287
00288
00289
00290 const TransformState *_result;
00291 };
00292
00293 typedef SimpleHashMap<const TransformState *, Composition, pointer_hash> CompositionCache;
00294 CompositionCache _composition_cache;
00295 CompositionCache _invert_composition_cache;
00296
00297
00298 UpdateSeq _cycle_detect;
00299 static UpdateSeq _last_cycle_detect;
00300
00301
00302
00303 static int _garbage_index;
00304
00305 static PStatCollector _cache_update_pcollector;
00306 static PStatCollector _garbage_collect_pcollector;
00307 static PStatCollector _transform_compose_pcollector;
00308 static PStatCollector _transform_invert_pcollector;
00309 static PStatCollector _transform_calc_pcollector;
00310 static PStatCollector _transform_break_cycles_pcollector;
00311 static PStatCollector _transform_new_pcollector;
00312 static PStatCollector _transform_validate_pcollector;
00313 static PStatCollector _transform_hash_pcollector;
00314
00315 static PStatCollector _node_counter;
00316 static PStatCollector _cache_counter;
00317
00318 private:
00319
00320 INLINE void check_hash() const;
00321 INLINE void check_singular() const;
00322 INLINE void check_components() const;
00323 INLINE void check_hpr() const;
00324 INLINE void check_quat() const;
00325 INLINE void check_norm_quat() const;
00326 INLINE void check_mat() const;
00327 INLINE void calc_hash();
00328 void do_calc_hash();
00329 void calc_singular();
00330 INLINE void calc_components();
00331 void do_calc_components();
00332 INLINE void calc_hpr();
00333 void do_calc_hpr();
00334 void calc_quat();
00335 void calc_norm_quat();
00336 INLINE void calc_mat();
00337 void do_calc_mat();
00338
00339 INLINE void check_uniform_scale();
00340 INLINE void check_uniform_scale2d();
00341
00342 INLINE void set_destructing();
00343 INLINE bool is_destructing() const;
00344
00345 INLINE void consider_update_pstats(int old_referenced_bits) const;
00346 static void update_pstats(int old_referenced_bits, int new_referenced_bits);
00347
00348 enum Flags {
00349 F_is_identity = 0x00000001,
00350 F_is_singular = 0x00000002,
00351 F_singular_known = 0x00000004,
00352 F_components_given = 0x00000008,
00353 F_components_known = 0x00000010,
00354 F_has_components = 0x00000020,
00355 F_mat_known = 0x00000040,
00356 F_is_invalid = 0x00000080,
00357 F_quat_given = 0x00000100,
00358 F_quat_known = 0x00000200,
00359 F_hpr_given = 0x00000400,
00360 F_hpr_known = 0x00000800,
00361 F_uniform_scale = 0x00001000,
00362 F_identity_scale = 0x00002000,
00363 F_has_nonzero_shear = 0x00004000,
00364 F_is_destructing = 0x00008000,
00365 F_is_2d = 0x00010000,
00366 F_hash_known = 0x00020000,
00367 F_norm_quat_known = 0x00040000,
00368 };
00369 LPoint3 _pos;
00370 LVecBase3 _hpr, _scale, _shear;
00371 LQuaternion _quat, _norm_quat;
00372 LMatrix4 _mat;
00373 LMatrix4 *_inv_mat;
00374 size_t _hash;
00375
00376 unsigned int _flags;
00377
00378
00379 LightMutex _lock;
00380
00381 static CacheStats _cache_stats;
00382
00383 public:
00384 static void register_with_read_factory();
00385 virtual void write_datagram(BamWriter *manager, Datagram &dg);
00386 static PT(TypedWritableReferenceCount) change_this(TypedWritableReferenceCount *old_ptr, BamReader *manager);
00387
00388 protected:
00389 static TypedWritable *make_from_bam(const FactoryParams ¶ms);
00390 void fillin(DatagramIterator &scan, BamReader *manager);
00391
00392 public:
00393 static TypeHandle get_class_type() {
00394 return _type_handle;
00395 }
00396 static void init_type() {
00397 NodeCachedReferenceCount::init_type();
00398 register_type(_type_handle, "TransformState",
00399 NodeCachedReferenceCount::get_class_type());
00400 }
00401 virtual TypeHandle get_type() const {
00402 return get_class_type();
00403 }
00404 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00405
00406 private:
00407 static TypeHandle _type_handle;
00408 };
00409
00410 INLINE ostream &operator << (ostream &out, const TransformState &state) {
00411 state.output(out);
00412 return out;
00413 }
00414
00415 #include "transformState.I"
00416
00417 #endif
00418