transformState.I 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. // Filename: transformState.I
  2. // Created by: drose (25Feb02)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. ////////////////////////////////////////////////////////////////////
  19. // Function: TransformState::make_pos
  20. // Access: Published, Static
  21. // Description: Makes a new TransformState with the specified
  22. // components.
  23. ////////////////////////////////////////////////////////////////////
  24. INLINE CPT(TransformState) TransformState::
  25. make_pos(const LVecBase3f &pos) {
  26. return make_pos_hpr_scale(pos,
  27. LVecBase3f(0.0f, 0.0f, 0.0f),
  28. LVecBase3f(1.0f, 1.0f, 1.0f));
  29. }
  30. ////////////////////////////////////////////////////////////////////
  31. // Function: TransformState::make_hpr
  32. // Access: Published, Static
  33. // Description: Makes a new TransformState with the specified
  34. // components.
  35. ////////////////////////////////////////////////////////////////////
  36. INLINE CPT(TransformState) TransformState::
  37. make_hpr(const LVecBase3f &hpr) {
  38. return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
  39. hpr,
  40. LVecBase3f(1.0f, 1.0f, 1.0f));
  41. }
  42. ////////////////////////////////////////////////////////////////////
  43. // Function: TransformState::make_quat
  44. // Access: Published, Static
  45. // Description: Makes a new TransformState with the specified
  46. // components.
  47. ////////////////////////////////////////////////////////////////////
  48. INLINE CPT(TransformState) TransformState::
  49. make_quat(const LQuaternionf &quat) {
  50. return make_pos_quat_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
  51. quat,
  52. LVecBase3f(1.0f, 1.0f, 1.0f));
  53. }
  54. ////////////////////////////////////////////////////////////////////
  55. // Function: TransformState::make_pos_hpr
  56. // Access: Published, Static
  57. // Description: Makes a new TransformState with the specified
  58. // components.
  59. ////////////////////////////////////////////////////////////////////
  60. INLINE CPT(TransformState) TransformState::
  61. make_pos_hpr(const LVecBase3f &pos, const LVecBase3f &hpr) {
  62. return make_pos_hpr_scale(pos, hpr,
  63. LVecBase3f(1.0, 1.0f, 1.0f));
  64. }
  65. ////////////////////////////////////////////////////////////////////
  66. // Function: TransformState::make_scale
  67. // Access: Published, Static
  68. // Description: Makes a new TransformState with the specified
  69. // components.
  70. ////////////////////////////////////////////////////////////////////
  71. INLINE CPT(TransformState) TransformState::
  72. make_scale(float scale) {
  73. return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
  74. LVecBase3f(0.0f, 0.0f, 0.0f),
  75. LVecBase3f(scale, scale, scale));
  76. }
  77. ////////////////////////////////////////////////////////////////////
  78. // Function: TransformState::make_scale
  79. // Access: Published, Static
  80. // Description: Makes a new TransformState with the specified
  81. // components.
  82. ////////////////////////////////////////////////////////////////////
  83. INLINE CPT(TransformState) TransformState::
  84. make_scale(const LVecBase3f &scale) {
  85. return make_pos_hpr_scale(LVecBase3f(0.0f, 0.0f, 0.0f),
  86. LVecBase3f(0.0f, 0.0f, 0.0f),
  87. scale);
  88. }
  89. ////////////////////////////////////////////////////////////////////
  90. // Function: TransformState::make_shear
  91. // Access: Published, Static
  92. // Description: Makes a new TransformState with the specified
  93. // components.
  94. ////////////////////////////////////////////////////////////////////
  95. INLINE CPT(TransformState) TransformState::
  96. make_shear(const LVecBase3f &shear) {
  97. return make_pos_hpr_scale_shear(LVecBase3f(0.0f, 0.0f, 0.0f),
  98. LVecBase3f(0.0f, 0.0f, 0.0f),
  99. LVecBase3f(1.0f, 1.0f, 1.0f),
  100. shear);
  101. }
  102. ////////////////////////////////////////////////////////////////////
  103. // Function: TransformState::make_pos_hpr_scale
  104. // Access: Published, Static
  105. // Description: Makes a new TransformState with the specified
  106. // components.
  107. ////////////////////////////////////////////////////////////////////
  108. INLINE CPT(TransformState) TransformState::
  109. make_pos_hpr_scale(const LVecBase3f &pos, const LVecBase3f &hpr,
  110. const LVecBase3f &scale) {
  111. return make_pos_hpr_scale_shear(pos, hpr, scale, LVecBase3f::zero());
  112. }
  113. ////////////////////////////////////////////////////////////////////
  114. // Function: TransformState::make_pos_quat_scale
  115. // Access: Published, Static
  116. // Description: Makes a new TransformState with the specified
  117. // components.
  118. ////////////////////////////////////////////////////////////////////
  119. INLINE CPT(TransformState) TransformState::
  120. make_pos_quat_scale(const LVecBase3f &pos, const LQuaternionf &quat,
  121. const LVecBase3f &scale) {
  122. return make_pos_quat_scale_shear(pos, quat, scale, LVecBase3f::zero());
  123. }
  124. ////////////////////////////////////////////////////////////////////
  125. // Function: TransformState::is_identity
  126. // Access: Published
  127. // Description: Returns true if the transform represents the identity
  128. // matrix, false otherwise.
  129. ////////////////////////////////////////////////////////////////////
  130. INLINE bool TransformState::
  131. is_identity() const {
  132. return ((_flags & F_is_identity) != 0);
  133. }
  134. ////////////////////////////////////////////////////////////////////
  135. // Function: TransformState::is_invalid
  136. // Access: Published
  137. // Description: Returns true if the transform represents an invalid
  138. // matrix, for instance the result of inverting a
  139. // singular matrix, or false if the transform is valid.
  140. ////////////////////////////////////////////////////////////////////
  141. INLINE bool TransformState::
  142. is_invalid() const {
  143. return ((_flags & F_is_invalid) != 0);
  144. }
  145. ////////////////////////////////////////////////////////////////////
  146. // Function: TransformState::is_singular
  147. // Access: Published
  148. // Description: Returns true if the transform represents a singular
  149. // transform (that is, it has a zero scale, and it
  150. // cannot be inverted), or false otherwise.
  151. ////////////////////////////////////////////////////////////////////
  152. INLINE bool TransformState::
  153. is_singular() const {
  154. check_singular();
  155. return ((_flags & F_is_singular) != 0);
  156. }
  157. ////////////////////////////////////////////////////////////////////
  158. // Function: TransformState::has_components
  159. // Access: Published
  160. // Description: Returns true if the transform can be described by
  161. // separate pos, hpr, and scale components. Most
  162. // transforms we use in everyday life can be so
  163. // described, but some kinds of transforms (for
  164. // instance, those involving a skew) cannot.
  165. //
  166. // This is not related to whether the transform was
  167. // originally described componentwise. Even a transform
  168. // that was constructed with a 4x4 may return true here
  169. // if the matrix is a simple affine matrix with no skew.
  170. //
  171. // If this returns true, you may safely call get_hpr()
  172. // and get_scale() to retrieve the components. (You
  173. // may always safely call get_pos() whether this returns
  174. // true or false.)
  175. ////////////////////////////////////////////////////////////////////
  176. INLINE bool TransformState::
  177. has_components() const {
  178. check_components();
  179. return ((_flags & F_has_components) != 0);
  180. }
  181. ////////////////////////////////////////////////////////////////////
  182. // Function: TransformState::components_given
  183. // Access: Published
  184. // Description: Returns true if the transform was specified
  185. // componentwise, or false if it was specified with a
  186. // general 4x4 matrix. If this is true, the components
  187. // returned by get_pos() and get_scale() will be exactly
  188. // those that were set; otherwise, these functions will
  189. // return computed values. If this is true, the
  190. // rotation may have been set either with a hpr trio or
  191. // with a quaternion; hpr_given() or quat_given() can
  192. // resolve the difference.
  193. ////////////////////////////////////////////////////////////////////
  194. INLINE bool TransformState::
  195. components_given() const {
  196. return ((_flags & F_components_given) != 0);
  197. }
  198. ////////////////////////////////////////////////////////////////////
  199. // Function: TransformState::hpr_given
  200. // Access: Published
  201. // Description: Returns true if the rotation was specified via a trio
  202. // of Euler angles, false otherwise. If this is true,
  203. // get_hpr() will be exactly as set; otherwise, it will
  204. // return a computed value.
  205. ////////////////////////////////////////////////////////////////////
  206. INLINE bool TransformState::
  207. hpr_given() const {
  208. return ((_flags & F_hpr_given) != 0);
  209. }
  210. ////////////////////////////////////////////////////////////////////
  211. // Function: TransformState::quat_given
  212. // Access: Published
  213. // Description: Returns true if the rotation was specified via a
  214. // quaternion, false otherwise. If this is true,
  215. // get_quat() will be exactly as set; otherwise, it will
  216. // return a computed value.
  217. ////////////////////////////////////////////////////////////////////
  218. INLINE bool TransformState::
  219. quat_given() const {
  220. return ((_flags & F_quat_given) != 0);
  221. }
  222. ////////////////////////////////////////////////////////////////////
  223. // Function: TransformState::has_pos
  224. // Access: Published
  225. // Description: Returns true if the transform's pos component can be
  226. // extracted out separately. This is generally always
  227. // true, unless the transform is invalid
  228. // (i.e. is_invalid() returns true).
  229. ////////////////////////////////////////////////////////////////////
  230. INLINE bool TransformState::
  231. has_pos() const {
  232. return !is_invalid();
  233. }
  234. ////////////////////////////////////////////////////////////////////
  235. // Function: TransformState::has_hpr
  236. // Access: Published
  237. // Description: Returns true if the transform's rotation component
  238. // can be extracted out separately and described as a
  239. // set of Euler angles. This is generally true only
  240. // when has_components() is true.
  241. ////////////////////////////////////////////////////////////////////
  242. INLINE bool TransformState::
  243. has_hpr() const {
  244. return has_components();
  245. }
  246. ////////////////////////////////////////////////////////////////////
  247. // Function: TransformState::has_quat
  248. // Access: Published
  249. // Description: Returns true if the transform's rotation component
  250. // can be extracted out separately and described as a
  251. // quaternion. This is generally true only when
  252. // has_components() is true.
  253. ////////////////////////////////////////////////////////////////////
  254. INLINE bool TransformState::
  255. has_quat() const {
  256. return has_components();
  257. }
  258. ////////////////////////////////////////////////////////////////////
  259. // Function: TransformState::has_scale
  260. // Access: Published
  261. // Description: Returns true if the transform's scale component
  262. // can be extracted out separately. This is generally
  263. // true only when has_components() is true.
  264. ////////////////////////////////////////////////////////////////////
  265. INLINE bool TransformState::
  266. has_scale() const {
  267. return has_components();
  268. }
  269. ////////////////////////////////////////////////////////////////////
  270. // Function: TransformState::has_uniform_scale
  271. // Access: Published
  272. // Description: Returns true if the scale is uniform across all three
  273. // axes (and therefore can be expressed as a single
  274. // number), or false if the transform has a different
  275. // scale in different dimensions.
  276. ////////////////////////////////////////////////////////////////////
  277. INLINE bool TransformState::
  278. has_uniform_scale() const {
  279. check_components();
  280. return (_flags & F_uniform_scale) != 0;
  281. }
  282. ////////////////////////////////////////////////////////////////////
  283. // Function: TransformState::has_shear
  284. // Access: Published
  285. // Description: Returns true if the transform's shear component
  286. // can be extracted out separately. This is generally
  287. // true only when has_components() is true.
  288. ////////////////////////////////////////////////////////////////////
  289. INLINE bool TransformState::
  290. has_shear() const {
  291. return has_components();
  292. }
  293. ////////////////////////////////////////////////////////////////////
  294. // Function: TransformState::has_nonzero_shear
  295. // Access: Published
  296. // Description: Returns true if the shear component is non-zero,
  297. // false if it is zero or if the matrix cannot be
  298. // decomposed.
  299. ////////////////////////////////////////////////////////////////////
  300. INLINE bool TransformState::
  301. has_nonzero_shear() const {
  302. check_components();
  303. return (_flags & F_has_nonzero_shear) != 0;
  304. }
  305. ////////////////////////////////////////////////////////////////////
  306. // Function: TransformState::has_mat
  307. // Access: Published
  308. // Description: Returns true if the transform can be described as a
  309. // matrix. This is generally always true, unless
  310. // is_invalid() is true.
  311. ////////////////////////////////////////////////////////////////////
  312. INLINE bool TransformState::
  313. has_mat() const {
  314. return !is_invalid();
  315. }
  316. ////////////////////////////////////////////////////////////////////
  317. // Function: TransformState::get_pos
  318. // Access: Published
  319. // Description: Returns the pos component of the transform. It is an
  320. // error to call this if has_pos() returned false.
  321. ////////////////////////////////////////////////////////////////////
  322. INLINE const LVecBase3f &TransformState::
  323. get_pos() const {
  324. check_components();
  325. nassertr(has_pos(), _pos);
  326. return _pos;
  327. }
  328. ////////////////////////////////////////////////////////////////////
  329. // Function: TransformState::get_hpr
  330. // Access: Published
  331. // Description: Returns the rotation component of the transform as a
  332. // trio of Euler angles. It is an error to call this if
  333. // has_components() returned false.
  334. ////////////////////////////////////////////////////////////////////
  335. INLINE const LVecBase3f &TransformState::
  336. get_hpr() const {
  337. check_hpr();
  338. nassertr(!is_invalid(), _hpr);
  339. // nassertr(has_hpr(), _hpr);
  340. return _hpr;
  341. }
  342. ////////////////////////////////////////////////////////////////////
  343. // Function: TransformState::get_quat
  344. // Access: Published
  345. // Description: Returns the rotation component of the transform as a
  346. // quaternion. It is an error to call this if
  347. // has_components() returned false.
  348. ////////////////////////////////////////////////////////////////////
  349. INLINE const LQuaternionf &TransformState::
  350. get_quat() const {
  351. check_quat();
  352. nassertr(!is_invalid(), _quat);
  353. // nassertr(has_quat(), _quat);
  354. return _quat;
  355. }
  356. ////////////////////////////////////////////////////////////////////
  357. // Function: TransformState::get_scale
  358. // Access: Published
  359. // Description: Returns the scale component of the transform. It is an
  360. // error to call this if has_components() returned
  361. // false.
  362. ////////////////////////////////////////////////////////////////////
  363. INLINE const LVecBase3f &TransformState::
  364. get_scale() const {
  365. check_components();
  366. nassertr(!is_invalid(), _scale);
  367. // nassertr(has_scale(), _scale);
  368. return _scale;
  369. }
  370. ////////////////////////////////////////////////////////////////////
  371. // Function: TransformState::get_uniform_scale
  372. // Access: Published
  373. // Description: Returns the scale component of the transform, as a
  374. // single number. It is an error to call this if
  375. // has_uniform_scale() returned false.
  376. ////////////////////////////////////////////////////////////////////
  377. INLINE float TransformState::
  378. get_uniform_scale() const {
  379. check_components();
  380. nassertr(has_uniform_scale(), _scale[0]);
  381. return _scale[0];
  382. }
  383. ////////////////////////////////////////////////////////////////////
  384. // Function: TransformState::get_shear
  385. // Access: Published
  386. // Description: Returns the shear component of the transform. It is
  387. // an error to call this if has_components() returned
  388. // false.
  389. ////////////////////////////////////////////////////////////////////
  390. INLINE const LVecBase3f &TransformState::
  391. get_shear() const {
  392. check_components();
  393. nassertr(!is_invalid(), _shear);
  394. return _shear;
  395. }
  396. ////////////////////////////////////////////////////////////////////
  397. // Function: TransformState::get_mat
  398. // Access: Published
  399. // Description: Returns the matrix that describes the transform.
  400. ////////////////////////////////////////////////////////////////////
  401. INLINE const LMatrix4f &TransformState::
  402. get_mat() const {
  403. nassertr(has_mat(), LMatrix4f::ident_mat());
  404. check_mat();
  405. return _mat;
  406. }
  407. ////////////////////////////////////////////////////////////////////
  408. // Function: TransformState::check_singular
  409. // Access: Private
  410. // Description: Ensures that we know whether the matrix is singular.
  411. ////////////////////////////////////////////////////////////////////
  412. INLINE void TransformState::
  413. check_singular() const {
  414. // This pretends to be a const function, even though it's not,
  415. // because it only updates a transparent cache value.
  416. if ((_flags & F_singular_known) == 0) {
  417. ((TransformState *)this)->calc_singular();
  418. }
  419. }
  420. ////////////////////////////////////////////////////////////////////
  421. // Function: TransformState::check_components
  422. // Access: Private
  423. // Description: Ensures that we know the components of the transform
  424. // (or that we know they cannot be derived).
  425. ////////////////////////////////////////////////////////////////////
  426. INLINE void TransformState::
  427. check_components() const {
  428. // This pretends to be a const function, even though it's not,
  429. // because it only updates a transparent cache value.
  430. if ((_flags & F_components_known) == 0) {
  431. ((TransformState *)this)->calc_components();
  432. }
  433. }
  434. ////////////////////////////////////////////////////////////////////
  435. // Function: TransformState::check_hpr
  436. // Access: Private
  437. // Description: Ensures that we know the hpr of the transform
  438. // (or that we know they cannot be derived).
  439. ////////////////////////////////////////////////////////////////////
  440. INLINE void TransformState::
  441. check_hpr() const {
  442. // This pretends to be a const function, even though it's not,
  443. // because it only updates a transparent cache value.
  444. if ((_flags & F_hpr_known) == 0) {
  445. ((TransformState *)this)->calc_hpr();
  446. }
  447. }
  448. ////////////////////////////////////////////////////////////////////
  449. // Function: TransformState::check_quat
  450. // Access: Private
  451. // Description: Ensures that we know the quat of the transform
  452. // (or that we know they cannot be derived).
  453. ////////////////////////////////////////////////////////////////////
  454. INLINE void TransformState::
  455. check_quat() const {
  456. // This pretends to be a const function, even though it's not,
  457. // because it only updates a transparent cache value.
  458. if ((_flags & F_quat_known) == 0) {
  459. ((TransformState *)this)->calc_quat();
  460. }
  461. }
  462. ////////////////////////////////////////////////////////////////////
  463. // Function: TransformState::check_mat
  464. // Access: Private
  465. // Description: Ensures that we know the overall matrix.
  466. ////////////////////////////////////////////////////////////////////
  467. INLINE void TransformState::
  468. check_mat() const {
  469. // This pretends to be a const function, even though it's not,
  470. // because it only updates a transparent cache value.
  471. if ((_flags & F_mat_known) == 0) {
  472. ((TransformState *)this)->calc_mat();
  473. }
  474. }
  475. ////////////////////////////////////////////////////////////////////
  476. // Function: TransformState::check_uniform_scale
  477. // Access: Private
  478. // Description: Should be called immediately after _scale (and
  479. // F_has_components) is set, this checks for a uniform
  480. // scale (as well as a non-zero shear) and sets the bit
  481. // appropriately.
  482. ////////////////////////////////////////////////////////////////////
  483. INLINE void TransformState::
  484. check_uniform_scale() {
  485. if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) &&
  486. IS_NEARLY_EQUAL(_scale[0], _scale[2])) {
  487. _flags |= F_uniform_scale;
  488. }
  489. if (!_shear.almost_equal(LVecBase3f::zero())) {
  490. _flags |= F_has_nonzero_shear;
  491. }
  492. }
  493. ////////////////////////////////////////////////////////////////////
  494. // Function: TransformState::set_destructing
  495. // Access: Private
  496. // Description: This function should only be called from the
  497. // destructor; it indicates that this TransformState
  498. // object is beginning destruction. It is only used as
  499. // a sanity check, and is only meaningful when NDEBUG is
  500. // not defined.
  501. ////////////////////////////////////////////////////////////////////
  502. INLINE void TransformState::
  503. set_destructing() {
  504. #ifndef NDEBUG
  505. _flags |= F_is_destructing;
  506. #endif
  507. }
  508. ////////////////////////////////////////////////////////////////////
  509. // Function: TransformState::is_destructing
  510. // Access: Private
  511. // Description: Returns true if the TransformState object is
  512. // currently within its destructor
  513. // (i.e. set_destructing() has been called). This is
  514. // only used as a sanity check, and is only meaningful
  515. // when NDEBUG is not defined.
  516. ////////////////////////////////////////////////////////////////////
  517. INLINE bool TransformState::
  518. is_destructing() const {
  519. #ifndef NDEBUG
  520. return (_flags & F_is_destructing) != 0;
  521. #else
  522. return false;
  523. #endif
  524. }
  525. ////////////////////////////////////////////////////////////////////
  526. // Function: TransformState::Composition::Constructor
  527. // Access: Public
  528. // Description:
  529. ////////////////////////////////////////////////////////////////////
  530. INLINE TransformState::Composition::
  531. Composition() {
  532. }
  533. ////////////////////////////////////////////////////////////////////
  534. // Function: TransformState::Composition::Copy Constructor
  535. // Access: Public
  536. // Description:
  537. ////////////////////////////////////////////////////////////////////
  538. INLINE TransformState::Composition::
  539. Composition(const TransformState::Composition &copy) :
  540. _result(copy._result)
  541. {
  542. }
  543. ////////////////////////////////////////////////////////////////////
  544. // Function: TransformState::CompositionCycleDescEntry::Constructor
  545. // Access: Public
  546. // Description:
  547. ////////////////////////////////////////////////////////////////////
  548. INLINE TransformState::CompositionCycleDescEntry::
  549. CompositionCycleDescEntry(const TransformState *obj,
  550. const TransformState *result,
  551. bool inverted) :
  552. _obj(obj),
  553. _result(result),
  554. _inverted(inverted)
  555. {
  556. }