131 lines
3.9 KiB
C++
131 lines
3.9 KiB
C++
#include "PlayerController.hpp"
|
|
#include <algorithm>
|
|
|
|
PlayerController::PlayerController(float distance, float height, float speed)
|
|
: cameraDistance(distance), cameraHeight(height), moveSpeed(speed) {
|
|
|
|
camera.position = {0, cameraHeight, cameraDistance};
|
|
camera.target = {0, 0, 0};
|
|
camera.up = {0, 1, 0};
|
|
camera.fovy = 45.0f;
|
|
camera.projection = CAMERA_PERSPECTIVE;
|
|
|
|
updateCameraPosition();
|
|
}
|
|
|
|
void PlayerController::update(float deltaTime) {
|
|
handleCameraRotation();
|
|
handleCameraZoom();
|
|
updateCameraPosition();
|
|
}
|
|
|
|
void PlayerController::setPlayerPosition(const Vector3& position) {
|
|
playerPosition = position;
|
|
}
|
|
|
|
Vector3 PlayerController::getMoveInput() const {
|
|
Vector3 moveDir = {0, 0, 0};
|
|
|
|
// Forward/Backward movement (W/S) - relative to camera direction
|
|
if (IsKeyDown(KEY_W)) {
|
|
moveDir.x += sinf(cameraYaw);
|
|
moveDir.z += cosf(cameraYaw);
|
|
}
|
|
if (IsKeyDown(KEY_S)) {
|
|
moveDir.x -= sinf(cameraYaw);
|
|
moveDir.z -= cosf(cameraYaw);
|
|
}
|
|
|
|
// Strafe left/right (Q/E) - perpendicular to camera direction (inverted)
|
|
if (IsKeyDown(KEY_Q)) {
|
|
moveDir.x += cosf(cameraYaw);
|
|
moveDir.z -= sinf(cameraYaw);
|
|
}
|
|
if (IsKeyDown(KEY_E)) {
|
|
moveDir.x -= cosf(cameraYaw);
|
|
moveDir.z += sinf(cameraYaw);
|
|
}
|
|
|
|
// Also support A/D for strafing as alternative (inverted)
|
|
if (IsKeyDown(KEY_A)) {
|
|
moveDir.x += cosf(cameraYaw);
|
|
moveDir.z -= sinf(cameraYaw);
|
|
}
|
|
if (IsKeyDown(KEY_D)) {
|
|
moveDir.x -= cosf(cameraYaw);
|
|
moveDir.z += sinf(cameraYaw);
|
|
}
|
|
|
|
// Normalize movement vector if it has length
|
|
float length = sqrtf(moveDir.x * moveDir.x + moveDir.z * moveDir.z);
|
|
if (length > 0.0f) {
|
|
moveDir.x /= length;
|
|
moveDir.z /= length;
|
|
}
|
|
|
|
return moveDir;
|
|
}
|
|
|
|
void PlayerController::updateCameraPosition() {
|
|
// Update camera target to player position
|
|
camera.target = playerPosition;
|
|
|
|
// Calculate camera position based on spherical coordinates
|
|
float cosYaw = cosf(cameraYaw);
|
|
float sinYaw = sinf(cameraYaw);
|
|
float cosPitch = cosf(cameraPitch);
|
|
float sinPitch = sinf(cameraPitch);
|
|
|
|
camera.position.x = playerPosition.x - sinYaw * cosPitch * cameraDistance;
|
|
camera.position.y = playerPosition.y + sinPitch * cameraDistance;
|
|
camera.position.z = playerPosition.z - cosYaw * cosPitch * cameraDistance;
|
|
}
|
|
|
|
void PlayerController::handleCameraRotation() {
|
|
// Check for right mouse button
|
|
if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) {
|
|
if (!isRightMouseDown) {
|
|
// Just pressed - store initial mouse position
|
|
isRightMouseDown = true;
|
|
lastMousePos = GetMousePosition();
|
|
DisableCursor();
|
|
}
|
|
|
|
// Get mouse delta
|
|
Vector2 currentMousePos = GetMousePosition();
|
|
Vector2 mouseDelta = {
|
|
currentMousePos.x - lastMousePos.x,
|
|
currentMousePos.y - lastMousePos.y
|
|
};
|
|
|
|
// Update camera angles (inverted Y-axis)
|
|
const float sensitivity = 0.003f;
|
|
cameraYaw -= mouseDelta.x * sensitivity;
|
|
cameraPitch += mouseDelta.y * sensitivity;
|
|
|
|
// Clamp pitch to prevent camera flipping
|
|
cameraPitch = std::clamp(cameraPitch, -1.4f, 1.4f);
|
|
|
|
// Wrap yaw
|
|
if (cameraYaw > PI * 2.0f) cameraYaw -= PI * 2.0f;
|
|
if (cameraYaw < 0.0f) cameraYaw += PI * 2.0f;
|
|
|
|
lastMousePos = currentMousePos;
|
|
} else {
|
|
if (isRightMouseDown) {
|
|
// Just released
|
|
isRightMouseDown = false;
|
|
EnableCursor();
|
|
}
|
|
}
|
|
}
|
|
|
|
void PlayerController::handleCameraZoom() {
|
|
// Handle mouse wheel zoom
|
|
float wheel = GetMouseWheelMove();
|
|
if (wheel != 0) {
|
|
cameraDistance -= wheel * 2.0f;
|
|
// Clamp zoom distance
|
|
cameraDistance = std::clamp(cameraDistance, 5.0f, 50.0f);
|
|
}
|
|
} |