BsTransform.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Scene/BsTransform.h"
  4. #include "Private/RTTI/BsTransformRTTI.h"
  5. namespace bs
  6. {
  7. Transform::Transform()
  8. : mPosition(Vector3::ZERO), mRotation(Quaternion::IDENTITY), mScale(Vector3::ONE)
  9. { }
  10. Transform::Transform(const Vector3& position, const Quaternion& rotation, const Vector3& scale)
  11. : mPosition(position), mRotation(rotation), mScale(scale)
  12. { }
  13. Matrix4 Transform::getMatrix() const
  14. {
  15. return Matrix4::TRS(mPosition, mRotation, mScale);
  16. }
  17. Matrix4 Transform::getInvMatrix() const
  18. {
  19. return Matrix4::inverseTRS(mPosition, mRotation, mScale);
  20. }
  21. void Transform::makeLocal(const Transform& parent)
  22. {
  23. setWorldPosition(mPosition, parent);
  24. setWorldRotation(mRotation, parent);
  25. setWorldScale(mScale, parent);
  26. }
  27. void Transform::makeWorld(const Transform& parent)
  28. {
  29. // Update orientation
  30. const Quaternion& parentOrientation = parent.getRotation();
  31. mRotation = parentOrientation * mRotation;
  32. // Update scale
  33. const Vector3& parentScale = parent.getScale();
  34. // Scale own position by parent scale, just combine as equivalent axes, no shearing
  35. mScale = parentScale * mScale;
  36. // Change position vector based on parent's orientation & scale
  37. mPosition = parentOrientation.rotate(parentScale * mPosition);
  38. // Add altered position vector to parents
  39. mPosition += parent.getPosition();
  40. }
  41. void Transform::setWorldPosition(const Vector3& position, const Transform& parent)
  42. {
  43. Vector3 invScale = parent.getScale();
  44. if (invScale.x != 0) invScale.x = 1.0f / invScale.x;
  45. if (invScale.y != 0) invScale.y = 1.0f / invScale.y;
  46. if (invScale.z != 0) invScale.z = 1.0f / invScale.z;
  47. Quaternion invRotation = parent.getRotation().inverse();
  48. mPosition = invRotation.rotate(position - parent.getPosition()) * invScale;
  49. }
  50. void Transform::setWorldRotation(const Quaternion& rotation, const Transform& parent)
  51. {
  52. Quaternion invRotation = parent.getRotation().inverse();
  53. mRotation = invRotation * rotation;
  54. }
  55. void Transform::setWorldScale(const Vector3& scale, const Transform& parent)
  56. {
  57. Matrix3 rotScale;
  58. Matrix4 parentMatrix = parent.getMatrix();
  59. parentMatrix.extract3x3Matrix(rotScale);
  60. rotScale.inverse();
  61. Matrix3 scaleMat = Matrix3(Quaternion::IDENTITY, scale);
  62. scaleMat = rotScale * scaleMat;
  63. Quaternion rotation;
  64. Vector3 localScale;
  65. scaleMat.decomposition(rotation, localScale);
  66. mScale = localScale;
  67. }
  68. void Transform::lookAt(const Vector3& location, const Vector3& up)
  69. {
  70. Vector3 forward = location - getPosition();
  71. Quaternion rotation = getRotation();
  72. rotation.lookRotation(forward, up);
  73. setRotation(rotation);
  74. }
  75. void Transform::move(const Vector3& vec)
  76. {
  77. setPosition(mPosition + vec);
  78. }
  79. void Transform::moveRelative(const Vector3& vec)
  80. {
  81. // Transform the axes of the relative vector by camera's local axes
  82. Vector3 trans = mRotation.rotate(vec);
  83. setPosition(mPosition + trans);
  84. }
  85. void Transform::rotate(const Vector3& axis, const Radian& angle)
  86. {
  87. Quaternion q;
  88. q.fromAxisAngle(axis, angle);
  89. rotate(q);
  90. }
  91. void Transform::rotate(const Quaternion& q)
  92. {
  93. // Note the order of the mult, i.e. q comes after
  94. // Normalize the quat to avoid cumulative problems with precision
  95. Quaternion qnorm = q;
  96. qnorm.normalize();
  97. setRotation(qnorm * mRotation);
  98. }
  99. void Transform::roll(const Radian& angle)
  100. {
  101. // Rotate around local Z axis
  102. Vector3 zAxis = mRotation.rotate(Vector3::UNIT_Z);
  103. rotate(zAxis, angle);
  104. }
  105. void Transform::yaw(const Radian& angle)
  106. {
  107. Vector3 yAxis = mRotation.rotate(Vector3::UNIT_Y);
  108. rotate(yAxis, angle);
  109. }
  110. void Transform::pitch(const Radian& angle)
  111. {
  112. // Rotate around local X axis
  113. Vector3 xAxis = mRotation.rotate(Vector3::UNIT_X);
  114. rotate(xAxis, angle);
  115. }
  116. void Transform::setForward(const Vector3& forwardDir)
  117. {
  118. Quaternion currentRotation = getRotation();
  119. currentRotation.lookRotation(forwardDir);
  120. setRotation(currentRotation);
  121. }
  122. RTTITypeBase* Transform::getRTTIStatic()
  123. {
  124. return TransformRTTI::instance();
  125. }
  126. RTTITypeBase* Transform::getRTTI() const
  127. {
  128. return Transform::getRTTIStatic();
  129. }
  130. }