readme
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user