36 m_yaw = atan2(forward.
GetX(), forward.
GetZ());
37 m_pitch = -asin(forward.
GetY());
39 static_cast<float>(m_pitchRange.GetX() *
D2R),
40 static_cast<float>(m_pitchRange.GetY() *
D2R));
49 UpdateInput(deltaTime);
50 UpdateCamera(deltaTime);
54 bool cursor_set = enabled ? SDL_ShowCursor() : SDL_HideCursor();
58void FirstPersonController::UpdateInput(
float deltaTime) {
60 SDL_GetRelativeMouseState(&x, &y);
72 static_cast<float>(m_pitchRange.
GetX() *
D2R),
73 static_cast<float>(m_pitchRange.
GetY() *
D2R));
76void FirstPersonController::UpdateCamera(
float deltaTime) {
81 Math::Quaternion combinedRotation = yawRotation * pitchRotation;
86 Math::Vector3D flatForward(forward.GetX(), 0.0f, forward.GetZ());
87 if (flatForward.Magnitude() > 0.001f) {
88 flatForward = flatForward.Normalized();
95 bool hasInput = inputDir.Magnitude() > 0.001f;
97 inputDir = inputDir.Normalized();
100 bool isGrounded = m_rigidbody && m_rigidbody->IsGrounded();
103 float currentMaxSpeed;
104 float effectiveAccel;
105 float effectiveBraking;
107 currentMaxSpeed = m_sprinting ? m_maxFlySpeed * m_flySprintMultiplier
109 float walkRef = (m_maxWalkSpeed > 0.001f) ? m_maxWalkSpeed : 1.0f;
110 float speedRatio = currentMaxSpeed / walkRef;
111 effectiveAccel = m_maxAcceleration * speedRatio;
112 effectiveBraking = m_brakingDeceleration * speedRatio;
114 currentMaxSpeed = m_sprinting ? m_maxWalkSpeed * m_sprintMultiplier
116 effectiveAccel = m_maxAcceleration;
117 if (!isGrounded) effectiveAccel *= m_airControl;
118 effectiveBraking = m_brakingDeceleration;
119 if (isGrounded) effectiveBraking *= m_groundFriction;
122 float speed = m_velocity.Magnitude();
125 m_velocity = m_velocity + inputDir * effectiveAccel * deltaTime;
127 float newSpeed = m_velocity.Magnitude();
128 if (newSpeed > currentMaxSpeed) {
129 m_velocity = m_velocity * (currentMaxSpeed / newSpeed);
133 float drop = effectiveBraking * deltaTime;
134 float newSpeed = speed - drop;
135 if (newSpeed < 0.0f) newSpeed = 0.0f;
136 m_velocity = m_velocity * (newSpeed / speed);
143 if (m_rigidbody && m_rigidbody->HadWallCollision()) {
144 Math::Vector3D wallNormal = m_rigidbody->GetWallNormal();
145 float dot = m_velocity.Dot(wallNormal);
147 m_velocity = m_velocity - wallNormal * dot;
153 if (m_flyVerticalInput > 0.001f || m_flyVerticalInput < -0.001f) {
154 m_flyVerticalVelocity += m_flyVerticalInput * effectiveAccel * deltaTime;
155 if (m_flyVerticalVelocity > currentMaxSpeed) m_flyVerticalVelocity = currentMaxSpeed;
156 if (m_flyVerticalVelocity < -currentMaxSpeed) m_flyVerticalVelocity = -currentMaxSpeed;
158 float vSpeed = std::fabs(m_flyVerticalVelocity);
159 if (vSpeed > 0.01f) {
160 float drop = effectiveBraking * deltaTime;
161 float newSpeed = vSpeed - drop;
162 if (newSpeed < 0.0f) newSpeed = 0.0f;
163 m_flyVerticalVelocity *= (newSpeed / vSpeed);
165 m_flyVerticalVelocity = 0.0f;
168 Math::Vector3D moveVel(m_velocity.GetX(),
169 m_flyVerticalVelocity,
171 camera->AddPosition(moveVel * deltaTime);
173 camera->AddPosition(m_velocity * deltaTime);
175 if (m_rigidbody && isGrounded) {
177 Math::Vector3D vel = m_rigidbody->GetVelocity();
178 vel = Math::Vector3D(vel.GetX(), m_jumpZVelocity, vel.GetZ());
179 m_rigidbody->SetVelocity(vel);
180 m_rigidbody->SetGrounded(
false);
187 Math::Vector3D lookTarget =
camera->GetPosition() + forward;
188 camera->SetLookTarget(lookTarget);
232 if (m_flying == flying)
return;
234 m_flyVerticalVelocity = 0.0f;
235 m_flyVerticalInput = 0.0f;
245 if (app) app->GetWindow().SetRelativeMouseMode(enabled);
254 m_yaw = atan2(forward.
GetX(), forward.
GetZ());
255 m_pitch = -asin(forward.
GetY());
257 static_cast<float>(m_pitchRange.GetX() *
D2R),
258 static_cast<float>(m_pitchRange.GetY() *
D2R));
static Application * GetInstance()
The one Application for this process, or null before construction.
virtual void SetEnabled(bool enabled)
Math::Vector3D translationInput
CameraController(GameObject *object)
virtual bool Initialize()
One-time setup, called after the component is attached and the owner is initialized.
static void UnregisterEvent(EventType type, std::string id)
Removes the single handler with matching id from type's handler list.
static std::string RegisterEventHandler(T *instance, void(T::*memberFunction)(const EventT &))
Registers a member-function handler bound to instance, returning an ID for later unregistration.
~FirstPersonController() override
void OnKeyPressed(const Events::Input::KeyPressedEvent &e)
Updates translation/sprint input state from a key-down event.
FirstPersonController(GameObject *object)
void Update(float deltaTime) override
bool Initialize() override
Grabs the sibling RigidbodyComponent and derives initial yaw/pitch from the camera's facing.
void SetEnabled(bool enabled) override
Toggles relative mouse mode and, when re-enabling, resets velocity and re-syncs yaw/pitch.
void OnKeyReleased(const Events::Input::KeyReleasedEvent &e)
Clears translation/sprint input state from a key-up event.
void ToggleCursor(bool enable) override
Shows or hides the OS cursor and, typically, toggles relative mouse mode.
void SetFlying(bool flying)
Switches between grounded movement and free-flight, resetting vertical velocity.
static Vector3D Forward()
constexpr const T & Clamp(const T &value, T min, T max)
Clamps value into [min, max].
Root namespace for everything the engine exposes.