This commit is contained in:
2026-11-08 07:45:01 -05:00
commit 36e093f84c
1109 changed files with 254529 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
#ifndef CAMERA_CLASS_H
#define CAMERA_CLASS_H
#include <algorithm>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/quaternion.hpp>
#include <cmath>
#include <cstdlib>
#include "common.h"
#include "Window.h"
#include "t.h"
#include "tFunctions.h"
#include "shaderClass.h"
const glm::vec3 worldUp = { 0.0f, 1.0f, 0.0f };
// Default mouse sensitivity in cm of mouse travel per 360 degree turn.
inline float StartupCmPer360 = 16.0f;
inline float StartupMouseDpi = 800.0f;
class Camera {
public:
bool lockedcursor = true;
t t;
float yaw = 0.0f;
float pitch = 0.0f;
const float originalspeed = 0.08f;
float speed = 0.08f;
float sensitivity = 0.001f;
float FOV = 110.0f;
float screenshake = 0.0f; // 0 still to 1 shaking as hard as it does, wearing off over time
float shakeDecay = 1.2f; // of full strength lost a second of game time
glm::vec3 shakeMaxAngles = glm::vec3(0.08f, 0.08f, 0.04f); // radians of pitch, yaw and roll at full strength
Camera() {
if (StartupCmPer360 > 0.0f) SetSensitivityCm(StartupCmPer360, StartupMouseDpi);
}
// Turn sensitivity into "this many cm of mouse travel per full 360 degree turn" for a mouse
// of the given DPI (mouse counts per inch).
void SetSensitivityCm(float cmPer360, float dpi) {
sensitivity = 6.2831853f / (cmPer360 / 2.54f * dpi);
}
// Shakes the camera, amount of full strength on top of whatever shake there already is. Around 0.3 for a hit,
// 1 for something huge.
void AddScreenshake(float amount) {
screenshake = std::min(screenshake + amount, 1.0f);
}
void Matrix(float nearPlane, float farPlane, Shader& shader) {
shader.SetMat4("proj", GetProjectionMatrix(nearPlane, farPlane));
shader.SetMat4("view", GetViewMatrix());
shader.Set3F("viewPos", t.GetTranslation());
}
glm::mat4 GetViewMatrix() {
glm::vec3 front = t.GetFrontVector();
glm::vec3 up = t.GetUpVector();
if (screenshake > 0.0f) {
// Apply smooth shake offset stored in shakeOffset
glm::quat offsetRot = glm::quat(glm::vec3(
shakeOffset.x,
shakeOffset.y,
shakeOffset.z // roll
));
front = glm::normalize(offsetRot * front);
up = glm::normalize(offsetRot * up);
}
return glm::lookAt(t.GetTranslation(), t.GetTranslation() + front, up);
}
glm::mat4 GetProjectionMatrix(float nearPlane, float farPlane) {
// Quake Pro style: FOV is the horizontal angle on a 4:3 screen, so the vertical angle is fixed
// and wider windows/fullscreen reveal more to the sides instead of zooming in.
const float aspect = (float)window->width / (float)window->height;
const float vfov = 2.0f * atan(tan(glm::radians(FOV) * 0.5f) * 3.0f / 4.0f);
return glm::perspective(vfov, aspect, nearPlane, farPlane);
}
void Step(float dt) {
if (screenshake <= 0.0f) {
shakeOffset = glm::vec3(0.0f);
return;
}
// A smooth wobble on each axis, out of step with each other, scaled by how strong the shake still is
shakeTime += dt;
auto Wobble = [&](float seed) {
return (std::sin(shakeTime * 31.0f + seed) + std::sin(shakeTime * 57.3f + seed * 2.7f)) * 0.5f;
};
shakeOffset = shakeMaxAngles * screenshake * glm::vec3(Wobble(0.0f), Wobble(11.0f), Wobble(23.0f));
screenshake = std::max(screenshake - shakeDecay * dt, 0.0f);
}
// Back to looking where the mouse last had it, after something else has turned the camera
void RestoreLook() {
t.RotateToEulerAngles({ pitch, yaw, 0.0f });
t.NormalizeRotation();
}
void ProcessMouseMovement(float xoffset, float yoffset) {
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
pitch = glm::clamp(pitch, -glm::radians(85.0f), glm::radians(85.0f));
t.RotateToEulerAngles({ pitch, yaw, 0.0f });
t.NormalizeRotation();
}
private:
glm::vec3 shakeOffset = glm::vec3(0.0f); // this frame's turn from shaking, pitch, yaw and roll
float shakeTime = 0.0f; // runs the wobble along
};
#endif