core: Define VK_USE_PLATFORM_XCB_KHR before including vkd3d_utils.h.
[vkmodelviewer.git] / Core / CameraController.cpp
blob4f097243c395b4e63965da93eee042769c48b012
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // This code is licensed under the MIT License (MIT).
4 // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5 // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6 // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7 // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
8 //
9 // Developed by Minigraph
11 // Author: James Stanard
14 #include "pch.h"
15 #include "CameraController.h"
16 #include "Camera.h"
17 #include "GameInput.h"
19 using namespace Math;
20 using namespace GameCore;
22 CameraController::CameraController( Camera& camera, Vector3 worldUp ) : m_TargetCamera( camera )
24 m_WorldUp = Normalize(worldUp);
25 m_WorldNorth = Normalize(Cross(m_WorldUp, Vector3(kXUnitVector)));
26 m_WorldEast = Cross(m_WorldNorth, m_WorldUp);
28 m_HorizontalLookSensitivity = 2.0f;
29 m_VerticalLookSensitivity = 2.0f;
30 m_MoveSpeed = 1000.0f;
31 m_StrafeSpeed = 1000.0f;
32 m_MouseSensitivityX = 1.0f;
33 m_MouseSensitivityY = 1.0f;
35 m_CurrentPitch = Sin(Dot(camera.GetForwardVec(), m_WorldUp));
37 Vector3 forward = Normalize(Cross(m_WorldUp, camera.GetRightVec()));
38 m_CurrentHeading = ATan2(-Dot(forward, m_WorldEast), Dot(forward, m_WorldNorth));
40 m_FineMovement = false;
41 m_FineRotation = false;
42 m_Momentum = true;
44 m_LastYaw = 0.0f;
45 m_LastPitch = 0.0f;
46 m_LastForward = 0.0f;
47 m_LastStrafe = 0.0f;
48 m_LastAscent = 0.0f;
51 namespace Graphics
53 extern EnumVar DebugZoom;
56 void CameraController::Update( float deltaTime )
58 float timeScale = Graphics::DebugZoom == 0 ? 1.0f : Graphics::DebugZoom == 1 ? 0.5f : 0.25f;
60 if (GameInput::IsFirstPressed(GameInput::kLThumbClick) || GameInput::IsFirstPressed(GameInput::kKey_lshift))
61 m_FineMovement = !m_FineMovement;
63 if (GameInput::IsFirstPressed(GameInput::kRThumbClick))
64 m_FineRotation = !m_FineRotation;
66 float speedScale = (m_FineMovement ? 0.1f : 1.0f) * timeScale;
67 float panScale = (m_FineRotation ? 0.5f : 1.0f) * timeScale;
69 float yaw = GameInput::GetTimeCorrectedAnalogInput( GameInput::kAnalogRightStickX ) * m_HorizontalLookSensitivity * panScale;
70 float pitch = GameInput::GetTimeCorrectedAnalogInput( GameInput::kAnalogRightStickY ) * m_VerticalLookSensitivity * panScale;
71 float forward = m_MoveSpeed * speedScale * (
72 GameInput::GetTimeCorrectedAnalogInput( GameInput::kAnalogLeftStickY ) +
73 (GameInput::IsPressed( GameInput::kKey_w ) ? deltaTime : 0.0f) +
74 (GameInput::IsPressed( GameInput::kKey_s ) ? -deltaTime : 0.0f)
76 float strafe = m_StrafeSpeed * speedScale * (
77 GameInput::GetTimeCorrectedAnalogInput( GameInput::kAnalogLeftStickX ) +
78 (GameInput::IsPressed( GameInput::kKey_d ) ? deltaTime : 0.0f) +
79 (GameInput::IsPressed( GameInput::kKey_a ) ? -deltaTime : 0.0f)
81 float ascent = m_StrafeSpeed * speedScale * (
82 GameInput::GetTimeCorrectedAnalogInput( GameInput::kAnalogRightTrigger ) -
83 GameInput::GetTimeCorrectedAnalogInput( GameInput::kAnalogLeftTrigger ) +
84 (GameInput::IsPressed( GameInput::kKey_e ) ? deltaTime : 0.0f) +
85 (GameInput::IsPressed( GameInput::kKey_q ) ? -deltaTime : 0.0f)
88 if (m_Momentum)
90 ApplyMomentum(m_LastYaw, yaw, deltaTime);
91 ApplyMomentum(m_LastPitch, pitch, deltaTime);
92 ApplyMomentum(m_LastForward, forward, deltaTime);
93 ApplyMomentum(m_LastStrafe, strafe, deltaTime);
94 ApplyMomentum(m_LastAscent, ascent, deltaTime);
97 // don't apply momentum to mouse inputs
98 yaw += GameInput::GetAnalogInput(GameInput::kAnalogMouseX) * m_MouseSensitivityX;
99 pitch += GameInput::GetAnalogInput(GameInput::kAnalogMouseY) * m_MouseSensitivityY;
101 m_CurrentPitch += pitch;
102 m_CurrentPitch = XMMin( XM_PIDIV2, m_CurrentPitch);
103 m_CurrentPitch = XMMax(-XM_PIDIV2, m_CurrentPitch);
105 m_CurrentHeading -= yaw;
106 if (m_CurrentHeading > XM_PI)
107 m_CurrentHeading -= XM_2PI;
108 else if (m_CurrentHeading <= -XM_PI)
109 m_CurrentHeading += XM_2PI;
111 Matrix3 orientation = Matrix3(m_WorldEast, m_WorldUp, -m_WorldNorth) * Matrix3::MakeYRotation( m_CurrentHeading ) * Matrix3::MakeXRotation( m_CurrentPitch );
112 Vector3 position = orientation * Vector3( strafe, ascent, -forward ) + m_TargetCamera.GetPosition();
113 m_TargetCamera.SetTransform( AffineTransform( orientation, position ) );
114 m_TargetCamera.Update();
117 void CameraController::ApplyMomentum( float& oldValue, float& newValue, float deltaTime )
119 float blendedValue;
120 if (Abs(newValue) > Abs(oldValue))
121 blendedValue = Lerp(newValue, oldValue, Pow(0.6f, deltaTime * 60.0f));
122 else
123 blendedValue = Lerp(newValue, oldValue, Pow(0.8f, deltaTime * 60.0f));
124 oldValue = blendedValue;
125 newValue = blendedValue;