Panda3D
Loading...
Searching...
No Matches
transformState.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file transformState.h
10 * @author drose
11 * @date 2002-02-25
12 */
13
14#ifndef TRANSFORMSTATE_H
15#define TRANSFORMSTATE_H
16
17#include "pandabase.h"
18
20#include "pointerTo.h"
21#include "luse.h"
22#include "event.h"
23#include "updateSeq.h"
24#include "pStatCollector.h"
25#include "geomEnums.h"
26#include "lightReMutex.h"
27#include "lightReMutexHolder.h"
28#include "lightMutex.h"
29#include "lightMutexHolder.h"
30#include "config_pgraph.h"
31#include "deletedChain.h"
32#include "simpleHashMap.h"
33#include "cacheStats.h"
34#include "extension.h"
35
37class FactoryParams;
38
39/**
40 * Indicates a coordinate-system transform on vertices. TransformStates are
41 * the primary means for storing transformations on the scene graph.
42 *
43 * Transforms may be specified in one of two ways: componentwise, with a pos-
44 * hpr-scale, or with an arbitrary transform matrix. If you specify a
45 * transform componentwise, it will remember its original components.
46 *
47 * TransformState objects are managed very much like RenderState objects.
48 * They are immutable and reference-counted automatically.
49 *
50 * You should not attempt to create or modify a TransformState object
51 * directly. Instead, call one of the make() functions to create one for you.
52 * And instead of modifying a TransformState object, create a new one.
53 */
54class EXPCL_PANDA_PGRAPH TransformState final : public NodeCachedReferenceCount {
55protected:
57
58public:
59 TransformState(const TransformState &copy) = delete;
60 virtual ~TransformState();
61 ALLOC_DELETED_CHAIN(TransformState);
62
63 TransformState &operator = (const TransformState &copy) = delete;
64
65PUBLISHED:
66 INLINE bool operator != (const TransformState &other) const;
67 INLINE int compare_to(const TransformState &other) const;
68 int compare_to(const TransformState &other, bool uniquify_matrix) const;
69 bool operator == (const TransformState &other) const;
70 INLINE size_t get_hash() const;
71
72 static CPT(TransformState) make_identity();
73 static CPT(TransformState) make_invalid();
74 INLINE static CPT(TransformState) make_pos(const LVecBase3 &pos);
75 INLINE static CPT(TransformState) make_hpr(const LVecBase3 &hpr);
76 INLINE static CPT(TransformState) make_quat(const LQuaternion &quat);
77 INLINE static CPT(TransformState) make_pos_hpr(const LVecBase3 &pos,
78 const LVecBase3 &hpr);
79 INLINE static CPT(TransformState) make_scale(PN_stdfloat scale);
80 INLINE static CPT(TransformState) make_scale(const LVecBase3 &scale);
81 INLINE static CPT(TransformState) make_shear(const LVecBase3 &shear);
82 INLINE static CPT(TransformState) make_pos_hpr_scale(const LVecBase3 &pos,
83 const LVecBase3 &hpr,
84 const LVecBase3 &scale);
85 INLINE static CPT(TransformState) make_pos_quat_scale(const LVecBase3 &pos,
86 const LQuaternion &quat,
87 const LVecBase3 &scale);
88 static CPT(TransformState) make_pos_hpr_scale_shear(const LVecBase3 &pos,
89 const LVecBase3 &hpr,
90 const LVecBase3 &scale,
91 const LVecBase3 &shear);
92 static CPT(TransformState) make_pos_quat_scale_shear(const LVecBase3 &pos,
93 const LQuaternion &quat,
94 const LVecBase3 &scale,
95 const LVecBase3 &shear);
96 static CPT(TransformState) make_mat(const LMatrix4 &mat);
97
98
99 INLINE static CPT(TransformState) make_pos2d(const LVecBase2 &pos);
100 INLINE static CPT(TransformState) make_rotate2d(PN_stdfloat rotate);
101 INLINE static CPT(TransformState) make_pos_rotate2d(const LVecBase2 &pos,
102 PN_stdfloat rotate);
103 INLINE static CPT(TransformState) make_scale2d(PN_stdfloat scale);
104 INLINE static CPT(TransformState) make_scale2d(const LVecBase2 &scale);
105 INLINE static CPT(TransformState) make_shear2d(PN_stdfloat shear);
106 INLINE static CPT(TransformState) make_pos_rotate_scale2d(const LVecBase2 &pos,
107 PN_stdfloat rotate,
108 const LVecBase2 &scale);
109 static CPT(TransformState) make_pos_rotate_scale_shear2d(const LVecBase2 &pos,
110 PN_stdfloat rotate,
111 const LVecBase2 &scale,
112 PN_stdfloat shear);
113 static CPT(TransformState) make_mat3(const LMatrix3 &mat);
114
115
116 INLINE bool is_identity() const;
117 INLINE bool is_invalid() const;
118 INLINE bool is_singular() const;
119 INLINE bool is_2d() const;
120
121 INLINE bool has_components() const;
122 INLINE bool components_given() const;
123 INLINE bool hpr_given() const;
124 INLINE bool quat_given() const;
125 INLINE bool has_pos() const;
126 INLINE bool has_hpr() const;
127 INLINE bool has_quat() const;
128 INLINE bool has_scale() const;
129 INLINE bool has_identity_scale() const;
130 INLINE bool has_uniform_scale() const;
131 INLINE bool has_shear() const;
132 INLINE bool has_nonzero_shear() const;
133 INLINE bool has_mat() const;
134
135#ifdef CPPPARSER
136 // Force interrogate to make a copy as a temporary solution for #1625.
137 LPoint3 get_pos() const;
138 LVecBase3 get_hpr() const;
139 LQuaternion get_quat() const;
140 LQuaternion get_norm_quat() const;
141 LVecBase3 get_scale() const;
142 PN_stdfloat get_uniform_scale() const;
143 LVecBase3 get_shear() const;
144 LMatrix4 get_mat() const;
145#else
146 INLINE const LPoint3 &get_pos() const;
147 INLINE const LVecBase3 &get_hpr() const;
148 INLINE const LQuaternion &get_quat() const;
149 INLINE const LQuaternion &get_norm_quat() const;
150 INLINE const LVecBase3 &get_scale() const;
151 INLINE PN_stdfloat get_uniform_scale() const;
152 INLINE const LVecBase3 &get_shear() const;
153 INLINE const LMatrix4 &get_mat() const;
154#endif
155
156 INLINE LVecBase2 get_pos2d() const;
157 INLINE PN_stdfloat get_rotate2d() const;
158 INLINE LVecBase2 get_scale2d() const;
159 INLINE PN_stdfloat get_shear2d() const;
160 INLINE LMatrix3 get_mat3() const;
161
162 MAKE_PROPERTY(pos, get_pos);
163 MAKE_PROPERTY(hpr, get_hpr);
164 MAKE_PROPERTY(quat, get_quat);
165 MAKE_PROPERTY(norm_quat, get_norm_quat);
166 MAKE_PROPERTY(scale, get_scale);
167 MAKE_PROPERTY(shear, get_shear);
168 MAKE_PROPERTY(mat, get_mat);
169
170 CPT(TransformState) set_pos(const LVecBase3 &pos) const;
171 CPT(TransformState) set_hpr(const LVecBase3 &hpr) const;
172 CPT(TransformState) set_quat(const LQuaternion &quat) const;
173 CPT(TransformState) set_scale(const LVecBase3 &scale) const;
174 CPT(TransformState) set_shear(const LVecBase3 &shear) const;
175
176 CPT(TransformState) set_pos2d(const LVecBase2 &pos) const;
177 CPT(TransformState) set_rotate2d(PN_stdfloat rotate) const;
178 CPT(TransformState) set_scale2d(const LVecBase2 &scale) const;
179 CPT(TransformState) set_shear2d(PN_stdfloat shear) const;
180
181 CPT(TransformState) compose(const TransformState *other) const;
182 CPT(TransformState) invert_compose(const TransformState *other) const;
183
184 INLINE CPT(TransformState) get_inverse() const;
185 INLINE CPT(TransformState) get_unique() const;
186
187 INLINE int get_geom_rendering(int geom_rendering) const;
188
189 virtual bool unref() const;
190
191 INLINE void cache_ref() const;
192 INLINE bool cache_unref() const;
193 INLINE void node_ref() const;
194 INLINE bool node_unref() const;
195
196 INLINE size_t get_composition_cache_num_entries() const;
197 INLINE size_t get_invert_composition_cache_num_entries() const;
198
199 INLINE size_t get_composition_cache_size() const;
200 INLINE const TransformState *get_composition_cache_source(size_t n) const;
201 INLINE const TransformState *get_composition_cache_result(size_t n) const;
202 INLINE size_t get_invert_composition_cache_size() const;
203 INLINE const TransformState *get_invert_composition_cache_source(size_t n) const;
204 INLINE const TransformState *get_invert_composition_cache_result(size_t n) const;
205 bool validate_composition_cache() const;
206 EXTENSION(PyObject *get_composition_cache() const);
207 EXTENSION(PyObject *get_invert_composition_cache() const);
208
209 void output(std::ostream &out) const;
210 void write(std::ostream &out, int indent_level) const;
211 void write_composition_cache(std::ostream &out, int indent_level) const;
212
213 static int get_num_states();
214 static int get_num_unused_states();
215 static int clear_cache();
216 static int garbage_collect();
217 static void list_cycles(std::ostream &out);
218 static void list_states(std::ostream &out);
219 static bool validate_states();
220 EXTENSION(static PyObject *get_states());
221 EXTENSION(static PyObject *get_unused_states());
222
223public:
224 static void init_states();
225
226 INLINE static void flush_level();
227
228 INLINE void cache_ref_only() const;
229
230protected:
231 INLINE void cache_unref_only() const;
232
233private:
234 INLINE bool do_cache_unref() const;
235 INLINE bool do_node_unref() const;
236
237 class CompositionCycleDescEntry {
238 public:
239 INLINE CompositionCycleDescEntry(const TransformState *obj,
240 const TransformState *result,
241 bool inverted);
242
243 const TransformState *_obj;
244 const TransformState *_result;
245 bool _inverted;
246 };
247 typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
248
249 static CPT(TransformState) return_new(TransformState *state);
250 static CPT(TransformState) return_unique(TransformState *state);
251
252 CPT(TransformState) do_compose(const TransformState *other) const;
253 CPT(TransformState) do_invert_compose(const TransformState *other) const;
254 void detect_and_break_cycles();
255 static bool r_detect_cycles(const TransformState *start_state,
256 const TransformState *current_state,
257 int length, UpdateSeq this_seq,
258 CompositionCycleDesc *cycle_desc);
259 static bool r_detect_reverse_cycles(const TransformState *start_state,
260 const TransformState *current_state,
261 int length, UpdateSeq this_seq,
262 CompositionCycleDesc *cycle_desc);
263
264 void release_new();
265 void remove_cache_pointers();
266
267private:
268 // This mutex protects _states. It also protects any modification to the
269 // cache, which is encoded in _composition_cache and
270 // _invert_composition_cache.
271 static LightReMutex *_states_lock;
273 static States *_states;
274 static CPT(TransformState) _identity_state;
275 static CPT(TransformState) _invalid_state;
276
277 // This iterator records the entry corresponding to this TransformState
278 // object in the above global set. We keep the index around so we can
279 // remove it when the TransformState destructs.
280 int _saved_entry;
281
282 // This data structure manages the job of caching the composition of two
283 // TransformStates. It's complicated because we have to be sure to remove
284 // the entry if *either* of the input TransformStates destructs. To
285 // implement this, we always record Composition entries in pairs, one in
286 // each of the two involved TransformState objects.
287
288 // The first element of the map is the object we compose with. This is not
289 // reference counted within this map; instead we store a companion pointer
290 // in the other object, and remove the references explicitly when either
291 // object destructs.
292 class Composition {
293 public:
294 INLINE Composition();
295 INLINE Composition(const Composition &copy);
296
297 // _result is reference counted if and only if it is not the same pointer
298 // as this.
299 const TransformState *_result;
300 };
301
303 mutable CompositionCache _composition_cache;
304 mutable CompositionCache _invert_composition_cache;
305
306 // This is used to mark nodes as we visit them to detect cycles.
307 UpdateSeq _cycle_detect;
308 static UpdateSeq _last_cycle_detect;
309
310 // This keeps track of our current position through the garbage collection
311 // cycle.
312 static size_t _garbage_index;
313
314 static bool _uniquify_matrix;
315
316 static PStatCollector _cache_update_pcollector;
317 static PStatCollector _garbage_collect_pcollector;
318 static PStatCollector _transform_compose_pcollector;
319 static PStatCollector _transform_invert_pcollector;
320 static PStatCollector _transform_calc_pcollector;
321 static PStatCollector _transform_break_cycles_pcollector;
322 static PStatCollector _transform_new_pcollector;
323 static PStatCollector _transform_validate_pcollector;
324 static PStatCollector _transform_hash_pcollector;
325
326 static PStatCollector _node_counter;
327 static PStatCollector _cache_counter;
328
329private:
330 // This is the actual data within the TransformState.
331 INLINE void check_hash() const;
332 INLINE void check_singular() const;
333 INLINE void check_components() const;
334 INLINE void check_hpr() const;
335 INLINE void check_quat() const;
336 INLINE void check_norm_quat() const;
337 INLINE void check_mat() const;
338 INLINE void calc_hash();
339 void do_calc_hash();
340 void calc_singular();
341 INLINE void calc_components();
342 void do_calc_components();
343 INLINE void calc_hpr();
344 void do_calc_hpr();
345 void calc_quat();
346 void calc_norm_quat();
347 INLINE void calc_mat();
348 void do_calc_mat();
349
350 INLINE void check_uniform_scale();
351 INLINE void check_uniform_scale2d();
352
353 INLINE void set_destructing();
354 INLINE bool is_destructing() const;
355
356 INLINE void consider_update_pstats(int old_referenced_bits) const;
357 static void update_pstats(int old_referenced_bits, int new_referenced_bits);
358
359 enum Flags {
360 F_is_identity = 0x00000001,
361 F_is_singular = 0x00000002,
362 F_singular_known = 0x00000004, // set if we know F_is_singular
363 F_components_given = 0x00000008,
364 F_components_known = 0x00000010, // set if we know F_has_components
365 F_has_components = 0x00000020,
366 F_mat_known = 0x00000040, // set if _mat is defined
367 F_is_invalid = 0x00000080,
368 F_quat_given = 0x00000100,
369 F_quat_known = 0x00000200, // set if _quat is defined
370 F_hpr_given = 0x00000400,
371 F_hpr_known = 0x00000800, // set if _hpr is defined
372 F_uniform_scale = 0x00001000,
373 F_identity_scale = 0x00002000,
374 F_has_nonzero_shear = 0x00004000,
375 F_is_destructing = 0x00008000,
376 F_is_2d = 0x00010000,
377 F_hash_known = 0x00020000,
378 F_norm_quat_known = 0x00040000,
379 };
380 LPoint3 _pos;
381 LVecBase3 _hpr, _scale, _shear;
382 LQuaternion _quat, _norm_quat;
383 LMatrix4 _mat;
384 LMatrix4 *_inv_mat;
385 size_t _hash;
386
387 unsigned int _flags;
388
389 // This mutex protects _flags, and all of the above computed values.
390 LightMutex _lock;
391
392 static CacheStats _cache_stats;
393
394public:
395 static void register_with_read_factory();
396 virtual void write_datagram(BamWriter *manager, Datagram &dg);
397 static PT(TypedWritableReferenceCount) change_this(TypedWritableReferenceCount *old_ptr, BamReader *manager);
398
399protected:
400 static TypedWritable *make_from_bam(const FactoryParams &params);
401 void fillin(DatagramIterator &scan, BamReader *manager);
402
403public:
404 static TypeHandle get_class_type() {
405 return _type_handle;
406 }
407 static void init_type() {
408 NodeCachedReferenceCount::init_type();
409 register_type(_type_handle, "TransformState",
410 NodeCachedReferenceCount::get_class_type());
411 }
412 virtual TypeHandle get_type() const {
413 return get_class_type();
414 }
415 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
416
417private:
418 static TypeHandle _type_handle;
419
420 friend class Extension<TransformState>;
421};
422
423// We can safely redefine this as a no-op.
424template<>
425INLINE void PointerToBase<TransformState>::update_type(To *ptr) {}
426
427INLINE std::ostream &operator << (std::ostream &out, const TransformState &state) {
428 state.output(out);
429 return out;
430}
431
432#include "transformState.I"
433
434#endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
This is used to track the utilization of the TransformState and RenderState caches,...
Definition cacheStats.h:25
void cache_ref() const
Explicitly increments the cache reference count and the normal reference count simultaneously.
bool cache_unref() const
Explicitly decrements the cache reference count and the normal reference count simultaneously.
void cache_ref_only() const
Decrements the cache reference count without affecting the normal reference count.
A class to retrieve the individual data elements previously stored in a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
The default class template does not define any methods.
Definition extension.h:34
An instance of this class is passed to the Factory when requesting it to do its business and construc...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition lightMutex.h:41
A lightweight reentrant mutex.
This class further specializes CachedTypedWritableReferenceCount to also add a node_ref_count,...
bool node_unref() const
Explicitly decrements the node reference count and the normal reference count simultaneously.
void node_ref() const
Explicitly increments the reference count.
A lightweight class that represents a single element that may be timed and/or counted via stats.
This is the base class for PointerTo and ConstPointerTo.
This template class implements an unordered map of keys to data, implemented as a hashtable.
Indicates a coordinate-system transform on vertices.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
virtual bool unref() const
Explicitly decrements the reference count.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
Base class for objects that can be written to and read from Bam files.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
An STL function object class, this is intended to be used on any ordered collection of class objects ...
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
STTransform::operator CPT TransformState() const
This is used internally to convert an STTransform into a TransformState pointer.
Definition stTransform.I:98
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.