Transform.cpp 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. #include "Base.h"
  2. #include "Transform.h"
  3. #include "Game.h"
  4. #include "Node.h"
  5. namespace gameplay
  6. {
  7. int Transform::_suspendTransformChanged(0);
  8. std::vector<Transform*> Transform::_transformsChanged;
  9. Transform::Transform()
  10. : _matrixDirtyBits(0), _listeners(NULL)
  11. {
  12. _targetType = AnimationTarget::TRANSFORM;
  13. _scale.set(Vector3::one());
  14. addScriptEvent("transformChanged", "<Transform>");
  15. }
  16. Transform::Transform(const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
  17. : _matrixDirtyBits(0), _listeners(NULL)
  18. {
  19. _targetType = AnimationTarget::TRANSFORM;
  20. set(scale, rotation, translation);
  21. addScriptEvent("transformChanged", "<Transform>");
  22. }
  23. Transform::Transform(const Vector3& scale, const Matrix& rotation, const Vector3& translation)
  24. : _matrixDirtyBits(0), _listeners(NULL)
  25. {
  26. _targetType = AnimationTarget::TRANSFORM;
  27. set(scale, rotation, translation);
  28. addScriptEvent("transformChanged", "<Transform>");
  29. }
  30. Transform::Transform(const Transform& copy)
  31. : _matrixDirtyBits(0), _listeners(NULL)
  32. {
  33. _targetType = AnimationTarget::TRANSFORM;
  34. set(copy);
  35. addScriptEvent("transformChanged", "<Transform>");
  36. }
  37. Transform::~Transform()
  38. {
  39. SAFE_DELETE(_listeners);
  40. }
  41. void Transform::suspendTransformChanged()
  42. {
  43. _suspendTransformChanged++;
  44. }
  45. void Transform::resumeTransformChanged()
  46. {
  47. if (_suspendTransformChanged == 0) // We haven't suspended transformChanged() calls, so do nothing.
  48. return;
  49. if (_suspendTransformChanged == 1)
  50. {
  51. // Call transformChanged() on all transforms in the list
  52. size_t transformCount = _transformsChanged.size();
  53. for (size_t i = 0; i < transformCount; i++)
  54. {
  55. Transform* t = _transformsChanged.at(i);
  56. GP_ASSERT(t);
  57. t->transformChanged();
  58. }
  59. // Go through list and reset DIRTY_NOTIFY bit. The list could potentially be larger here if the
  60. // transforms we were delaying calls to transformChanged() have any child nodes.
  61. transformCount = _transformsChanged.size();
  62. for (size_t i = 0; i < transformCount; i++)
  63. {
  64. Transform* t = _transformsChanged.at(i);
  65. GP_ASSERT(t);
  66. t->_matrixDirtyBits &= ~DIRTY_NOTIFY;
  67. }
  68. // empty list for next frame.
  69. _transformsChanged.clear();
  70. }
  71. _suspendTransformChanged--;
  72. }
  73. bool Transform::isTransformChangedSuspended()
  74. {
  75. return (_suspendTransformChanged > 0);
  76. }
  77. const Matrix& Transform::getMatrix() const
  78. {
  79. if (_matrixDirtyBits)
  80. {
  81. if (!isStatic())
  82. {
  83. bool hasTranslation = !_translation.isZero();
  84. bool hasScale = !_scale.isOne();
  85. bool hasRotation = !_rotation.isIdentity();
  86. // Compose the matrix in TRS order since we use column-major matrices with column vectors and
  87. // multiply M*v (as opposed to XNA and DirectX that use row-major matrices with row vectors and multiply v*M).
  88. if (hasTranslation || (_matrixDirtyBits & DIRTY_TRANSLATION) == DIRTY_TRANSLATION)
  89. {
  90. Matrix::createTranslation(_translation, &_matrix);
  91. if (hasRotation || (_matrixDirtyBits & DIRTY_ROTATION) == DIRTY_ROTATION)
  92. {
  93. _matrix.rotate(_rotation);
  94. }
  95. if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
  96. {
  97. _matrix.scale(_scale);
  98. }
  99. }
  100. else if (hasRotation || (_matrixDirtyBits & DIRTY_ROTATION) == DIRTY_ROTATION)
  101. {
  102. Matrix::createRotation(_rotation, &_matrix);
  103. if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
  104. {
  105. _matrix.scale(_scale);
  106. }
  107. }
  108. else if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
  109. {
  110. Matrix::createScale(_scale, &_matrix);
  111. }
  112. }
  113. _matrixDirtyBits &= ~DIRTY_TRANSLATION & ~DIRTY_ROTATION & ~DIRTY_SCALE;
  114. }
  115. return _matrix;
  116. }
  117. const Vector3& Transform::getScale() const
  118. {
  119. return _scale;
  120. }
  121. void Transform::getScale(Vector3* scale) const
  122. {
  123. GP_ASSERT(scale);
  124. scale->set(_scale);
  125. }
  126. float Transform::getScaleX() const
  127. {
  128. return _scale.x;
  129. }
  130. float Transform::getScaleY() const
  131. {
  132. return _scale.y;
  133. }
  134. float Transform::getScaleZ() const
  135. {
  136. return _scale.z;
  137. }
  138. const Quaternion& Transform::getRotation() const
  139. {
  140. return _rotation;
  141. }
  142. void Transform::getRotation(Quaternion* rotation) const
  143. {
  144. GP_ASSERT(rotation);
  145. rotation->set(_rotation);
  146. }
  147. void Transform::getRotation(Matrix* rotation) const
  148. {
  149. GP_ASSERT(rotation);
  150. Matrix::createRotation(_rotation, rotation);
  151. }
  152. float Transform::getRotation(Vector3* axis) const
  153. {
  154. GP_ASSERT(axis);
  155. return _rotation.toAxisAngle(axis);
  156. }
  157. const Vector3& Transform::getTranslation() const
  158. {
  159. return _translation;
  160. }
  161. void Transform::getTranslation(Vector3* translation) const
  162. {
  163. GP_ASSERT(translation);
  164. translation->set(_translation);
  165. }
  166. float Transform::getTranslationX() const
  167. {
  168. return _translation.x;
  169. }
  170. float Transform::getTranslationY() const
  171. {
  172. return _translation.y;
  173. }
  174. float Transform::getTranslationZ() const
  175. {
  176. return _translation.z;
  177. }
  178. Vector3 Transform::getForwardVector() const
  179. {
  180. Vector3 v;
  181. getForwardVector(&v);
  182. return v;
  183. }
  184. void Transform::getForwardVector(Vector3* dst) const
  185. {
  186. getMatrix().getForwardVector(dst);
  187. }
  188. Vector3 Transform::getBackVector() const
  189. {
  190. Vector3 v;
  191. getBackVector(&v);
  192. return v;
  193. }
  194. void Transform::getBackVector(Vector3* dst) const
  195. {
  196. getMatrix().getBackVector(dst);
  197. }
  198. Vector3 Transform::getUpVector() const
  199. {
  200. Vector3 v;
  201. getUpVector(&v);
  202. return v;
  203. }
  204. void Transform::getUpVector(Vector3* dst) const
  205. {
  206. getMatrix().getUpVector(dst);
  207. }
  208. Vector3 Transform::getDownVector() const
  209. {
  210. Vector3 v;
  211. getDownVector(&v);
  212. return v;
  213. }
  214. void Transform::getDownVector(Vector3* dst) const
  215. {
  216. getMatrix().getDownVector(dst);
  217. }
  218. Vector3 Transform::getLeftVector() const
  219. {
  220. Vector3 v;
  221. getLeftVector(&v);
  222. return v;
  223. }
  224. void Transform::getLeftVector(Vector3* dst) const
  225. {
  226. getMatrix().getLeftVector(dst);
  227. }
  228. Vector3 Transform::getRightVector() const
  229. {
  230. Vector3 v;
  231. getRightVector(&v);
  232. return v;
  233. }
  234. void Transform::getRightVector(Vector3* dst) const
  235. {
  236. getMatrix().getRightVector(dst);
  237. }
  238. void Transform::rotate(float qx, float qy, float qz, float qw)
  239. {
  240. if (isStatic())
  241. return;
  242. Quaternion q(qx, qy, qz, qw);
  243. _rotation.multiply(q);
  244. dirty(DIRTY_ROTATION);
  245. }
  246. void Transform::rotate(const Quaternion& rotation)
  247. {
  248. if (isStatic())
  249. return;
  250. _rotation.multiply(rotation);
  251. dirty(DIRTY_ROTATION);
  252. }
  253. void Transform::rotate(const Vector3& axis, float angle)
  254. {
  255. if (isStatic())
  256. return;
  257. Quaternion rotationQuat;
  258. Quaternion::createFromAxisAngle(axis, angle, &rotationQuat);
  259. _rotation.multiply(rotationQuat);
  260. _rotation.normalize();
  261. dirty(DIRTY_ROTATION);
  262. }
  263. void Transform::rotate(const Matrix& rotation)
  264. {
  265. if (isStatic())
  266. return;
  267. Quaternion rotationQuat;
  268. Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
  269. _rotation.multiply(rotationQuat);
  270. dirty(DIRTY_ROTATION);
  271. }
  272. void Transform::rotateX(float angle)
  273. {
  274. if (isStatic())
  275. return;
  276. Quaternion rotationQuat;
  277. Quaternion::createFromAxisAngle(Vector3::unitX(), angle, &rotationQuat);
  278. _rotation.multiply(rotationQuat);
  279. dirty(DIRTY_ROTATION);
  280. }
  281. void Transform::rotateY(float angle)
  282. {
  283. if (isStatic())
  284. return;
  285. Quaternion rotationQuat;
  286. Quaternion::createFromAxisAngle(Vector3::unitY(), angle, &rotationQuat);
  287. _rotation.multiply(rotationQuat);
  288. dirty(DIRTY_ROTATION);
  289. }
  290. void Transform::rotateZ(float angle)
  291. {
  292. if (isStatic())
  293. return;
  294. Quaternion rotationQuat;
  295. Quaternion::createFromAxisAngle(Vector3::unitZ(), angle, &rotationQuat);
  296. _rotation.multiply(rotationQuat);
  297. dirty(DIRTY_ROTATION);
  298. }
  299. void Transform::scale(float scale)
  300. {
  301. if (isStatic())
  302. return;
  303. _scale.scale(scale);
  304. dirty(DIRTY_SCALE);
  305. }
  306. void Transform::scale(float sx, float sy, float sz)
  307. {
  308. if (isStatic())
  309. return;
  310. _scale.x *= sx;
  311. _scale.y *= sy;
  312. _scale.z *= sz;
  313. dirty(DIRTY_SCALE);
  314. }
  315. void Transform::scale(const Vector3& scale)
  316. {
  317. if (isStatic())
  318. return;
  319. _scale.x *= scale.x;
  320. _scale.y *= scale.y;
  321. _scale.z *= scale.z;
  322. dirty(DIRTY_SCALE);
  323. }
  324. void Transform::scaleX(float sx)
  325. {
  326. if (isStatic())
  327. return;
  328. _scale.x *= sx;
  329. dirty(DIRTY_SCALE);
  330. }
  331. void Transform::scaleY(float sy)
  332. {
  333. if (isStatic())
  334. return;
  335. _scale.y *= sy;
  336. dirty(DIRTY_SCALE);
  337. }
  338. void Transform::scaleZ(float sz)
  339. {
  340. if (isStatic())
  341. return;
  342. _scale.z *= sz;
  343. dirty(DIRTY_SCALE);
  344. }
  345. void Transform::set(const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
  346. {
  347. if (isStatic())
  348. return;
  349. _scale.set(scale);
  350. _rotation.set(rotation);
  351. _translation.set(translation);
  352. dirty(DIRTY_TRANSLATION | DIRTY_ROTATION | DIRTY_SCALE);
  353. }
  354. void Transform::set(const Vector3& scale, const Matrix& rotation, const Vector3& translation)
  355. {
  356. if (isStatic())
  357. return;
  358. _scale.set(scale);
  359. Quaternion rotationQuat;
  360. Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
  361. _rotation.set(rotationQuat);
  362. _translation.set(translation);
  363. dirty(DIRTY_TRANSLATION | DIRTY_ROTATION | DIRTY_SCALE);
  364. }
  365. void Transform::set(const Vector3& scale, const Vector3& axis, float angle, const Vector3& translation)
  366. {
  367. if (isStatic())
  368. return;
  369. _scale.set(scale);
  370. _rotation.set(axis, angle);
  371. _translation.set(translation);
  372. dirty(DIRTY_TRANSLATION | DIRTY_ROTATION | DIRTY_SCALE);
  373. }
  374. void Transform::set(const Transform& transform)
  375. {
  376. if (isStatic())
  377. return;
  378. _scale.set(transform._scale);
  379. _rotation.set(transform._rotation);
  380. _translation.set(transform._translation);
  381. dirty(DIRTY_TRANSLATION | DIRTY_ROTATION | DIRTY_SCALE);
  382. }
  383. void Transform::setIdentity()
  384. {
  385. if (isStatic())
  386. return;
  387. _scale.set(1.0f, 1.0f, 1.0f);
  388. _rotation.setIdentity();
  389. _translation.set(0.0f, 0.0f, 0.0f);
  390. dirty(DIRTY_TRANSLATION | DIRTY_ROTATION | DIRTY_SCALE);
  391. }
  392. void Transform::setScale(float scale)
  393. {
  394. if (isStatic())
  395. return;
  396. _scale.set(scale, scale, scale);
  397. dirty(DIRTY_SCALE);
  398. }
  399. void Transform::setScale(float sx, float sy, float sz)
  400. {
  401. if (isStatic())
  402. return;
  403. _scale.set(sx, sy, sz);
  404. dirty(DIRTY_SCALE);
  405. }
  406. void Transform::setScale(const Vector3& scale)
  407. {
  408. _scale.set(scale);
  409. dirty(DIRTY_SCALE);
  410. }
  411. void Transform::setScaleX(float sx)
  412. {
  413. if (isStatic())
  414. return;
  415. _scale.x = sx;
  416. dirty(DIRTY_SCALE);
  417. }
  418. void Transform::setScaleY(float sy)
  419. {
  420. if (isStatic())
  421. return;
  422. _scale.y = sy;
  423. dirty(DIRTY_SCALE);
  424. }
  425. void Transform::setScaleZ(float sz)
  426. {
  427. if (isStatic())
  428. return;
  429. _scale.z = sz;
  430. dirty(DIRTY_SCALE);
  431. }
  432. void Transform::setRotation(const Quaternion& rotation)
  433. {
  434. if (isStatic())
  435. return;
  436. _rotation.set(rotation);
  437. dirty(DIRTY_ROTATION);
  438. }
  439. void Transform::setRotation(float qx, float qy, float qz, float qw)
  440. {
  441. if (isStatic())
  442. return;
  443. _rotation.set(qx, qy, qz, qw);
  444. dirty(DIRTY_ROTATION);
  445. }
  446. void Transform::setRotation(const Matrix& rotation)
  447. {
  448. if (isStatic())
  449. return;
  450. Quaternion rotationQuat;
  451. Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
  452. _rotation.set(rotationQuat);
  453. dirty(DIRTY_ROTATION);
  454. }
  455. void Transform::setRotation(const Vector3& axis, float angle)
  456. {
  457. if (isStatic())
  458. return;
  459. _rotation.set(axis, angle);
  460. dirty(DIRTY_ROTATION);
  461. }
  462. void Transform::setTranslation(const Vector3& translation)
  463. {
  464. if (isStatic())
  465. return;
  466. _translation.set(translation);
  467. dirty(DIRTY_TRANSLATION);
  468. }
  469. void Transform::setTranslation(float tx, float ty, float tz)
  470. {
  471. if (isStatic())
  472. return;
  473. _translation.set(tx, ty, tz);
  474. dirty(DIRTY_TRANSLATION);
  475. }
  476. void Transform::setTranslationX(float tx)
  477. {
  478. if (isStatic())
  479. return;
  480. _translation.x = tx;
  481. dirty(DIRTY_TRANSLATION);
  482. }
  483. void Transform::setTranslationY(float ty)
  484. {
  485. if (isStatic())
  486. return;
  487. _translation.y = ty;
  488. dirty(DIRTY_TRANSLATION);
  489. }
  490. void Transform::setTranslationZ(float tz)
  491. {
  492. if (isStatic())
  493. return;
  494. _translation.z = tz;
  495. dirty(DIRTY_TRANSLATION);
  496. }
  497. void Transform::translate(float tx, float ty, float tz)
  498. {
  499. if (isStatic())
  500. return;
  501. _translation.x += tx;
  502. _translation.y += ty;
  503. _translation.z += tz;
  504. dirty(DIRTY_TRANSLATION);
  505. }
  506. void Transform::translate(const Vector3& translation)
  507. {
  508. if (isStatic())
  509. return;
  510. _translation.x += translation.x;
  511. _translation.y += translation.y;
  512. _translation.z += translation.z;
  513. dirty(DIRTY_TRANSLATION);
  514. }
  515. void Transform::translateX(float tx)
  516. {
  517. if (isStatic())
  518. return;
  519. _translation.x += tx;
  520. dirty(DIRTY_TRANSLATION);
  521. }
  522. void Transform::translateY(float ty)
  523. {
  524. if (isStatic())
  525. return;
  526. _translation.y += ty;
  527. dirty(DIRTY_TRANSLATION);
  528. }
  529. void Transform::translateZ(float tz)
  530. {
  531. if (isStatic())
  532. return;
  533. _translation.z += tz;
  534. dirty(DIRTY_TRANSLATION);
  535. }
  536. void Transform::translateLeft(float amount)
  537. {
  538. if (isStatic())
  539. return;
  540. // Force the current transform matrix to be updated.
  541. getMatrix();
  542. Vector3 left;
  543. _matrix.getLeftVector(&left);
  544. left.normalize();
  545. left.scale(amount);
  546. translate(left);
  547. }
  548. void Transform::translateUp(float amount)
  549. {
  550. if (isStatic())
  551. return;
  552. // Force the current transform matrix to be updated.
  553. getMatrix();
  554. Vector3 up;
  555. _matrix.getUpVector(&up);
  556. up.normalize();
  557. up.scale(amount);
  558. translate(up);
  559. }
  560. void Transform::translateForward(float amount)
  561. {
  562. if (isStatic())
  563. return;
  564. // Force the current transform matrix to be updated.
  565. getMatrix();
  566. Vector3 forward;
  567. _matrix.getForwardVector(&forward);
  568. forward.normalize();
  569. forward.scale(amount);
  570. translate(forward);
  571. }
  572. void Transform::translateSmooth(const Vector3& target, float elapsedTime, float responseTime)
  573. {
  574. if (isStatic())
  575. return;
  576. if (elapsedTime > 0)
  577. {
  578. _translation += (target - _translation) * (elapsedTime / (elapsedTime + responseTime));
  579. dirty(DIRTY_TRANSLATION);
  580. }
  581. }
  582. void Transform::transformPoint(Vector3* point)
  583. {
  584. getMatrix();
  585. _matrix.transformPoint(point);
  586. }
  587. void Transform::transformPoint(const Vector3& point, Vector3* dst)
  588. {
  589. getMatrix();
  590. _matrix.transformPoint(point, dst);
  591. }
  592. void Transform::transformVector(Vector3* normal)
  593. {
  594. getMatrix();
  595. _matrix.transformVector(normal);
  596. }
  597. void Transform::transformVector(const Vector3& normal, Vector3* dst)
  598. {
  599. getMatrix();
  600. _matrix.transformVector(normal, dst);
  601. }
  602. void Transform::transformVector(float x, float y, float z, float w, Vector3* dst)
  603. {
  604. getMatrix();
  605. _matrix.transformVector(x, y, z, w, dst);
  606. }
  607. bool Transform::isStatic() const
  608. {
  609. return false;
  610. }
  611. unsigned int Transform::getAnimationPropertyComponentCount(int propertyId) const
  612. {
  613. switch (propertyId)
  614. {
  615. case ANIMATE_SCALE_UNIT:
  616. case ANIMATE_SCALE_X:
  617. case ANIMATE_SCALE_Y:
  618. case ANIMATE_SCALE_Z:
  619. case ANIMATE_TRANSLATE_X:
  620. case ANIMATE_TRANSLATE_Y:
  621. case ANIMATE_TRANSLATE_Z:
  622. return 1;
  623. case ANIMATE_SCALE:
  624. case ANIMATE_TRANSLATE:
  625. return 3;
  626. case ANIMATE_ROTATE:
  627. return 4;
  628. case ANIMATE_SCALE_TRANSLATE:
  629. return 6;
  630. case ANIMATE_ROTATE_TRANSLATE:
  631. case ANIMATE_SCALE_ROTATE:
  632. return 7;
  633. case ANIMATE_SCALE_ROTATE_TRANSLATE:
  634. return 10;
  635. default:
  636. return -1;
  637. }
  638. }
  639. void Transform::getAnimationPropertyValue(int propertyId, AnimationValue* value)
  640. {
  641. GP_ASSERT(value);
  642. switch (propertyId)
  643. {
  644. case ANIMATE_SCALE_UNIT:
  645. value->setFloat(0, _scale.x);
  646. break;
  647. case ANIMATE_SCALE:
  648. value->setFloats(0, &_scale.x, 3);
  649. break;
  650. case ANIMATE_SCALE_X:
  651. value->setFloat(0, _scale.x);
  652. break;
  653. case ANIMATE_SCALE_Y:
  654. value->setFloat(0, _scale.y);
  655. break;
  656. case ANIMATE_SCALE_Z:
  657. value->setFloat(0, _scale.z);
  658. break;
  659. case ANIMATE_ROTATE:
  660. value->setFloats(0, &_rotation.x, 4);
  661. break;
  662. case ANIMATE_TRANSLATE:
  663. value->setFloats(0, &_translation.x, 3);
  664. break;
  665. case ANIMATE_TRANSLATE_X:
  666. value->setFloat(0, _translation.x);
  667. break;
  668. case ANIMATE_TRANSLATE_Y:
  669. value->setFloat(0, _translation.y);
  670. break;
  671. case ANIMATE_TRANSLATE_Z:
  672. value->setFloat(0, _translation.z);
  673. break;
  674. case ANIMATE_ROTATE_TRANSLATE:
  675. value->setFloats(0, &_rotation.x, 4);
  676. value->setFloats(4, &_translation.x, 3);
  677. break;
  678. case ANIMATE_SCALE_ROTATE:
  679. value->setFloats(0, &_scale.x, 3);
  680. value->setFloats(3, &_rotation.x, 4);
  681. break;
  682. case ANIMATE_SCALE_TRANSLATE:
  683. value->setFloats(0, &_scale.x, 3);
  684. value->setFloats(3, &_translation.x, 3);
  685. break;
  686. case ANIMATE_SCALE_ROTATE_TRANSLATE:
  687. value->setFloats(0, &_scale.x, 3);
  688. value->setFloats(3, &_rotation.x, 4);
  689. value->setFloats(7, &_translation.x, 3);
  690. break;
  691. default:
  692. break;
  693. }
  694. }
  695. void Transform::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
  696. {
  697. GP_ASSERT(value);
  698. GP_ASSERT(blendWeight >= 0.0f && blendWeight <= 1.0f);
  699. switch (propertyId)
  700. {
  701. case ANIMATE_SCALE_UNIT:
  702. {
  703. float scale = Curve::lerp(blendWeight, _scale.x, value->getFloat(0));
  704. setScale(scale);
  705. break;
  706. }
  707. case ANIMATE_SCALE:
  708. {
  709. setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
  710. break;
  711. }
  712. case ANIMATE_SCALE_X:
  713. {
  714. setScaleX(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)));
  715. break;
  716. }
  717. case ANIMATE_SCALE_Y:
  718. {
  719. setScaleY(Curve::lerp(blendWeight, _scale.y, value->getFloat(0)));
  720. break;
  721. }
  722. case ANIMATE_SCALE_Z:
  723. {
  724. setScaleZ(Curve::lerp(blendWeight, _scale.z, value->getFloat(0)));
  725. break;
  726. }
  727. case ANIMATE_ROTATE:
  728. {
  729. applyAnimationValueRotation(value, 0, blendWeight);
  730. break;
  731. }
  732. case ANIMATE_TRANSLATE:
  733. {
  734. setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(0)), Curve::lerp(blendWeight, _translation.y, value->getFloat(1)), Curve::lerp(blendWeight, _translation.z, value->getFloat(2)));
  735. break;
  736. }
  737. case ANIMATE_TRANSLATE_X:
  738. {
  739. setTranslationX(Curve::lerp(blendWeight, _translation.x, value->getFloat(0)));
  740. break;
  741. }
  742. case ANIMATE_TRANSLATE_Y:
  743. {
  744. setTranslationY(Curve::lerp(blendWeight, _translation.y, value->getFloat(0)));
  745. break;
  746. }
  747. case ANIMATE_TRANSLATE_Z:
  748. {
  749. setTranslationZ(Curve::lerp(blendWeight, _translation.z, value->getFloat(0)));
  750. break;
  751. }
  752. case ANIMATE_ROTATE_TRANSLATE:
  753. {
  754. applyAnimationValueRotation(value, 0, blendWeight);
  755. setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(4)), Curve::lerp(blendWeight, _translation.y, value->getFloat(5)), Curve::lerp(blendWeight, _translation.z, value->getFloat(6)));
  756. break;
  757. }
  758. case ANIMATE_SCALE_ROTATE:
  759. {
  760. setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
  761. applyAnimationValueRotation(value, 3, blendWeight);
  762. break;
  763. }
  764. case ANIMATE_SCALE_TRANSLATE:
  765. {
  766. setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
  767. setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(3)), Curve::lerp(blendWeight, _translation.y, value->getFloat(4)), Curve::lerp(blendWeight, _translation.z, value->getFloat(5)));
  768. break;
  769. }
  770. case ANIMATE_SCALE_ROTATE_TRANSLATE:
  771. {
  772. setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
  773. applyAnimationValueRotation(value, 3, blendWeight);
  774. setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(7)), Curve::lerp(blendWeight, _translation.y, value->getFloat(8)), Curve::lerp(blendWeight, _translation.z, value->getFloat(9)));
  775. break;
  776. }
  777. default:
  778. break;
  779. }
  780. }
  781. void Transform::dirty(char matrixDirtyBits)
  782. {
  783. _matrixDirtyBits |= matrixDirtyBits;
  784. if (isTransformChangedSuspended())
  785. {
  786. if (!isDirty(DIRTY_NOTIFY))
  787. {
  788. suspendTransformChange(this);
  789. }
  790. }
  791. else
  792. {
  793. transformChanged();
  794. }
  795. }
  796. bool Transform::isDirty(char matrixDirtyBits) const
  797. {
  798. return (_matrixDirtyBits & matrixDirtyBits) == matrixDirtyBits;
  799. }
  800. void Transform::suspendTransformChange(Transform* transform)
  801. {
  802. GP_ASSERT(transform);
  803. transform->_matrixDirtyBits |= DIRTY_NOTIFY;
  804. _transformsChanged.push_back(transform);
  805. }
  806. void Transform::addListener(Transform::Listener* listener, long cookie)
  807. {
  808. GP_ASSERT(listener);
  809. if (_listeners == NULL)
  810. _listeners = new std::list<TransformListener>();
  811. TransformListener l;
  812. l.listener = listener;
  813. l.cookie = cookie;
  814. _listeners->push_back(l);
  815. }
  816. void Transform::removeListener(Transform::Listener* listener)
  817. {
  818. GP_ASSERT(listener);
  819. if (_listeners)
  820. {
  821. for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); ++itr)
  822. {
  823. if ((*itr).listener == listener)
  824. {
  825. _listeners->erase(itr);
  826. break;
  827. }
  828. }
  829. }
  830. }
  831. void Transform::transformChanged()
  832. {
  833. if (_listeners)
  834. {
  835. for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); ++itr)
  836. {
  837. TransformListener& l = *itr;
  838. GP_ASSERT(l.listener);
  839. l.listener->transformChanged(this, l.cookie);
  840. }
  841. }
  842. fireScriptEvent<void>("transformChanged", this);
  843. }
  844. void Transform::cloneInto(Transform* transform, NodeCloneContext &context) const
  845. {
  846. GP_ASSERT(transform);
  847. AnimationTarget::cloneInto(transform, context);
  848. transform->_scale.set(_scale);
  849. transform->_rotation.set(_rotation);
  850. transform->_translation.set(_translation);
  851. transform->dirty(DIRTY_TRANSLATION | DIRTY_ROTATION | DIRTY_SCALE);
  852. }
  853. void Transform::applyAnimationValueRotation(AnimationValue* value, unsigned int index, float blendWeight)
  854. {
  855. if (isStatic())
  856. return;
  857. GP_ASSERT(value);
  858. Quaternion::slerp(_rotation.x, _rotation.y, _rotation.z, _rotation.w, value->getFloat(index), value->getFloat(index + 1), value->getFloat(index + 2), value->getFloat(index + 3), blendWeight,
  859. &_rotation.x, &_rotation.y, &_rotation.z, &_rotation.w);
  860. dirty(DIRTY_ROTATION);
  861. }
  862. }