Transform.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. #include "Base.h"
  2. #include "Transform.h"
  3. #include "Game.h"
  4. namespace gameplay
  5. {
  6. Transform::Transform()
  7. : _matrixDirty(false), _listeners(NULL)
  8. {
  9. _targetType = AnimationTarget::TRANSFORM;
  10. _scale.set(Vector3::one());
  11. }
  12. Transform::Transform(const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
  13. : _matrixDirty(false), _listeners(NULL)
  14. {
  15. _targetType = AnimationTarget::TRANSFORM;
  16. set(scale, rotation, translation);
  17. }
  18. Transform::Transform(const Vector3& scale, const Matrix& rotation, const Vector3& translation)
  19. : _matrixDirty(false), _listeners(NULL)
  20. {
  21. _targetType = AnimationTarget::TRANSFORM;
  22. set(scale, rotation, translation);
  23. }
  24. Transform::Transform(const Transform& copy)
  25. : _matrixDirty(false), _listeners(NULL)
  26. {
  27. _targetType = AnimationTarget::TRANSFORM;
  28. set(copy);
  29. }
  30. Transform::~Transform()
  31. {
  32. SAFE_DELETE(_listeners);
  33. }
  34. const Matrix& Transform::getMatrix() const
  35. {
  36. if (_matrixDirty)
  37. {
  38. _matrixDirty = false;
  39. bool hasTranslation = !_translation.isZero();
  40. bool hasScale = !_scale.isOne();
  41. bool hasRotation = !_rotation.isIdentity();
  42. // Compose the matrix in TRS order since we use column-major matrices with column vectors and
  43. // multiply M*v (as opposed to XNA and DirectX that use row-major matrices with row vectors and multiply v*M).
  44. if (hasTranslation)
  45. {
  46. Matrix::createTranslation(_translation, &_matrix);
  47. if (hasRotation)
  48. {
  49. _matrix.rotate(_rotation);
  50. }
  51. if (hasScale)
  52. {
  53. _matrix.scale(_scale);
  54. }
  55. }
  56. else if (hasRotation)
  57. {
  58. Matrix::createRotation(_rotation, &_matrix);
  59. if (hasScale)
  60. {
  61. _matrix.scale(_scale);
  62. }
  63. }
  64. else if (hasScale)
  65. {
  66. Matrix::createScale(_scale, &_matrix);
  67. }
  68. }
  69. return _matrix;
  70. }
  71. const Vector3& Transform::getScale() const
  72. {
  73. return _scale;
  74. }
  75. void Transform::getScale(Vector3* scale) const
  76. {
  77. scale->set(_scale);
  78. }
  79. float Transform::getScaleX() const
  80. {
  81. return _scale.x;
  82. }
  83. float Transform::getScaleY() const
  84. {
  85. return _scale.y;
  86. }
  87. float Transform::getScaleZ() const
  88. {
  89. return _scale.z;
  90. }
  91. const Quaternion& Transform::getRotation() const
  92. {
  93. return _rotation;
  94. }
  95. void Transform::getRotation(Quaternion* rotation) const
  96. {
  97. assert(rotation);
  98. rotation->set(_rotation);
  99. }
  100. void Transform::getRotation(Matrix* rotation) const
  101. {
  102. assert(rotation);
  103. Matrix::createRotation(_rotation, rotation);
  104. }
  105. float Transform::getRotation(Vector3* axis) const
  106. {
  107. assert(axis);
  108. return _rotation.toAxisAngle(axis);
  109. }
  110. const Vector3& Transform::getTranslation() const
  111. {
  112. return _translation;
  113. }
  114. void Transform::getTranslation(Vector3* translation) const
  115. {
  116. translation->set(_translation);
  117. }
  118. float Transform::getTranslationX() const
  119. {
  120. return _translation.x;
  121. }
  122. float Transform::getTranslationY() const
  123. {
  124. return _translation.y;
  125. }
  126. float Transform::getTranslationZ() const
  127. {
  128. return _translation.z;
  129. }
  130. Vector3 Transform::getForwardVector() const
  131. {
  132. Vector3 v;
  133. getForwardVector(&v);
  134. return v;
  135. }
  136. void Transform::getForwardVector(Vector3* dst) const
  137. {
  138. getMatrix().getForwardVector(dst);
  139. }
  140. Vector3 Transform::getBackVector() const
  141. {
  142. Vector3 v;
  143. getBackVector(&v);
  144. return v;
  145. }
  146. void Transform::getBackVector(Vector3* dst) const
  147. {
  148. getMatrix().getBackVector(dst);
  149. }
  150. Vector3 Transform::getUpVector() const
  151. {
  152. Vector3 v;
  153. getUpVector(&v);
  154. return v;
  155. }
  156. void Transform::getUpVector(Vector3* dst) const
  157. {
  158. getMatrix().getUpVector(dst);
  159. }
  160. Vector3 Transform::getDownVector() const
  161. {
  162. Vector3 v;
  163. getDownVector(&v);
  164. return v;
  165. }
  166. void Transform::getDownVector(Vector3* dst) const
  167. {
  168. getMatrix().getDownVector(dst);
  169. }
  170. Vector3 Transform::getLeftVector() const
  171. {
  172. Vector3 v;
  173. getLeftVector(&v);
  174. return v;
  175. }
  176. void Transform::getLeftVector(Vector3* dst) const
  177. {
  178. getMatrix().getLeftVector(dst);
  179. }
  180. Vector3 Transform::getRightVector() const
  181. {
  182. Vector3 v;
  183. getRightVector(&v);
  184. return v;
  185. }
  186. void Transform::getRightVector(Vector3* dst) const
  187. {
  188. getMatrix().getRightVector(dst);
  189. }
  190. void Transform::rotate(const Quaternion& rotation)
  191. {
  192. _rotation.multiply(rotation);
  193. dirty();
  194. }
  195. void Transform::rotate(const Vector3& axis, float angle)
  196. {
  197. Quaternion rotationQuat;
  198. Quaternion::createFromAxisAngle(axis, angle, &rotationQuat);
  199. _rotation.multiply(rotationQuat);
  200. _rotation.normalize();
  201. dirty();
  202. }
  203. void Transform::rotate(const Matrix& rotation)
  204. {
  205. Quaternion rotationQuat;
  206. Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
  207. _rotation.multiply(rotationQuat);
  208. dirty();
  209. }
  210. void Transform::rotateX(float angle)
  211. {
  212. Quaternion rotationQuat;
  213. Quaternion::createFromAxisAngle(Vector3::unitX(), angle, &rotationQuat);
  214. _rotation.multiply(rotationQuat);
  215. dirty();
  216. }
  217. void Transform::rotateY(float angle)
  218. {
  219. Quaternion rotationQuat;
  220. Quaternion::createFromAxisAngle(Vector3::unitY(), angle, &rotationQuat);
  221. _rotation.multiply(rotationQuat);
  222. dirty();
  223. }
  224. void Transform::rotateZ(float angle)
  225. {
  226. Quaternion rotationQuat;
  227. Quaternion::createFromAxisAngle(Vector3::unitZ(), angle, &rotationQuat);
  228. _rotation.multiply(rotationQuat);
  229. dirty();
  230. }
  231. void Transform::scale(float scale)
  232. {
  233. _scale.scale(scale);
  234. dirty();
  235. }
  236. void Transform::scale(float sx, float sy, float sz)
  237. {
  238. _scale.x *= sx;
  239. _scale.y *= sy;
  240. _scale.z *= sz;
  241. dirty();
  242. }
  243. void Transform::scale(const Vector3& scale)
  244. {
  245. _scale.x *= scale.x;
  246. _scale.y *= scale.y;
  247. _scale.z *= scale.z;
  248. dirty();
  249. }
  250. void Transform::scaleX(float sx)
  251. {
  252. _scale.x *= sx;
  253. dirty();
  254. }
  255. void Transform::scaleY(float sy)
  256. {
  257. _scale.y *= sy;
  258. dirty();
  259. }
  260. void Transform::scaleZ(float sz)
  261. {
  262. _scale.z *= sz;
  263. dirty();
  264. }
  265. void Transform::set(const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
  266. {
  267. _scale.set(scale);
  268. _rotation.set(rotation);
  269. _translation.set(translation);
  270. dirty();
  271. }
  272. void Transform::set(const Vector3& scale, const Matrix& rotation, const Vector3& translation)
  273. {
  274. _scale.set(scale);
  275. Quaternion rotationQuat;
  276. Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
  277. _rotation.set(rotationQuat);
  278. _translation.set(translation);
  279. dirty();
  280. }
  281. void Transform::set(const Vector3& scale, const Vector3& axis, float angle, const Vector3& translation)
  282. {
  283. _scale.set(scale);
  284. _rotation.set(axis, angle);
  285. _translation.set(translation);
  286. }
  287. void Transform::set(const Transform& transform)
  288. {
  289. _scale.set(transform._scale);
  290. _rotation.set(transform._rotation);
  291. _translation.set(transform._translation);
  292. dirty();
  293. }
  294. void Transform::setScale(float scale)
  295. {
  296. _scale.set(scale, scale, scale);
  297. dirty();
  298. }
  299. void Transform::setScale(float sx, float sy, float sz)
  300. {
  301. _scale.set(sx, sy, sz);
  302. dirty();
  303. }
  304. void Transform::setScale(const Vector3& scale)
  305. {
  306. _scale.set(scale);
  307. dirty();
  308. }
  309. void Transform::setScaleX(float sx)
  310. {
  311. _scale.x = sx;
  312. dirty();
  313. }
  314. void Transform::setScaleY(float sy)
  315. {
  316. _scale.y = sy;
  317. dirty();
  318. }
  319. void Transform::setScaleZ(float sz)
  320. {
  321. _scale.z = sz;
  322. dirty();
  323. }
  324. void Transform::setRotation(const Quaternion& rotation)
  325. {
  326. _rotation.set(rotation);
  327. dirty();
  328. }
  329. void Transform::setRotation(float qx, float qy, float qz, float qw)
  330. {
  331. _rotation.set(qx, qy, qz, qw);
  332. dirty();
  333. }
  334. void Transform::setRotation(const Matrix& rotation)
  335. {
  336. Quaternion rotationQuat;
  337. Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
  338. _rotation.set(rotationQuat);
  339. dirty();
  340. }
  341. void Transform::setRotation(const Vector3& axis, float angle)
  342. {
  343. _rotation.set(axis, angle);
  344. dirty();
  345. }
  346. void Transform::setTranslation(const Vector3& translation)
  347. {
  348. _translation.set(translation);
  349. dirty();
  350. }
  351. void Transform::setTranslation(float tx, float ty, float tz)
  352. {
  353. _translation.set(tx, ty, tz);
  354. dirty();
  355. }
  356. void Transform::setTranslationX(float tx)
  357. {
  358. _translation.x = tx;
  359. dirty();
  360. }
  361. void Transform::setTranslationY(float ty)
  362. {
  363. _translation.y = ty;
  364. dirty();
  365. }
  366. void Transform::setTranslationZ(float tz)
  367. {
  368. _translation.z = tz;
  369. dirty();
  370. }
  371. void Transform::translate(float tx, float ty, float tz)
  372. {
  373. _translation.x += tx;
  374. _translation.y += ty;
  375. _translation.z += tz;
  376. dirty();
  377. }
  378. void Transform::translate(const Vector3& translation)
  379. {
  380. _translation.x += translation.x;
  381. _translation.y += translation.y;
  382. _translation.z += translation.z;
  383. dirty();
  384. }
  385. void Transform::translateX(float tx)
  386. {
  387. _translation.x += tx;
  388. dirty();
  389. }
  390. void Transform::translateY(float ty)
  391. {
  392. _translation.y += ty;
  393. dirty();
  394. }
  395. void Transform::translateZ(float tz)
  396. {
  397. _translation.z += tz;
  398. dirty();
  399. }
  400. void Transform::translateLeft(float amount)
  401. {
  402. // Force the current transform matrix to be updated.
  403. getMatrix();
  404. Vector3 left;
  405. _matrix.getLeftVector(&left);
  406. left.normalize();
  407. left.scale(amount);
  408. translate(left);
  409. }
  410. void Transform::translateUp(float amount)
  411. {
  412. // Force the current transform matrix to be updated.
  413. getMatrix();
  414. Vector3 up;
  415. _matrix.getUpVector(&up);
  416. up.normalize();
  417. up.scale(amount);
  418. translate(up);
  419. }
  420. void Transform::translateForward(float amount)
  421. {
  422. // Force the current transform matrix to be updated.
  423. getMatrix();
  424. Vector3 forward;
  425. _matrix.getForwardVector(&forward);
  426. forward.normalize();
  427. forward.scale(amount);
  428. translate(forward);
  429. }
  430. void Transform::transformPoint(Vector3* point)
  431. {
  432. assert(point);
  433. getMatrix();
  434. _matrix.transformPoint(point);
  435. }
  436. void Transform::transformPoint(const Vector3& point, Vector3* dst)
  437. {
  438. assert(dst);
  439. getMatrix();
  440. _matrix.transformPoint(point, dst);
  441. }
  442. void Transform::transformVector(Vector3* normal)
  443. {
  444. assert(normal);
  445. getMatrix();
  446. _matrix.transformVector(normal);
  447. }
  448. void Transform::transformVector(const Vector3& normal, Vector3* dst)
  449. {
  450. getMatrix();
  451. _matrix.transformVector(normal, dst);
  452. }
  453. void Transform::transformVector(float x, float y, float z, float w, Vector3* dst)
  454. {
  455. getMatrix();
  456. _matrix.transformVector(x, y, z, w, dst);
  457. }
  458. unsigned int Transform::getAnimationPropertyComponentCount(int propertyId) const
  459. {
  460. switch (propertyId)
  461. {
  462. case ANIMATE_SCALE_X:
  463. case ANIMATE_SCALE_Y:
  464. case ANIMATE_SCALE_Z:
  465. case ANIMATE_TRANSLATE_X:
  466. case ANIMATE_TRANSLATE_Y:
  467. case ANIMATE_TRANSLATE_Z:
  468. return 1;
  469. case ANIMATE_SCALE:
  470. case ANIMATE_TRANSLATE:
  471. return 3;
  472. case ANIMATE_ROTATE:
  473. return 4;
  474. case ANIMATE_ROTATE_TRANSLATE:
  475. return 7;
  476. case ANIMATE_SCALE_ROTATE_TRANSLATE:
  477. return 10;
  478. default:
  479. return -1;
  480. }
  481. }
  482. void Transform::getAnimationPropertyValue(int propertyId, AnimationValue* value)
  483. {
  484. switch (propertyId)
  485. {
  486. case ANIMATE_SCALE:
  487. value->setFloat(0, _scale.x);
  488. value->setFloat(1, _scale.y);
  489. value->setFloat(2, _scale.z);
  490. break;
  491. case ANIMATE_SCALE_X:
  492. value->setFloat(0, _scale.x);
  493. break;
  494. case ANIMATE_SCALE_Y:
  495. value->setFloat(0, _scale.y);
  496. break;
  497. case ANIMATE_SCALE_Z:
  498. value->setFloat(0, _scale.z);
  499. break;
  500. case ANIMATE_ROTATE:
  501. value->setFloat(0, _rotation.x);
  502. value->setFloat(1, _rotation.y);
  503. value->setFloat(2, _rotation.z);
  504. value->setFloat(3, _rotation.w);
  505. break;
  506. case ANIMATE_TRANSLATE:
  507. value->setFloat(0, _translation.x);
  508. value->setFloat(1, _translation.y);
  509. value->setFloat(2, _translation.z);
  510. break;
  511. case ANIMATE_TRANSLATE_X:
  512. value->setFloat(0, _translation.x);
  513. break;
  514. case ANIMATE_TRANSLATE_Y:
  515. value->setFloat(0, _translation.y);
  516. break;
  517. case ANIMATE_TRANSLATE_Z:
  518. value->setFloat(0, _translation.z);
  519. break;
  520. case ANIMATE_ROTATE_TRANSLATE:
  521. value->setFloat(0, _rotation.x);
  522. value->setFloat(1, _rotation.y);
  523. value->setFloat(2, _rotation.z);
  524. value->setFloat(3, _rotation.w);
  525. value->setFloat(4, _translation.x);
  526. value->setFloat(5, _translation.y);
  527. value->setFloat(6, _translation.z);
  528. break;
  529. case ANIMATE_SCALE_ROTATE_TRANSLATE:
  530. value->setFloat(0, _scale.x);
  531. value->setFloat(1, _scale.y);
  532. value->setFloat(2, _scale.z);
  533. value->setFloat(3, _rotation.x);
  534. value->setFloat(4, _rotation.y);
  535. value->setFloat(5, _rotation.z);
  536. value->setFloat(6, _rotation.w);
  537. value->setFloat(7, _translation.x);
  538. value->setFloat(8, _translation.y);
  539. value->setFloat(9, _translation.z);
  540. break;
  541. default:
  542. break;
  543. }
  544. }
  545. void Transform::setAnimationPropertyValue(int propertyId, AnimationValue* value)
  546. {
  547. switch (propertyId)
  548. {
  549. case ANIMATE_SCALE:
  550. setScale(value->getFloat(0), value->getFloat(1), value->getFloat(2));
  551. break;
  552. case ANIMATE_SCALE_X:
  553. setScaleX(value->getFloat(0));
  554. break;
  555. case ANIMATE_SCALE_Y:
  556. setScaleY(value->getFloat(0));
  557. break;
  558. case ANIMATE_SCALE_Z:
  559. setScaleZ(value->getFloat(0));
  560. break;
  561. case ANIMATE_ROTATE:
  562. setRotation(value->getFloat(0), value->getFloat(1), value->getFloat(2), value->getFloat(3));
  563. break;
  564. case ANIMATE_TRANSLATE:
  565. setTranslation(value->getFloat(0), value->getFloat(1), value->getFloat(2));
  566. break;
  567. case ANIMATE_TRANSLATE_X:
  568. setTranslationX(value->getFloat(0));
  569. break;
  570. case ANIMATE_TRANSLATE_Y:
  571. setTranslationY(value->getFloat(0));
  572. break;
  573. case ANIMATE_TRANSLATE_Z:
  574. setTranslationZ(value->getFloat(0));
  575. break;
  576. case ANIMATE_ROTATE_TRANSLATE:
  577. setRotation(value->getFloat(0), value->getFloat(1), value->getFloat(2), value->getFloat(3));
  578. setTranslation(value->getFloat(4), value->getFloat(5), value->getFloat(6));
  579. break;
  580. case ANIMATE_SCALE_ROTATE_TRANSLATE:
  581. setScale(value->getFloat(0), value->getFloat(1), value->getFloat(2));
  582. setRotation(value->getFloat(3), value->getFloat(4), value->getFloat(5), value->getFloat(6));
  583. setTranslation(value->getFloat(7), value->getFloat(8), value->getFloat(9));
  584. break;
  585. default:
  586. break;
  587. }
  588. }
  589. void Transform::dirty()
  590. {
  591. _matrixDirty = true;
  592. transformChanged();
  593. }
  594. void Transform::addListener(Transform::Listener* listener, long cookie)
  595. {
  596. if (_listeners == NULL)
  597. _listeners = new std::list<TransformListener>();
  598. TransformListener l;
  599. l.listener = listener;
  600. l.cookie = cookie;
  601. _listeners->push_back(l);
  602. }
  603. void Transform::removeListener(Transform::Listener* listener)
  604. {
  605. if (_listeners)
  606. {
  607. for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); itr++)
  608. {
  609. if ((*itr).listener == listener)
  610. {
  611. _listeners->erase(itr);
  612. break;
  613. }
  614. }
  615. }
  616. }
  617. void Transform::transformChanged()
  618. {
  619. if (_listeners)
  620. {
  621. for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); itr++)
  622. {
  623. TransformListener& l = *itr;
  624. l.listener->transformChanged(this, l.cookie);
  625. }
  626. }
  627. }
  628. }