2
0

BsCameraFlyer.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "BsCameraFlyer.h"
  2. #include "Math/BsVector3.h"
  3. #include "Utility/BsTime.h"
  4. #include "Math/BsMath.h"
  5. #include "Scene/BsSceneObject.h"
  6. #include "Components/BsCCamera.h"
  7. #include "Platform/BsCursor.h"
  8. namespace bs
  9. {
  10. const float CameraFlyer::START_SPEED = 40.0f;
  11. const float CameraFlyer::TOP_SPEED = 130.0f;
  12. const float CameraFlyer::ACCELERATION = 10.0f;
  13. const float CameraFlyer::FAST_MODE_MULTIPLIER = 2.0f;
  14. const float CameraFlyer::ROTATION_SPEED = 3.0f;
  15. /** Wraps an angle so it always stays in [0, 360) range. */
  16. Degree wrapAngle(Degree angle)
  17. {
  18. if (angle.valueDegrees() < -360.0f)
  19. angle += Degree(360.0f);
  20. if (angle.valueDegrees() > 360.0f)
  21. angle -= Degree(360.0f);
  22. return angle;
  23. }
  24. CameraFlyer::CameraFlyer(const HSceneObject& parent)
  25. :Component(parent)
  26. {
  27. // Set a name for the component, so we can find it later if needed
  28. setName("CameraFlyer");
  29. // Get handles for key bindings. Actual keys attached to these bindings will be registered during app start-up.
  30. mMoveForward = VirtualButton("Forward");
  31. mMoveBack = VirtualButton("Back");
  32. mMoveLeft = VirtualButton("Left");
  33. mMoveRight = VirtualButton("Right");
  34. mFastMove = VirtualButton("FastMove");
  35. mRotateCam = VirtualButton("RotateCam");
  36. mHorizontalAxis = VirtualAxis("Horizontal");
  37. mVerticalAxis = VirtualAxis("Vertical");
  38. }
  39. void CameraFlyer::update()
  40. {
  41. // Check if any movement or rotation keys are being held
  42. bool goingForward = gVirtualInput().isButtonHeld(mMoveForward);
  43. bool goingBack = gVirtualInput().isButtonHeld(mMoveBack);
  44. bool goingLeft = gVirtualInput().isButtonHeld(mMoveLeft);
  45. bool goingRight = gVirtualInput().isButtonHeld(mMoveRight);
  46. bool fastMove = gVirtualInput().isButtonHeld(mFastMove);
  47. bool camRotating = gVirtualInput().isButtonHeld(mRotateCam);
  48. // If switch to or from rotation mode, hide or show the cursor
  49. if (camRotating != mLastButtonState)
  50. {
  51. if (camRotating)
  52. Cursor::instance().hide();
  53. else
  54. Cursor::instance().show();
  55. mLastButtonState = camRotating;
  56. }
  57. // If camera is rotating, apply new pitch/yaw rotation values depending on the amount of rotation from the
  58. // vertical/horizontal axes.
  59. float frameDelta = gTime().getFrameDelta();
  60. if (camRotating)
  61. {
  62. mYaw += Degree(gVirtualInput().getAxisValue(mHorizontalAxis) * ROTATION_SPEED);
  63. mPitch += Degree(gVirtualInput().getAxisValue(mVerticalAxis) * ROTATION_SPEED);
  64. mYaw = wrapAngle(mYaw);
  65. mPitch = wrapAngle(mPitch);
  66. Quaternion yRot;
  67. yRot.fromAxisAngle(Vector3::UNIT_Y, Radian(mYaw));
  68. Quaternion xRot;
  69. xRot.fromAxisAngle(Vector3::UNIT_X, Radian(mPitch));
  70. Quaternion camRot = yRot * xRot;
  71. camRot.normalize();
  72. SO()->setRotation(camRot);
  73. }
  74. const Transform& tfrm = SO()->getTransform();
  75. // If the movement button is pressed, determine direction to move in
  76. Vector3 direction = Vector3::ZERO;
  77. if (goingForward) direction += tfrm.getForward();
  78. if (goingBack) direction -= tfrm.getForward();
  79. if (goingRight) direction += tfrm.getRight();
  80. if (goingLeft) direction -= tfrm.getRight();
  81. // If a direction is chosen, normalize it to determine final direction.
  82. if (direction.squaredLength() != 0)
  83. {
  84. direction.normalize();
  85. // Apply fast move multiplier if the fast move button is held.
  86. float multiplier = 1.0f;
  87. if (fastMove)
  88. multiplier = FAST_MODE_MULTIPLIER;
  89. // Calculate current speed of the camera
  90. mCurrentSpeed = Math::clamp(mCurrentSpeed + ACCELERATION * frameDelta, START_SPEED, TOP_SPEED);
  91. mCurrentSpeed *= multiplier;
  92. }
  93. else
  94. {
  95. mCurrentSpeed = 0.0f;
  96. }
  97. // If the current speed isn't too small, move the camera in the wanted direction
  98. float tooSmall = std::numeric_limits<float>::epsilon();
  99. if (mCurrentSpeed > tooSmall)
  100. {
  101. Vector3 velocity = direction * mCurrentSpeed;
  102. SO()->move(velocity * frameDelta);
  103. }
  104. }
  105. }