BsObjectRotator.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "BsObjectRotator.h"
  2. #include "Math/BsVector3.h"
  3. #include "Utility/BsTime.h"
  4. #include "Math/BsMath.h"
  5. #include "Scene/BsSceneObject.h"
  6. #include "Platform/BsCursor.h"
  7. namespace bs
  8. {
  9. const float ObjectRotator::ROTATION_SPEED = 1.0f;
  10. /** Wraps an angle so it always stays in [0, 360) range. */
  11. Degree wrapAngle2(Degree angle)
  12. {
  13. if (angle.valueDegrees() < -360.0f)
  14. angle += Degree(360.0f);
  15. if (angle.valueDegrees() > 360.0f)
  16. angle -= Degree(360.0f);
  17. return angle;
  18. }
  19. ObjectRotator::ObjectRotator(const HSceneObject& parent)
  20. :Component(parent), mPitch(0.0f), mYaw(0.0f), mLastButtonState(false)
  21. {
  22. // Set a name for the component, so we can find it later if needed
  23. setName("ObjectRotator");
  24. // Get handles for key bindings. Actual keys attached to these bindings will be registered during app start-up.
  25. mRotateObj = VirtualButton("RotateObj");
  26. mHorizontalAxis = VirtualAxis("Horizontal");
  27. mVerticalAxis = VirtualAxis("Vertical");
  28. // Determine initial yaw and pitch
  29. Quaternion rotation = SO()->getTransform().getRotation();
  30. Radian pitch, yaw, roll;
  31. (void)rotation.toEulerAngles(pitch, yaw, roll);
  32. mPitch = pitch;
  33. mYaw = yaw;
  34. }
  35. void ObjectRotator::update()
  36. {
  37. // Check if any movement or rotation keys are being held
  38. bool isRotating = gVirtualInput().isButtonHeld(mRotateObj);
  39. // If switch to or from rotation mode, hide or show the cursor
  40. if (isRotating != mLastButtonState)
  41. {
  42. if (isRotating)
  43. Cursor::instance().hide();
  44. else
  45. Cursor::instance().show();
  46. mLastButtonState = isRotating;
  47. }
  48. // If we're rotating, apply new pitch/yaw rotation values depending on the amount of rotation from the
  49. // vertical/horizontal axes.
  50. if (isRotating)
  51. {
  52. mYaw -= Degree(gVirtualInput().getAxisValue(mHorizontalAxis) * ROTATION_SPEED);
  53. mPitch -= Degree(gVirtualInput().getAxisValue(mVerticalAxis) * ROTATION_SPEED);
  54. mYaw = wrapAngle2(mYaw);
  55. mPitch = wrapAngle2(mPitch);
  56. Quaternion yRot;
  57. yRot.fromAxisAngle(Vector3::UNIT_Y, Radian(mYaw));
  58. Quaternion xRot;
  59. xRot.fromAxisAngle(Vector3::UNIT_X, Radian(mPitch));
  60. Quaternion camRot = yRot * xRot;
  61. camRot.normalize();
  62. SO()->setRotation(camRot);
  63. }
  64. }
  65. }