Files
GP1-DirectX/project/src/Camera.cpp
2025-01-13 17:12:23 +01:00

221 lines
6.5 KiB
C++

//
// Created by Bram on 11/12/2024.
//
#include <iostream>
#include "Camera.h"
#include "GamePadController.h"
dae::Camera::Camera(const dae::Vector3 &_origin, float _fovAngle) :
origin{_origin},
fovAngle{_fovAngle} {
SetFOV(_fovAngle);
}
void dae::Camera::Initialize(float _fovAngle, dae::Vector3 _origin, float _aspect) {
fovAngle = _fovAngle;
fov = tanf((fovAngle * TO_RADIANS) / 2.f);
aspect = _aspect;
origin = _origin;
}
void dae::Camera::SetFOV(float _fovAngle) {
fovAngle = _fovAngle;
fov = tanf((fovAngle * TO_RADIANS) / 2.f);
}
void dae::Camera::CalculateViewMatrix() {
viewMatrix = Matrix::CreateLookAtLH(origin, origin + forward, Vector3::UnitY);
Matrix temp = viewMatrix;
invViewMatrix = temp.Inverse();
right = invViewMatrix.GetAxisX();
up = invViewMatrix.GetAxisY();
forward = invViewMatrix.GetAxisZ();
}
void dae::Camera::CalculateProjectionMatrix() {
//TODO W3
ProjectionMatrix = Matrix::CreatePerspectiveFovLH(fov, aspect, zNear, zFar);
//DirectX Implementation => https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovlh
}
void dae::Camera::Update(const dae::Timer *pTimer) {
const float deltaTime = pTimer->GetElapsed();
//Keyboard Input
const uint8_t *pKeyboardState = SDL_GetKeyboardState(nullptr);
Vector3 zDirection{0.f, 0.f, 0.f};
const Vector3 xDirection{0.f, 0.f, 0.f};
const Vector3 yDirection{0.f, 0.f, 0.f};
float MovementSpeed{10.f};
if (pKeyboardState[SDL_SCANCODE_LSHIFT]) {
MovementSpeed *= 2;
}
if (pKeyboardState[SDL_SCANCODE_W]) {
origin += forward * deltaTime * MovementSpeed;
}
if (pKeyboardState[SDL_SCANCODE_A]) {
origin -= right * deltaTime * MovementSpeed;
}
if (pKeyboardState[SDL_SCANCODE_S]) {
origin -= forward * deltaTime * MovementSpeed;
}
if (pKeyboardState[SDL_SCANCODE_D]) {
origin += right * deltaTime * MovementSpeed;
}
if (pKeyboardState[SDL_SCANCODE_E]) {
origin += up * deltaTime * MovementSpeed;
}
if (pKeyboardState[SDL_SCANCODE_Q]) {
origin -= up * deltaTime * MovementSpeed;
}
bool rightStickMoved = false;
constexpr float DEADZONE = 5000;
if (GamePadController::GetInstance().isAnyControllerConnected()) {
//Controller
float LeftStickX = GamePadController::GetInstance().GetAxis(PLAYER1, SDL_CONTROLLER_AXIS_LEFTX);
float LeftStickY = GamePadController::GetInstance().GetAxis(PLAYER1, SDL_CONTROLLER_AXIS_LEFTY);
float RightStickX = GamePadController::GetInstance().GetAxis(PLAYER1, SDL_CONTROLLER_AXIS_RIGHTX);
float RightStickY = GamePadController::GetInstance().GetAxis(PLAYER1, SDL_CONTROLLER_AXIS_RIGHTY);
if (std::abs(LeftStickX) > DEADZONE) {
float correctedValue = remap(LeftStickX, -32767.f, 32767.f, -1.f, 1.f);
origin += right * deltaTime * MovementSpeed * correctedValue;
}
if (std::abs(LeftStickY) > DEADZONE) {
float correctedValue = -remap(LeftStickY, -32767, 32767, -1, 1);
origin += forward * deltaTime * MovementSpeed * correctedValue;
}
//Look around Controller
float lookMultiplier = 2.f;
if (std::abs(RightStickX) > DEADZONE) {
float correctedValue = remap(RightStickX, -32767.f, 32767.f, -1.f, 1.f);
totalYaw += correctedValue * deltaTime * lookMultiplier;
rightStickMoved = true;
}
if (std::abs(RightStickY) > DEADZONE) {
float correctedValue = -remap(RightStickY, -32767.f, 32767.f, -1.f, 1.f);
totalPitch += correctedValue * deltaTime * lookMultiplier;
rightStickMoved = true;
}
//Controller Up and Down Triggers
float LeftTrigger = GamePadController::GetInstance().GetAxis(PLAYER1, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
float RightTrigger = GamePadController::GetInstance().GetAxis(PLAYER1, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
if (std::abs(LeftTrigger) > DEADZONE) {
float correctedValue = remap(LeftTrigger, 0.f, 32767.f, 0.f, 1.f);
origin -= up * deltaTime * MovementSpeed * correctedValue;
}
if (std::abs(RightTrigger) > DEADZONE) {
float correctedValue = remap(RightTrigger, 0.f, 32767.f, 0.f, 1.f);
origin += up * deltaTime * MovementSpeed * correctedValue;
}
}
//Mouse Input
bool mousePosChange{false};
int mouseX{}, mouseY{};
const uint32_t mouseState = SDL_GetRelativeMouseState(&mouseX, &mouseY);
mouseY *= -1;
if (mouseState == SDL_BUTTON_X1) //rmb
{
totalYaw += (static_cast<float>(mouseX) * mouseSens) * TO_RADIANS;
totalPitch += (static_cast<float>(mouseY) * mouseSens) * TO_RADIANS;
mousePosChange = true;
} else if (mouseState == SDL_BUTTON_LEFT) {
zDirection = forward.Normalized() * static_cast<float>(-mouseY);
totalYaw += static_cast<float>(mouseX) * mouseSens * TO_RADIANS;
mousePosChange = true;
} else if (mouseState == SDL_BUTTON_X2) //lmb + rmb
{
origin.y -= static_cast<float>(mouseY) / 2;
mousePosChange = true;
}
origin += ((zDirection + xDirection + yDirection) * cameraSpeed * deltaTime);
if (mousePosChange || rightStickMoved) {
const Matrix yawMatrix{Matrix::CreateRotationY(totalYaw)};
const Matrix pitchMatrix{Matrix::CreateRotationX(totalPitch)};
const Matrix finalRotation{pitchMatrix * yawMatrix};
forward = finalRotation.TransformVector(Vector3::UnitZ);
forward.Normalize();
}
//Update Matrices
CalculateViewMatrix();
CalculateProjectionMatrix();
}
dae::Matrix dae::Camera::GetViewProjectionMatrix() const {
return viewMatrix * ProjectionMatrix;
}
const dae::Vector3 & dae::Camera::GetPosition() const {
return origin;
}
const dae::Vector3 dae::Camera::GetRotation() const {
return {totalPitch, totalYaw, 0.f};
}
void dae::Camera::SetPosition(const dae::Vector3 &position) {
origin = position;
CalculateViewMatrix();
CalculateProjectionMatrix();
}
void dae::Camera::SetRotation(const dae::Vector3 &rotation) {
totalPitch = rotation.x;
totalYaw = rotation.y;
const Matrix yawMatrix{Matrix::CreateRotationY(totalYaw)};
const Matrix pitchMatrix{Matrix::CreateRotationX(totalPitch)};
const Matrix finalRotation{pitchMatrix * yawMatrix};
forward = finalRotation.TransformVector(Vector3::UnitZ);
forward.Normalize();
CalculateViewMatrix();
CalculateProjectionMatrix();
}