Panda3D
transformState.I
1 // Filename: transformState.I
2 // Created by: drose (25Feb02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: TransformState::operator !=
18 // Access: Published
19 // Description: Opposite of operator ==.
20 ////////////////////////////////////////////////////////////////////
21 INLINE bool TransformState::
22 operator != (const TransformState &other) const {
23  return !(operator == (other));
24 }
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: TransformState::compare_to
28 // Access: Published
29 // Description: Provides an arbitrary ordering among all unique
30 // TransformStates, so we can store the essentially
31 // different ones in a big set and throw away the rest.
32 //
33 // Note that if this returns 0, it doesn't necessarily
34 // imply that operator == returns true; it uses a very
35 // slightly different comparison threshold.
36 ////////////////////////////////////////////////////////////////////
37 INLINE int TransformState::
38 compare_to(const TransformState &other) const {
39  return compare_to(other, _uniquify_matrix);
40 }
41 
42 ////////////////////////////////////////////////////////////////////
43 // Function: TransformState::get_hash
44 // Access: Published
45 // Description: Returns a suitable hash value for phash_map.
46 ////////////////////////////////////////////////////////////////////
47 INLINE size_t TransformState::
48 get_hash() const {
49  check_hash();
50  return _hash;
51 }
52 
53 ////////////////////////////////////////////////////////////////////
54 // Function: TransformState::make_pos
55 // Access: Published, Static
56 // Description: Makes a new TransformState with the specified
57 // components.
58 ////////////////////////////////////////////////////////////////////
59 INLINE CPT(TransformState) TransformState::
60 make_pos(const LVecBase3 &pos) {
61  return make_pos_hpr_scale(pos,
62  LVecBase3(0.0f, 0.0f, 0.0f),
63  LVecBase3(1.0f, 1.0f, 1.0f));
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: TransformState::make_hpr
68 // Access: Published, Static
69 // Description: Makes a new TransformState with the specified
70 // components.
71 ////////////////////////////////////////////////////////////////////
72 INLINE CPT(TransformState) TransformState::
73 make_hpr(const LVecBase3 &hpr) {
74  return make_pos_hpr_scale(LVecBase3(0.0f, 0.0f, 0.0f),
75  hpr,
76  LVecBase3(1.0f, 1.0f, 1.0f));
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: TransformState::make_quat
81 // Access: Published, Static
82 // Description: Makes a new TransformState with the specified
83 // components.
84 ////////////////////////////////////////////////////////////////////
85 INLINE CPT(TransformState) TransformState::
86 make_quat(const LQuaternion &quat) {
87  return make_pos_quat_scale(LVecBase3(0.0f, 0.0f, 0.0f),
88  quat,
89  LVecBase3(1.0f, 1.0f, 1.0f));
90 }
91 
92 ////////////////////////////////////////////////////////////////////
93 // Function: TransformState::make_pos_hpr
94 // Access: Published, Static
95 // Description: Makes a new TransformState with the specified
96 // components.
97 ////////////////////////////////////////////////////////////////////
98 INLINE CPT(TransformState) TransformState::
99 make_pos_hpr(const LVecBase3 &pos, const LVecBase3 &hpr) {
100  return make_pos_hpr_scale(pos, hpr,
101  LVecBase3(1.0, 1.0f, 1.0f));
102 }
103 
104 ////////////////////////////////////////////////////////////////////
105 // Function: TransformState::make_scale
106 // Access: Published, Static
107 // Description: Makes a new TransformState with the specified
108 // components.
109 ////////////////////////////////////////////////////////////////////
110 INLINE CPT(TransformState) TransformState::
111 make_scale(PN_stdfloat scale) {
112  // We actually map this 3-d uniform make_scale() to the 2-d
113  // version--might as well call it a 2-d scale.
114  return make_scale2d(scale);
115 }
116 
117 ////////////////////////////////////////////////////////////////////
118 // Function: TransformState::make_scale
119 // Access: Published, Static
120 // Description: Makes a new TransformState with the specified
121 // components.
122 ////////////////////////////////////////////////////////////////////
123 INLINE CPT(TransformState) TransformState::
124 make_scale(const LVecBase3 &scale) {
125  return make_pos_hpr_scale(LVecBase3(0.0f, 0.0f, 0.0f),
126  LVecBase3(0.0f, 0.0f, 0.0f),
127  scale);
128 }
129 
130 ////////////////////////////////////////////////////////////////////
131 // Function: TransformState::make_shear
132 // Access: Published, Static
133 // Description: Makes a new TransformState with the specified
134 // components.
135 ////////////////////////////////////////////////////////////////////
136 INLINE CPT(TransformState) TransformState::
137 make_shear(const LVecBase3 &shear) {
138  return make_pos_hpr_scale_shear(LVecBase3(0.0f, 0.0f, 0.0f),
139  LVecBase3(0.0f, 0.0f, 0.0f),
140  LVecBase3(1.0f, 1.0f, 1.0f),
141  shear);
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function: TransformState::make_pos_hpr_scale
146 // Access: Published, Static
147 // Description: Makes a new TransformState with the specified
148 // components.
149 ////////////////////////////////////////////////////////////////////
150 INLINE CPT(TransformState) TransformState::
151 make_pos_hpr_scale(const LVecBase3 &pos, const LVecBase3 &hpr,
152  const LVecBase3 &scale) {
153  return make_pos_hpr_scale_shear(pos, hpr, scale, LVecBase3::zero());
154 }
155 
156 ////////////////////////////////////////////////////////////////////
157 // Function: TransformState::make_pos_quat_scale
158 // Access: Published, Static
159 // Description: Makes a new TransformState with the specified
160 // components.
161 ////////////////////////////////////////////////////////////////////
162 INLINE CPT(TransformState) TransformState::
163 make_pos_quat_scale(const LVecBase3 &pos, const LQuaternion &quat,
164  const LVecBase3 &scale) {
165  return make_pos_quat_scale_shear(pos, quat, scale, LVecBase3::zero());
166 }
167 
168 ////////////////////////////////////////////////////////////////////
169 // Function: TransformState::make_pos2d
170 // Access: Published, Static
171 // Description: Makes a new 2-d TransformState with the specified
172 // components.
173 ////////////////////////////////////////////////////////////////////
174 INLINE CPT(TransformState) TransformState::
175 make_pos2d(const LVecBase2 &pos) {
176  return make_pos_rotate_scale2d(pos, 0.0f, LVecBase2(1.0f, 1.0f));
177 }
178 
179 ////////////////////////////////////////////////////////////////////
180 // Function: TransformState::make_rotate2d
181 // Access: Published, Static
182 // Description: Makes a new 2-d TransformState with the specified
183 // components.
184 ////////////////////////////////////////////////////////////////////
185 INLINE CPT(TransformState) TransformState::
186 make_rotate2d(PN_stdfloat rotate) {
187  return make_pos_rotate_scale2d(LVecBase2(0.0f, 0.0f), rotate,
188  LVecBase2(1.0f, 1.0f));
189 }
190 
191 ////////////////////////////////////////////////////////////////////
192 // Function: TransformState::make_pos_rotate2d
193 // Access: Published, Static
194 // Description: Makes a new 2-d TransformState with the specified
195 // components.
196 ////////////////////////////////////////////////////////////////////
197 INLINE CPT(TransformState) TransformState::
198 make_pos_rotate2d(const LVecBase2 &pos, PN_stdfloat rotate) {
199  return make_pos_rotate_scale2d(pos, rotate,
200  LVecBase2(1.0, 1.0f));
201 }
202 
203 ////////////////////////////////////////////////////////////////////
204 // Function: TransformState::make_scale2d
205 // Access: Published, Static
206 // Description: Makes a new 2-d TransformState with the specified
207 // components.
208 ////////////////////////////////////////////////////////////////////
209 INLINE CPT(TransformState) TransformState::
210 make_scale2d(PN_stdfloat scale) {
211  return make_pos_rotate_scale2d(LVecBase2(0.0f, 0.0f), 0.0f,
212  LVecBase2(scale, scale));
213 }
214 
215 ////////////////////////////////////////////////////////////////////
216 // Function: TransformState::make_scale2d
217 // Access: Published, Static
218 // Description: Makes a new 2-d TransformState with the specified
219 // components.
220 ////////////////////////////////////////////////////////////////////
221 INLINE CPT(TransformState) TransformState::
222 make_scale2d(const LVecBase2 &scale) {
223  return make_pos_rotate_scale2d(LVecBase2(0.0f, 0.0f), 0.0f, scale);
224 }
225 
226 ////////////////////////////////////////////////////////////////////
227 // Function: TransformState::make_shear2d
228 // Access: Published, Static
229 // Description: Makes a new 2-d TransformState with the specified
230 // components.
231 ////////////////////////////////////////////////////////////////////
232 INLINE CPT(TransformState) TransformState::
233 make_shear2d(PN_stdfloat shear) {
234  return make_pos_rotate_scale_shear2d(LVecBase2(0.0f, 0.0f), 0.0f,
235  LVecBase2(1.0f, 1.0f), shear);
236 }
237 
238 ////////////////////////////////////////////////////////////////////
239 // Function: TransformState::make_pos_rotate_scale2d
240 // Access: Published, Static
241 // Description: Makes a new 2-d TransformState with the specified
242 // components.
243 ////////////////////////////////////////////////////////////////////
244 INLINE CPT(TransformState) TransformState::
245 make_pos_rotate_scale2d(const LVecBase2 &pos, PN_stdfloat rotate,
246  const LVecBase2 &scale) {
247  return make_pos_rotate_scale_shear2d(pos, rotate, scale, 0.0f);
248 }
249 
250 ////////////////////////////////////////////////////////////////////
251 // Function: TransformState::is_identity
252 // Access: Published
253 // Description: Returns true if the transform represents the identity
254 // matrix, false otherwise.
255 ////////////////////////////////////////////////////////////////////
256 INLINE bool TransformState::
257 is_identity() const {
258  return ((_flags & F_is_identity) != 0);
259 }
260 
261 ////////////////////////////////////////////////////////////////////
262 // Function: TransformState::is_invalid
263 // Access: Published
264 // Description: Returns true if the transform represents an invalid
265 // matrix, for instance the result of inverting a
266 // singular matrix, or false if the transform is valid.
267 ////////////////////////////////////////////////////////////////////
268 INLINE bool TransformState::
269 is_invalid() const {
270  return ((_flags & F_is_invalid) != 0);
271 }
272 
273 ////////////////////////////////////////////////////////////////////
274 // Function: TransformState::is_singular
275 // Access: Published
276 // Description: Returns true if the transform represents a singular
277 // transform (that is, it has a zero scale, and it
278 // cannot be inverted), or false otherwise.
279 ////////////////////////////////////////////////////////////////////
280 INLINE bool TransformState::
281 is_singular() const {
282  check_singular();
283  return ((_flags & F_is_singular) != 0);
284 }
285 
286 ////////////////////////////////////////////////////////////////////
287 // Function: TransformState::is_2d
288 // Access: Published
289 // Description: Returns true if the transform has been constructed
290 // entirely using the 2-d transform operations,
291 // e.g. make_pos2d(), and therefore operates strictly in
292 // two-dimensional space on X and Y only.
293 ////////////////////////////////////////////////////////////////////
294 INLINE bool TransformState::
295 is_2d() const {
296  return ((_flags & F_is_2d) != 0);
297 }
298 
299 ////////////////////////////////////////////////////////////////////
300 // Function: TransformState::has_components
301 // Access: Published
302 // Description: Returns true if the transform can be described by
303 // separate pos, hpr, and scale components. Most
304 // transforms we use in everyday life can be so
305 // described, but some kinds of transforms (for
306 // instance, those involving a skew) cannot.
307 //
308 // This is not related to whether the transform was
309 // originally described componentwise. Even a transform
310 // that was constructed with a 4x4 may return true here
311 // if the matrix is a simple affine matrix with no skew.
312 //
313 // If this returns true, you may safely call get_hpr()
314 // and get_scale() to retrieve the components. (You
315 // may always safely call get_pos() whether this returns
316 // true or false.)
317 ////////////////////////////////////////////////////////////////////
318 INLINE bool TransformState::
319 has_components() const {
320  check_components();
321  return ((_flags & F_has_components) != 0);
322 }
323 
324 ////////////////////////////////////////////////////////////////////
325 // Function: TransformState::components_given
326 // Access: Published
327 // Description: Returns true if the transform was specified
328 // componentwise, or false if it was specified with a
329 // general 4x4 matrix. If this is true, the components
330 // returned by get_pos() and get_scale() will be exactly
331 // those that were set; otherwise, these functions will
332 // return computed values. If this is true, the
333 // rotation may have been set either with a hpr trio or
334 // with a quaternion; hpr_given() or quat_given() can
335 // resolve the difference.
336 ////////////////////////////////////////////////////////////////////
337 INLINE bool TransformState::
338 components_given() const {
339  return ((_flags & F_components_given) != 0);
340 }
341 
342 ////////////////////////////////////////////////////////////////////
343 // Function: TransformState::hpr_given
344 // Access: Published
345 // Description: Returns true if the rotation was specified via a trio
346 // of Euler angles, false otherwise. If this is true,
347 // get_hpr() will be exactly as set; otherwise, it will
348 // return a computed value.
349 ////////////////////////////////////////////////////////////////////
350 INLINE bool TransformState::
351 hpr_given() const {
352  return ((_flags & F_hpr_given) != 0);
353 }
354 
355 ////////////////////////////////////////////////////////////////////
356 // Function: TransformState::quat_given
357 // Access: Published
358 // Description: Returns true if the rotation was specified via a
359 // quaternion, false otherwise. If this is true,
360 // get_quat() will be exactly as set; otherwise, it will
361 // return a computed value.
362 ////////////////////////////////////////////////////////////////////
363 INLINE bool TransformState::
364 quat_given() const {
365  return ((_flags & F_quat_given) != 0);
366 }
367 
368 ////////////////////////////////////////////////////////////////////
369 // Function: TransformState::has_pos
370 // Access: Published
371 // Description: Returns true if the transform's pos component can be
372 // extracted out separately. This is generally always
373 // true, unless the transform is invalid
374 // (i.e. is_invalid() returns true).
375 ////////////////////////////////////////////////////////////////////
376 INLINE bool TransformState::
377 has_pos() const {
378  return !is_invalid();
379 }
380 
381 ////////////////////////////////////////////////////////////////////
382 // Function: TransformState::has_hpr
383 // Access: Published
384 // Description: Returns true if the transform's rotation component
385 // can be extracted out separately and described as a
386 // set of Euler angles. This is generally true only
387 // when has_components() is true.
388 ////////////////////////////////////////////////////////////////////
389 INLINE bool TransformState::
390 has_hpr() const {
391  return has_components();
392 }
393 
394 ////////////////////////////////////////////////////////////////////
395 // Function: TransformState::has_quat
396 // Access: Published
397 // Description: Returns true if the transform's rotation component
398 // can be extracted out separately and described as a
399 // quaternion. This is generally true only when
400 // has_components() is true.
401 ////////////////////////////////////////////////////////////////////
402 INLINE bool TransformState::
403 has_quat() const {
404  return has_components();
405 }
406 
407 ////////////////////////////////////////////////////////////////////
408 // Function: TransformState::has_scale
409 // Access: Published
410 // Description: Returns true if the transform's scale component
411 // can be extracted out separately. This is generally
412 // true only when has_components() is true.
413 ////////////////////////////////////////////////////////////////////
414 INLINE bool TransformState::
415 has_scale() const {
416  return has_components();
417 }
418 
419 ////////////////////////////////////////////////////////////////////
420 // Function: TransformState::has_identity_scale
421 // Access: Published
422 // Description: Returns true if the scale is uniform 1.0, or false if
423 // the scale has some real value.
424 ////////////////////////////////////////////////////////////////////
425 INLINE bool TransformState::
426 has_identity_scale() const {
427  check_components();
428  return (_flags & F_identity_scale) != 0;
429 }
430 
431 ////////////////////////////////////////////////////////////////////
432 // Function: TransformState::has_uniform_scale
433 // Access: Published
434 // Description: Returns true if the scale is uniform across all three
435 // axes (and therefore can be expressed as a single
436 // number), or false if the transform has a different
437 // scale in different dimensions.
438 ////////////////////////////////////////////////////////////////////
439 INLINE bool TransformState::
440 has_uniform_scale() const {
441  check_components();
442  return (_flags & F_uniform_scale) != 0;
443 }
444 
445 ////////////////////////////////////////////////////////////////////
446 // Function: TransformState::has_shear
447 // Access: Published
448 // Description: Returns true if the transform's shear component
449 // can be extracted out separately. This is generally
450 // true only when has_components() is true.
451 ////////////////////////////////////////////////////////////////////
452 INLINE bool TransformState::
453 has_shear() const {
454  return has_components();
455 }
456 
457 ////////////////////////////////////////////////////////////////////
458 // Function: TransformState::has_nonzero_shear
459 // Access: Published
460 // Description: Returns true if the shear component is non-zero,
461 // false if it is zero or if the matrix cannot be
462 // decomposed.
463 ////////////////////////////////////////////////////////////////////
464 INLINE bool TransformState::
465 has_nonzero_shear() const {
466  check_components();
467  return (_flags & F_has_nonzero_shear) != 0;
468 }
469 
470 ////////////////////////////////////////////////////////////////////
471 // Function: TransformState::has_mat
472 // Access: Published
473 // Description: Returns true if the transform can be described as a
474 // matrix. This is generally always true, unless
475 // is_invalid() is true.
476 ////////////////////////////////////////////////////////////////////
477 INLINE bool TransformState::
478 has_mat() const {
479  return !is_invalid();
480 }
481 
482 ////////////////////////////////////////////////////////////////////
483 // Function: TransformState::get_pos
484 // Access: Published
485 // Description: Returns the pos component of the transform. It is an
486 // error to call this if has_pos() returned false.
487 ////////////////////////////////////////////////////////////////////
488 INLINE const LPoint3 &TransformState::
489 get_pos() const {
490  check_components();
491  nassertr(has_pos(), _pos);
492  return _pos;
493 }
494 
495 ////////////////////////////////////////////////////////////////////
496 // Function: TransformState::get_hpr
497 // Access: Published
498 // Description: Returns the rotation component of the transform as a
499 // trio of Euler angles. It is an error to call this if
500 // has_components() returned false.
501 ////////////////////////////////////////////////////////////////////
502 INLINE const LVecBase3 &TransformState::
503 get_hpr() const {
504  check_hpr();
505  nassertr(!is_invalid(), _hpr);
506  return _hpr;
507 }
508 
509 ////////////////////////////////////////////////////////////////////
510 // Function: TransformState::get_quat
511 // Access: Published
512 // Description: Returns the rotation component of the transform as a
513 // quaternion. The return value will be normalized if a
514 // normalized quaternion was given to the constructor
515 // (or if the quaternion was computed implicitly); it
516 // will be non-normalized if a non-normalized quaternion
517 // was given to the constructor. See also
518 // get_norm_quat().
519 //
520 // It is an error to call this if has_components()
521 // returned false.
522 ////////////////////////////////////////////////////////////////////
523 INLINE const LQuaternion &TransformState::
524 get_quat() const {
525  check_quat();
526  nassertr(!is_invalid(), _quat);
527  return _quat;
528 }
529 
530 ////////////////////////////////////////////////////////////////////
531 // Function: TransformState::get_norm_quat
532 // Access: Published
533 // Description: Returns the rotation component of the transform as a
534 // quaternion. Unlike the result of get_quat(), the
535 // return value of this method is guaranteed to be
536 // normalized. It is an error to call this if
537 // has_components() returned false.
538 ////////////////////////////////////////////////////////////////////
539 INLINE const LQuaternion &TransformState::
540 get_norm_quat() const {
541  check_norm_quat();
542  nassertr(!is_invalid(), _norm_quat);
543  return _norm_quat;
544 }
545 
546 ////////////////////////////////////////////////////////////////////
547 // Function: TransformState::get_scale
548 // Access: Published
549 // Description: Returns the scale component of the transform. It is an
550 // error to call this if has_components() returned
551 // false.
552 ////////////////////////////////////////////////////////////////////
553 INLINE const LVecBase3 &TransformState::
554 get_scale() const {
555  check_components();
556  nassertr(!is_invalid(), _scale);
557  return _scale;
558 }
559 
560 ////////////////////////////////////////////////////////////////////
561 // Function: TransformState::get_uniform_scale
562 // Access: Published
563 // Description: Returns the scale component of the transform, as a
564 // single number. It is an error to call this if
565 // has_uniform_scale() returned false.
566 ////////////////////////////////////////////////////////////////////
567 INLINE PN_stdfloat TransformState::
568 get_uniform_scale() const {
569  check_components();
570  nassertr(has_uniform_scale(), _scale[0]);
571  return _scale[0];
572 }
573 
574 ////////////////////////////////////////////////////////////////////
575 // Function: TransformState::get_shear
576 // Access: Published
577 // Description: Returns the shear component of the transform. It is
578 // an error to call this if has_components() returned
579 // false.
580 ////////////////////////////////////////////////////////////////////
581 INLINE const LVecBase3 &TransformState::
582 get_shear() const {
583  check_components();
584  nassertr(!is_invalid(), _shear);
585  return _shear;
586 }
587 
588 ////////////////////////////////////////////////////////////////////
589 // Function: TransformState::get_mat
590 // Access: Published
591 // Description: Returns the matrix that describes the transform.
592 ////////////////////////////////////////////////////////////////////
593 INLINE const LMatrix4 &TransformState::
594 get_mat() const {
595  nassertr(has_mat(), LMatrix4::ident_mat());
596  check_mat();
597  return _mat;
598 }
599 
600 ////////////////////////////////////////////////////////////////////
601 // Function: TransformState::get_pos2d
602 // Access: Published
603 // Description: Returns the pos component of the 2-d transform. It
604 // is an error to call this if has_pos() or is_2d()
605 // returned false.
606 ////////////////////////////////////////////////////////////////////
607 INLINE LVecBase2 TransformState::
608 get_pos2d() const {
609  check_components();
610  nassertr(has_pos() && is_2d(), LVecBase2::zero());
611  return LVecBase2(_pos[0], _pos[1]);
612 }
613 
614 ////////////////////////////////////////////////////////////////////
615 // Function: TransformState::get_rotate2d
616 // Access: Published
617 // Description: Returns the rotation component of the 2-d transform
618 // as an angle in degrees clockwise about the origin.
619 // It is an error to call this if has_components() or
620 // is_2d() returned false.
621 ////////////////////////////////////////////////////////////////////
622 INLINE PN_stdfloat TransformState::
623 get_rotate2d() const {
624  check_hpr();
625  nassertr(!is_invalid() && is_2d(), 0);
626  switch (get_default_coordinate_system()) {
627  default:
628  case CS_zup_right:
629  return _hpr[0];
630  case CS_zup_left:
631  return -_hpr[0];
632  case CS_yup_right:
633  return -_hpr[2];
634  case CS_yup_left:
635  return _hpr[2];
636  }
637 }
638 
639 ////////////////////////////////////////////////////////////////////
640 // Function: TransformState::get_scale2d
641 // Access: Published
642 // Description: Returns the scale component of the 2-d transform. It
643 // is an error to call this if has_components() or
644 // is_2d() returned false.
645 ////////////////////////////////////////////////////////////////////
646 INLINE LVecBase2 TransformState::
647 get_scale2d() const {
648  check_components();
649  nassertr(!is_invalid() && is_2d(), LVecBase2::zero());
650  return LVecBase2(_scale[0], _scale[1]);
651 }
652 
653 ////////////////////////////////////////////////////////////////////
654 // Function: TransformState::get_shear2d
655 // Access: Published
656 // Description: Returns the shear component of the 2-d transform. It
657 // is an error to call this if has_components() or
658 // is_2d() returned false.
659 ////////////////////////////////////////////////////////////////////
660 INLINE PN_stdfloat TransformState::
661 get_shear2d() const {
662  check_components();
663  nassertr(!is_invalid() && is_2d(), 0.0f);
664  return _shear[0];
665 }
666 
667 ////////////////////////////////////////////////////////////////////
668 // Function: TransformState::get_mat3
669 // Access: Published
670 // Description: Returns the 3x3 matrix that describes the 2-d
671 // transform. It is an error to call this if is_2d()
672 // returned false.
673 ////////////////////////////////////////////////////////////////////
674 INLINE LMatrix3 TransformState::
675 get_mat3() const {
676  nassertr(has_mat() && is_2d(), LMatrix3::ident_mat());
677  check_mat();
678  return LMatrix3(_mat(0, 0), _mat(0, 1), _mat(0, 3),
679  _mat(1, 0), _mat(1, 1), _mat(1, 3),
680  _mat(3, 0), _mat(3, 1), _mat(3, 3));
681 }
682 
683 ////////////////////////////////////////////////////////////////////
684 // Function: TransformState::get_inverse
685 // Access: Published
686 // Description: Returns the inverse of this transform. If you are
687 // going to immediately compose this result with another
688 // TransformState, it is faster to do it in one
689 // operation with invert_compose().
690 ////////////////////////////////////////////////////////////////////
691 INLINE CPT(TransformState) TransformState::
692 get_inverse() const {
693  return invert_compose(TransformState::make_identity());
694 }
695 
696 ////////////////////////////////////////////////////////////////////
697 // Function: TransformState::get_unique
698 // Access: Published
699 // Description: Returns the pointer to the unique TransformState in
700 // the cache that is equivalent to this one. This may
701 // be the same pointer as this object, or it may be a
702 // different pointer; but it will be an equivalent
703 // object, and it will be a shared pointer. This may be
704 // called from time to time to improve cache benefits.
705 ////////////////////////////////////////////////////////////////////
706 INLINE CPT(TransformState) TransformState::
707 get_unique() const {
708  return return_unique((TransformState *)this);
709 }
710 
711 ////////////////////////////////////////////////////////////////////
712 // Function: TransformState::get_geom_rendering
713 // Access: Published
714 // Description: Returns the union of the Geom::GeomRendering bits
715 // that will be required once this TransformState is
716 // applied to a geom which includes the indicated
717 // geom_rendering bits. The RenderState's
718 // get_geom_rendering() should already have been
719 // applied.
720 ////////////////////////////////////////////////////////////////////
721 INLINE int TransformState::
722 get_geom_rendering(int geom_rendering) const {
723  if ((geom_rendering & GeomEnums::GR_point_perspective) != 0) {
724  if (!has_identity_scale()) {
725  geom_rendering |= GeomEnums::GR_point_scale;
726  }
727  }
728 
729  return geom_rendering;
730 }
731 
732 ////////////////////////////////////////////////////////////////////
733 // Function: TransformState::cache_ref
734 // Access: Published
735 // Description: Overrides this method to update PStats appropriately.
736 ////////////////////////////////////////////////////////////////////
737 INLINE void TransformState::
738 cache_ref() const {
739 #ifdef DO_PSTATS
740  int old_referenced_bits = get_referenced_bits();
742  consider_update_pstats(old_referenced_bits);
743 #else // DO_PSTATS
745 #endif // DO_PSTATS
746 }
747 
748 ////////////////////////////////////////////////////////////////////
749 // Function: TransformState::cache_unref
750 // Access: Published
751 // Description: Overrides this method to update PStats appropriately.
752 ////////////////////////////////////////////////////////////////////
753 INLINE bool TransformState::
754 cache_unref() const {
755 #ifdef DO_PSTATS
756  int old_referenced_bits = get_referenced_bits();
757  bool result = do_cache_unref();
758  consider_update_pstats(old_referenced_bits);
759  return result;
760 #else // DO_PSTATS
761  return do_cache_unref();
762 #endif // DO_PSTATS
763 }
764 
765 ////////////////////////////////////////////////////////////////////
766 // Function: TransformState::node_ref
767 // Access: Published
768 // Description: Overrides this method to update PStats appropriately.
769 ////////////////////////////////////////////////////////////////////
770 INLINE void TransformState::
771 node_ref() const {
772 #ifdef DO_PSTATS
773  int old_referenced_bits = get_referenced_bits();
775  consider_update_pstats(old_referenced_bits);
776 #else // DO_PSTATS
778 #endif // DO_PSTATS
779 }
780 
781 ////////////////////////////////////////////////////////////////////
782 // Function: TransformState::node_unref
783 // Access: Published
784 // Description: Overrides this method to update PStats appropriately.
785 ////////////////////////////////////////////////////////////////////
786 INLINE bool TransformState::
787 node_unref() const {
788 #ifdef DO_PSTATS
789  int old_referenced_bits = get_referenced_bits();
790  bool result = do_node_unref();
791  consider_update_pstats(old_referenced_bits);
792  return result;
793 #else // DO_PSTATS
794  return do_node_unref();
795 #endif // DO_PSTATS
796 }
797 
798 ////////////////////////////////////////////////////////////////////
799 // Function: TransformState::get_composition_cache_num_entries
800 // Access: Published
801 // Description: Returns the number of entries in the composition
802 // cache for this TransformState. This is the number of
803 // other TransformStates whose composition with this one
804 // has been cached. This number is not useful for any
805 // practical reason other than performance analysis.
806 ////////////////////////////////////////////////////////////////////
807 INLINE int TransformState::
808 get_composition_cache_num_entries() const {
809  LightReMutexHolder holder(*_states_lock);
810  return _composition_cache.get_num_entries();
811 }
812 
813 ////////////////////////////////////////////////////////////////////
814 // Function: TransformState::get_invert_composition_cache_num_entries
815 // Access: Published
816 // Description: Returns the number of entries in the
817 // invert_composition cache for this TransformState.
818 // This is similar to the composition cache, but it
819 // records cache entries for the invert_compose()
820 // operation. See get_composition_cache_num_entries().
821 ////////////////////////////////////////////////////////////////////
822 INLINE int TransformState::
823 get_invert_composition_cache_num_entries() const {
824  LightReMutexHolder holder(*_states_lock);
825  return _invert_composition_cache.get_num_entries();
826 }
827 
828 ////////////////////////////////////////////////////////////////////
829 // Function: TransformState::get_composition_cache_size
830 // Access: Published
831 // Description: Returns the number of slots in the composition
832 // cache for this TransformState. You may use this as
833 // an upper bound when walking through all of the
834 // composition cache results via
835 // get_composition_cache_source() or result().
836 //
837 // This has no practical value other than for examining
838 // the cache for performance analysis.
839 ////////////////////////////////////////////////////////////////////
840 INLINE int TransformState::
841 get_composition_cache_size() const {
842  LightReMutexHolder holder(*_states_lock);
843  return _composition_cache.get_size();
844 }
845 
846 ////////////////////////////////////////////////////////////////////
847 // Function: TransformState::get_composition_cache_source
848 // Access: Published
849 // Description: Returns the source TransformState of the nth element
850 // in the composition cache. Returns NULL if there
851 // doesn't happen to be an entry in the nth element.
852 // See get_composition_cache_result().
853 //
854 // This has no practical value other than for examining
855 // the cache for performance analysis.
856 ////////////////////////////////////////////////////////////////////
857 INLINE const TransformState *TransformState::
858 get_composition_cache_source(int n) const {
859  LightReMutexHolder holder(*_states_lock);
860  if (!_composition_cache.has_element(n)) {
861  return NULL;
862  }
863  return _composition_cache.get_key(n);
864 }
865 
866 ////////////////////////////////////////////////////////////////////
867 // Function: TransformState::get_composition_cache_result
868 // Access: Published
869 // Description: Returns the result TransformState of the nth element
870 // in the composition cache. Returns NULL if there
871 // doesn't happen to be an entry in the nth element.
872 //
873 // In general,
874 // a->compose(a->get_composition_cache_source(n)) ==
875 // a->get_composition_cache_result(n).
876 //
877 // This has no practical value other than for examining
878 // the cache for performance analysis.
879 ////////////////////////////////////////////////////////////////////
880 INLINE const TransformState *TransformState::
881 get_composition_cache_result(int n) const {
882  LightReMutexHolder holder(*_states_lock);
883  if (!_composition_cache.has_element(n)) {
884  return NULL;
885  }
886  return _composition_cache.get_data(n)._result;
887 }
888 
889 ////////////////////////////////////////////////////////////////////
890 // Function: TransformState::get_invert_composition_cache_size
891 // Access: Published
892 // Description: Returns the number of slots in the composition
893 // cache for this TransformState. You may use this as
894 // an upper bound when walking through all of the
895 // composition cache results via
896 // get_invert_composition_cache_source() or result().
897 //
898 // This has no practical value other than for examining
899 // the cache for performance analysis.
900 ////////////////////////////////////////////////////////////////////
901 INLINE int TransformState::
902 get_invert_composition_cache_size() const {
903  LightReMutexHolder holder(*_states_lock);
904  return _invert_composition_cache.get_size();
905 }
906 
907 ////////////////////////////////////////////////////////////////////
908 // Function: TransformState::get_invert_composition_cache_source
909 // Access: Published
910 // Description: Returns the source TransformState of the nth element
911 // in the invert composition cache. Returns NULL if
912 // there doesn't happen to be an entry in the nth
913 // element. See get_invert_composition_cache_result().
914 //
915 // This has no practical value other than for examining
916 // the cache for performance analysis.
917 ////////////////////////////////////////////////////////////////////
918 INLINE const TransformState *TransformState::
919 get_invert_composition_cache_source(int n) const {
920  LightReMutexHolder holder(*_states_lock);
921  if (!_invert_composition_cache.has_element(n)) {
922  return NULL;
923  }
924  return _invert_composition_cache.get_key(n);
925 }
926 
927 ////////////////////////////////////////////////////////////////////
928 // Function: TransformState::get_invert_composition_cache_result
929 // Access: Published
930 // Description: Returns the result TransformState of the nth element
931 // in the invert composition cache. Returns NULL if
932 // there doesn't happen to be an entry in the nth
933 // element.
934 //
935 // In general,
936 // a->invert_compose(a->get_invert_composition_cache_source(n))
937 // == a->get_invert_composition_cache_result(n).
938 //
939 // This has no practical value other than for examining
940 // the cache for performance analysis.
941 ////////////////////////////////////////////////////////////////////
942 INLINE const TransformState *TransformState::
943 get_invert_composition_cache_result(int n) const {
944  LightReMutexHolder holder(*_states_lock);
945  if (!_invert_composition_cache.has_element(n)) {
946  return NULL;
947  }
948  return _invert_composition_cache.get_data(n)._result;
949 }
950 
951 ////////////////////////////////////////////////////////////////////
952 // Function: TransformState::flush_level
953 // Access: Public, Static
954 // Description: Flushes the PStatCollectors used during traversal.
955 ////////////////////////////////////////////////////////////////////
956 INLINE void TransformState::
957 flush_level() {
958  _node_counter.flush_level();
959  _cache_counter.flush_level();
960 }
961 
962 ////////////////////////////////////////////////////////////////////
963 // Function: TransformState::do_node_unref
964 // Access: Private
965 // Description: Reimplements NodeReferenceCount::node_unref(). We do
966 // this because we have a non-virtual unref() method.
967 ////////////////////////////////////////////////////////////////////
968 INLINE bool TransformState::
969 do_node_unref() const {
970  node_unref_only();
971  return unref();
972 }
973 
974 ////////////////////////////////////////////////////////////////////
975 // Function: TransformState::do_cache_unref
976 // Access: Private
977 // Description: Reimplements
978 // CachedTypedWritableReferenceCount::cache_unref(). We
979 // do this because we have a non-virtual unref() method.
980 ////////////////////////////////////////////////////////////////////
981 INLINE bool TransformState::
982 do_cache_unref() const {
983  cache_unref_only();
984  return unref();
985 }
986 
987 ////////////////////////////////////////////////////////////////////
988 // Function: TransformState::check_hash
989 // Access: Private
990 // Description: Ensures that we know the hash value.
991 ////////////////////////////////////////////////////////////////////
992 INLINE void TransformState::
993 check_hash() const {
994  // This pretends to be a const function, even though it's not,
995  // because it only updates a transparent cache value.
996  if ((_flags & F_hash_known) == 0) {
997  ((TransformState *)this)->calc_hash();
998  }
999 }
1000 
1001 ////////////////////////////////////////////////////////////////////
1002 // Function: TransformState::check_singular
1003 // Access: Private
1004 // Description: Ensures that we know whether the matrix is singular.
1005 ////////////////////////////////////////////////////////////////////
1006 INLINE void TransformState::
1007 check_singular() const {
1008  // This pretends to be a const function, even though it's not,
1009  // because it only updates a transparent cache value.
1010  if ((_flags & F_singular_known) == 0) {
1011  ((TransformState *)this)->calc_singular();
1012  }
1013 }
1014 
1015 ////////////////////////////////////////////////////////////////////
1016 // Function: TransformState::check_components
1017 // Access: Private
1018 // Description: Ensures that we know the components of the transform
1019 // (or that we know they cannot be derived).
1020 ////////////////////////////////////////////////////////////////////
1021 INLINE void TransformState::
1022 check_components() const {
1023  // This pretends to be a const function, even though it's not,
1024  // because it only updates a transparent cache value.
1025  if ((_flags & F_components_known) == 0) {
1026  ((TransformState *)this)->calc_components();
1027  }
1028 }
1029 
1030 ////////////////////////////////////////////////////////////////////
1031 // Function: TransformState::check_hpr
1032 // Access: Private
1033 // Description: Ensures that we know the hpr of the transform
1034 // (or that we know they cannot be derived).
1035 ////////////////////////////////////////////////////////////////////
1036 INLINE void TransformState::
1037 check_hpr() const {
1038  // This pretends to be a const function, even though it's not,
1039  // because it only updates a transparent cache value.
1040  if ((_flags & F_hpr_known) == 0) {
1041  ((TransformState *)this)->calc_hpr();
1042  }
1043 }
1044 
1045 ////////////////////////////////////////////////////////////////////
1046 // Function: TransformState::check_quat
1047 // Access: Private
1048 // Description: Ensures that we know the quat of the transform
1049 // (or that we know they cannot be derived).
1050 ////////////////////////////////////////////////////////////////////
1051 INLINE void TransformState::
1052 check_quat() const {
1053  // This pretends to be a const function, even though it's not,
1054  // because it only updates a transparent cache value.
1055  if ((_flags & F_quat_known) == 0) {
1056  ((TransformState *)this)->calc_quat();
1057  }
1058 }
1059 
1060 ////////////////////////////////////////////////////////////////////
1061 // Function: TransformState::check_norm_quat
1062 // Access: Private
1063 // Description: Ensures that we know the normalized quat of the transform
1064 // (or that we know they cannot be derived).
1065 ////////////////////////////////////////////////////////////////////
1066 INLINE void TransformState::
1067 check_norm_quat() const {
1068  // This pretends to be a const function, even though it's not,
1069  // because it only updates a transparent cache value.
1070  if ((_flags & F_norm_quat_known) == 0) {
1071  ((TransformState *)this)->calc_norm_quat();
1072  }
1073 }
1074 
1075 ////////////////////////////////////////////////////////////////////
1076 // Function: TransformState::check_mat
1077 // Access: Private
1078 // Description: Ensures that we know the overall matrix.
1079 ////////////////////////////////////////////////////////////////////
1080 INLINE void TransformState::
1081 check_mat() const {
1082  // This pretends to be a const function, even though it's not,
1083  // because it only updates a transparent cache value.
1084  if ((_flags & F_mat_known) == 0) {
1085  ((TransformState *)this)->calc_mat();
1086  }
1087 }
1088 
1089 ////////////////////////////////////////////////////////////////////
1090 // Function: TransformState::calc_hash
1091 // Access: Private
1092 // Description: Computes the hash value.
1093 ////////////////////////////////////////////////////////////////////
1094 INLINE void TransformState::
1095 calc_hash() {
1096  LightMutexHolder holder(_lock);
1097  do_calc_hash();
1098 }
1099 
1100 ////////////////////////////////////////////////////////////////////
1101 // Function: TransformState::calc_components
1102 // Access: Private
1103 // Description: Derives the components from the matrix, if possible.
1104 ////////////////////////////////////////////////////////////////////
1105 INLINE void TransformState::
1106 calc_components() {
1107  LightMutexHolder holder(_lock);
1108  do_calc_components();
1109 }
1110 
1111 ////////////////////////////////////////////////////////////////////
1112 // Function: TransformState::calc_hpr
1113 // Access: Private
1114 // Description: Derives the hpr, from the matrix if necessary, or
1115 // from the quat.
1116 ////////////////////////////////////////////////////////////////////
1117 INLINE void TransformState::
1118 calc_hpr() {
1119  LightMutexHolder holder(_lock);
1120  do_calc_hpr();
1121 }
1122 
1123 ////////////////////////////////////////////////////////////////////
1124 // Function: TransformState::calc_mat
1125 // Access: Private
1126 // Description: Computes the matrix from the components.
1127 ////////////////////////////////////////////////////////////////////
1128 INLINE void TransformState::
1129 calc_mat() {
1130  LightMutexHolder holder(_lock);
1131  do_calc_mat();
1132 }
1133 
1134 ////////////////////////////////////////////////////////////////////
1135 // Function: TransformState::check_uniform_scale
1136 // Access: Private
1137 // Description: Should be called immediately after _scale (and
1138 // F_has_components) is set, this checks for a
1139 // identity and/or uniform scale (as well as a non-zero
1140 // shear) and sets the bit appropriately.
1141 //
1142 // It does not matter whether the lock is or is not held
1143 // before calling this method.
1144 ////////////////////////////////////////////////////////////////////
1145 INLINE void TransformState::
1146 check_uniform_scale() {
1147  if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) &&
1148  IS_NEARLY_EQUAL(_scale[0], _scale[2])) {
1149  _flags |= F_uniform_scale;
1150  if (IS_NEARLY_EQUAL(_scale[0], 1.0f)) {
1151  _flags |= F_identity_scale;
1152  }
1153  }
1154 
1155  if (!_shear.almost_equal(LVecBase3::zero())) {
1156  _flags |= F_has_nonzero_shear;
1157  }
1158 }
1159 
1160 ////////////////////////////////////////////////////////////////////
1161 // Function: TransformState::check_uniform_scale2d
1162 // Access: Private
1163 // Description: Should be called immediately after _scale (and
1164 // F_has_components) is set, for a known 2-d scale, this
1165 // checks for a identity and/or uniform scale (as well
1166 // as a non-zero shear) and sets the bit appropriately.
1167 //
1168 // It does not matter whether the lock is or is not held
1169 // before calling this method.
1170 ////////////////////////////////////////////////////////////////////
1171 INLINE void TransformState::
1172 check_uniform_scale2d() {
1173  if (IS_NEARLY_EQUAL(_scale[0], _scale[1])) {
1174  _scale[2] = _scale[0];
1175  _flags |= F_uniform_scale;
1176  if (IS_NEARLY_EQUAL(_scale[0], 1.0f)) {
1177  _flags |= F_identity_scale;
1178  }
1179  }
1180 
1181  if (!_shear.almost_equal(LVecBase3::zero())) {
1182  _flags |= F_has_nonzero_shear;
1183  }
1184 }
1185 
1186 ////////////////////////////////////////////////////////////////////
1187 // Function: TransformState::set_destructing
1188 // Access: Private
1189 // Description: This function should only be called from the
1190 // destructor; it indicates that this TransformState
1191 // object is beginning destruction. It is only used as
1192 // a sanity check, and is only meaningful when NDEBUG is
1193 // not defined.
1194 ////////////////////////////////////////////////////////////////////
1195 INLINE void TransformState::
1196 set_destructing() {
1197 #ifndef NDEBUG
1198  _flags |= F_is_destructing;
1199 #endif
1200 }
1201 
1202 ////////////////////////////////////////////////////////////////////
1203 // Function: TransformState::is_destructing
1204 // Access: Private
1205 // Description: Returns true if the TransformState object is
1206 // currently within its destructor
1207 // (i.e. set_destructing() has been called). This is
1208 // only used as a sanity check, and is only meaningful
1209 // when NDEBUG is not defined.
1210 ////////////////////////////////////////////////////////////////////
1211 INLINE bool TransformState::
1212 is_destructing() const {
1213 #ifndef NDEBUG
1214  return (_flags & F_is_destructing) != 0;
1215 #else
1216  return false;
1217 #endif
1218 }
1219 
1220 ////////////////////////////////////////////////////////////////////
1221 // Function: TransformState::consider_update_pstats
1222 // Access: Private
1223 // Description: Calls update_pstats() if the state of the referenced
1224 // bits has changed from the indicated value.
1225 ////////////////////////////////////////////////////////////////////
1226 INLINE void TransformState::
1227 consider_update_pstats(int old_referenced_bits) const {
1228 #ifdef DO_PSTATS
1229  int new_referenced_bits = get_referenced_bits();
1230  if (old_referenced_bits != new_referenced_bits) {
1231  update_pstats(old_referenced_bits, new_referenced_bits);
1232  }
1233 #endif // DO_PSTATS
1234 }
1235 
1236 ////////////////////////////////////////////////////////////////////
1237 // Function: TransformState::Composition::Constructor
1238 // Access: Public
1239 // Description:
1240 ////////////////////////////////////////////////////////////////////
1241 INLINE TransformState::Composition::
1242 Composition() {
1243 }
1244 
1245 ////////////////////////////////////////////////////////////////////
1246 // Function: TransformState::Composition::Copy Constructor
1247 // Access: Public
1248 // Description:
1249 ////////////////////////////////////////////////////////////////////
1250 INLINE TransformState::Composition::
1251 Composition(const TransformState::Composition &copy) :
1252  _result(copy._result)
1253 {
1254 }
1255 
1256 ////////////////////////////////////////////////////////////////////
1257 // Function: TransformState::CompositionCycleDescEntry::Constructor
1258 // Access: Public
1259 // Description:
1260 ////////////////////////////////////////////////////////////////////
1261 INLINE TransformState::CompositionCycleDescEntry::
1262 CompositionCycleDescEntry(const TransformState *obj,
1263  const TransformState *result,
1264  bool inverted) :
1265  _obj(obj),
1266  _result(result),
1267  _inverted(inverted)
1268 {
1269 }
static const LMatrix4f & ident_mat()
Returns an identity matrix.
Definition: lmatrix.h:903
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
static const LMatrix3f & ident_mat()
Returns an identity matrix.
Definition: lmatrix.h:2863
void node_ref() const
Explicitly increments the reference count.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
static const LVecBase2f & zero()
Returns a zero-length vector.
Definition: lvecBase2.h:359
static const LVecBase3f & zero()
Returns a zero-length vector.
Definition: lvecBase3.h:382
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
Similar to MutexHolder, but for a light mutex.
void cache_ref() const
Explicitly increments the cache reference count and the normal reference count simultaneously.
This is the base class for all two-component vectors and points.
Definition: lvecBase2.h:105
Similar to MutexHolder, but for a light reentrant mutex.
An STL function object class, this is intended to be used on any ordered collection of class objects ...
Definition: stl_compares.h:79
This is the base quaternion class.
Definition: lquaternion.h:96
This is a 3-by-3 transform matrix.
Definition: lmatrix.h:110