CameraFlyer.cpp 4.2 KB

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