initial commit-moved from vulkan_guide
This commit is contained in:
83
src/scene/camera.cpp
Normal file
83
src/scene/camera.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "camera.h"
|
||||
#include <glm/gtx/transform.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
void Camera::update()
|
||||
{
|
||||
glm::mat4 cameraRotation = getRotationMatrix();
|
||||
position += glm::vec3(cameraRotation * glm::vec4(velocity * moveSpeed, 0.f));
|
||||
}
|
||||
|
||||
void Camera::processSDLEvent(SDL_Event& e)
|
||||
{
|
||||
if (e.type == SDL_KEYDOWN) {
|
||||
// Camera uses -Z forward convention (right-handed)
|
||||
if (e.key.keysym.sym == SDLK_w) { velocity.z = -1; }
|
||||
if (e.key.keysym.sym == SDLK_s) { velocity.z = 1; }
|
||||
if (e.key.keysym.sym == SDLK_a) { velocity.x = -1; }
|
||||
if (e.key.keysym.sym == SDLK_d) { velocity.x = 1; }
|
||||
}
|
||||
|
||||
if (e.type == SDL_KEYUP) {
|
||||
if (e.key.keysym.sym == SDLK_w) { velocity.z = 0; }
|
||||
if (e.key.keysym.sym == SDLK_s) { velocity.z = 0; }
|
||||
if (e.key.keysym.sym == SDLK_a) { velocity.x = 0; }
|
||||
if (e.key.keysym.sym == SDLK_d) { velocity.x = 0; }
|
||||
}
|
||||
|
||||
if (e.type == SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_RIGHT) {
|
||||
rmbDown = true;
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
}
|
||||
if (e.type == SDL_MOUSEBUTTONUP && e.button.button == SDL_BUTTON_RIGHT) {
|
||||
rmbDown = false;
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
}
|
||||
|
||||
if (e.type == SDL_MOUSEMOTION && rmbDown) {
|
||||
// Mouse right (xrel > 0) turns view right with -Z-forward
|
||||
yaw += (float)e.motion.xrel * lookSensitivity; // axis = +Y
|
||||
// Mouse up (yrel < 0) looks up with -Z-forward
|
||||
pitch -= (float)e.motion.yrel * lookSensitivity;
|
||||
}
|
||||
|
||||
if (e.type == SDL_MOUSEWHEEL) {
|
||||
// Ctrl modifies FOV, otherwise adjust move speed
|
||||
const bool ctrl = (SDL_GetModState() & KMOD_CTRL) != 0;
|
||||
const int steps = e.wheel.y; // positive = wheel up
|
||||
if (ctrl) {
|
||||
// Wheel up -> zoom in (smaller FOV)
|
||||
fovDegrees -= steps * 2.0f;
|
||||
fovDegrees = std::clamp(fovDegrees, 30.0f, 110.0f);
|
||||
} else {
|
||||
// Exponential scale for pleasant feel
|
||||
float factor = std::pow(1.15f, (float)steps);
|
||||
moveSpeed = std::clamp(moveSpeed * factor, 0.001f, 5.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getViewMatrix()
|
||||
{
|
||||
// to create a correct model view, we need to move the world in opposite
|
||||
// direction to the camera
|
||||
// so we will create the camera model matrix and invert
|
||||
glm::mat4 cameraTranslation = glm::translate(glm::mat4(1.f), position);
|
||||
glm::mat4 cameraRotation = getRotationMatrix();
|
||||
return glm::inverse(cameraTranslation * cameraRotation);
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getRotationMatrix()
|
||||
{
|
||||
// fairly typical FPS style camera. we join the pitch and yaw rotations into
|
||||
// the final rotation matrix
|
||||
|
||||
glm::quat pitchRotation = glm::angleAxis(pitch, glm::vec3 { 1.f, 0.f, 0.f });
|
||||
// Yaw around +Y keeps mouse-right -> turn-right with -Z-forward
|
||||
glm::quat yawRotation = glm::angleAxis(yaw, glm::vec3 { 0.f, 1.f, 0.f });
|
||||
|
||||
return glm::toMat4(yawRotation) * glm::toMat4(pitchRotation);
|
||||
}
|
||||
Reference in New Issue
Block a user