| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #include "BsCameraFlyer.h"
- #include "Math/BsVector3.h"
- #include "Utility/BsTime.h"
- #include "Math/BsMath.h"
- #include "Scene/BsSceneObject.h"
- #include "Components/BsCCamera.h"
- #include "Platform/BsCursor.h"
- namespace bs
- {
- const float CameraFlyer::START_SPEED = 40.0f;
- const float CameraFlyer::TOP_SPEED = 130.0f;
- const float CameraFlyer::ACCELERATION = 10.0f;
- const float CameraFlyer::FAST_MODE_MULTIPLIER = 2.0f;
- const float CameraFlyer::ROTATION_SPEED = 3.0f;
- /** Wraps an angle so it always stays in [0, 360) range. */
- Degree wrapAngle(Degree angle)
- {
- if (angle.valueDegrees() < -360.0f)
- angle += Degree(360.0f);
- if (angle.valueDegrees() > 360.0f)
- angle -= Degree(360.0f);
- return angle;
- }
- CameraFlyer::CameraFlyer(const HSceneObject& parent)
- :Component(parent)
- {
- // Set a name for the component, so we can find it later if needed
- setName("CameraFlyer");
- // Get handles for key bindings. Actual keys attached to these bindings will be registered during app start-up.
- mMoveForward = VirtualButton("Forward");
- mMoveBack = VirtualButton("Back");
- mMoveLeft = VirtualButton("Left");
- mMoveRight = VirtualButton("Right");
- mFastMove = VirtualButton("FastMove");
- mRotateCam = VirtualButton("RotateCam");
- mHorizontalAxis = VirtualAxis("Horizontal");
- mVerticalAxis = VirtualAxis("Vertical");
- }
- void CameraFlyer::update()
- {
- // Check if any movement or rotation keys are being held
- bool goingForward = gVirtualInput().isButtonHeld(mMoveForward);
- bool goingBack = gVirtualInput().isButtonHeld(mMoveBack);
- bool goingLeft = gVirtualInput().isButtonHeld(mMoveLeft);
- bool goingRight = gVirtualInput().isButtonHeld(mMoveRight);
- bool fastMove = gVirtualInput().isButtonHeld(mFastMove);
- bool camRotating = gVirtualInput().isButtonHeld(mRotateCam);
- // If switch to or from rotation mode, hide or show the cursor
- if (camRotating != mLastButtonState)
- {
- if (camRotating)
- Cursor::instance().hide();
- else
- Cursor::instance().show();
- mLastButtonState = camRotating;
- }
- // If camera is rotating, apply new pitch/yaw rotation values depending on the amount of rotation from the
- // vertical/horizontal axes.
- float frameDelta = gTime().getFrameDelta();
- if (camRotating)
- {
- mYaw += Degree(gVirtualInput().getAxisValue(mHorizontalAxis) * ROTATION_SPEED);
- mPitch += Degree(gVirtualInput().getAxisValue(mVerticalAxis) * ROTATION_SPEED);
- mYaw = wrapAngle(mYaw);
- mPitch = wrapAngle(mPitch);
- Quaternion yRot;
- yRot.fromAxisAngle(Vector3::UNIT_Y, Radian(mYaw));
- Quaternion xRot;
- xRot.fromAxisAngle(Vector3::UNIT_X, Radian(mPitch));
- Quaternion camRot = yRot * xRot;
- camRot.normalize();
- SO()->setRotation(camRot);
- }
- const Transform& tfrm = SO()->getTransform();
- // If the movement button is pressed, determine direction to move in
- Vector3 direction = Vector3::ZERO;
- if (goingForward) direction += tfrm.getForward();
- if (goingBack) direction -= tfrm.getForward();
- if (goingRight) direction += tfrm.getRight();
- if (goingLeft) direction -= tfrm.getRight();
- // If a direction is chosen, normalize it to determine final direction.
- if (direction.squaredLength() != 0)
- {
- direction.normalize();
- // Apply fast move multiplier if the fast move button is held.
- float multiplier = 1.0f;
- if (fastMove)
- multiplier = FAST_MODE_MULTIPLIER;
- // Calculate current speed of the camera
- mCurrentSpeed = Math::clamp(mCurrentSpeed + ACCELERATION * frameDelta, START_SPEED, TOP_SPEED);
- mCurrentSpeed *= multiplier;
- }
- else
- {
- mCurrentSpeed = 0.0f;
- }
- // If the current speed isn't too small, move the camera in the wanted direction
- float tooSmall = std::numeric_limits<float>::epsilon();
- if (mCurrentSpeed > tooSmall)
- {
- Vector3 velocity = direction * mCurrentSpeed;
- SO()->move(velocity * frameDelta);
- }
- }
- }
|