transformState.I 23 KB

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