BsTransform.cpp 4.1 KB

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