173 lines
3.5 KiB
C++
173 lines
3.5 KiB
C++
#include <scene/camera.hpp>
|
|
|
|
using namespace inferno;
|
|
|
|
Camera::Camera()
|
|
{
|
|
mProjMatrix = glm::perspective( glm::radians(FOV), 1.0f, 0.1f, 1000.0f );
|
|
|
|
Roll = 0.0f;
|
|
Pitch = 0.0f;
|
|
Yaw = 0.0f;
|
|
|
|
Position = {};
|
|
LookDirection = {};
|
|
|
|
mViewMatrix = {};
|
|
|
|
UpdateView();
|
|
}
|
|
|
|
Camera::Camera(int w, int h)
|
|
{
|
|
mProjMatrix = glm::perspective(glm::radians(FOV), (float)w / (float)h, 0.1f, 1000.0f);
|
|
|
|
Roll = 0.0f;
|
|
Pitch = 0.0f;
|
|
Yaw = 0.0f;
|
|
|
|
Position = {};
|
|
LookDirection = {};
|
|
|
|
mViewMatrix = {};
|
|
|
|
UpdateView();
|
|
}
|
|
|
|
void Camera::UpdateView()
|
|
{
|
|
// roll can be removed
|
|
glm::mat4 matRoll = glm::mat4(1.0f); //identity matrix
|
|
glm::mat4 matPitch = glm::mat4(1.0f);//identity matrix
|
|
glm::mat4 matYaw = glm::mat4(1.0f); //identity matrix
|
|
|
|
// roll, pitch and yaw
|
|
matRoll = glm::rotate(matRoll, Roll, glm::vec3(0.0f, 0.0f, 1.0f));
|
|
matPitch = glm::rotate(matPitch, Pitch, glm::vec3(1.0f, 0.0f, 0.0f));
|
|
matYaw = glm::rotate(matYaw, Yaw, glm::vec3( 0.0f, 1.0f, 0.0f));
|
|
|
|
glm::mat4 rotate = matRoll * matPitch * matYaw;
|
|
|
|
glm::mat4 translate = glm::mat4(1.0f);
|
|
translate = glm::translate(translate, -Position);
|
|
|
|
mViewMatrix = rotate * translate;
|
|
|
|
// Work out Look Vector
|
|
glm::mat4 inverseView = glm::inverse(mViewMatrix);
|
|
|
|
LookDirection.x = inverseView[2][0];
|
|
LookDirection.y = inverseView[2][1];
|
|
LookDirection.z = inverseView[2][2];
|
|
}
|
|
|
|
glm::mat4 Camera::GetViewMatrix()
|
|
{
|
|
return mViewMatrix;
|
|
}
|
|
|
|
glm::mat4 Camera::GetProjectionMatrix()
|
|
{
|
|
return mProjMatrix;
|
|
}
|
|
|
|
void Camera::UpdateProjection(int width, int height)
|
|
{
|
|
mViewport = {width, height};
|
|
mProjMatrix = glm::perspective(glm::radians(FOV), (float)width / (float)height, 0.1f, 1000.0f);
|
|
}
|
|
|
|
void Camera::UpdateProjection()
|
|
{
|
|
mProjMatrix = glm::perspective(glm::radians(FOV), mViewport.x / mViewport.y, 0.1f, 1000.0f);
|
|
}
|
|
|
|
void Camera::MoveCamera(uint8_t posDelta)
|
|
{
|
|
if (posDelta == 0) return;
|
|
|
|
// Rotate by camera direction
|
|
glm::vec3 delta(0.0f);
|
|
|
|
glm::mat2 rotate {
|
|
cos(Yaw), -sin(Yaw),
|
|
sin(Yaw), cos(Yaw)
|
|
};
|
|
|
|
glm::vec2 f(0.0, 1.0);
|
|
f = f * rotate;
|
|
|
|
if (posDelta & 0x80) {
|
|
delta.z -= f.y;
|
|
delta.x -= f.x;
|
|
}
|
|
if (posDelta & 0x20) {
|
|
delta.z += f.y;
|
|
delta.x += f.x;
|
|
}
|
|
if (posDelta & 0x40) {
|
|
delta.z += f.x;
|
|
delta.x += -f.y;
|
|
}
|
|
if (posDelta & 0x10) {
|
|
delta.z -= f.x;
|
|
delta.x -= -f.y;
|
|
}
|
|
if (posDelta & 0x8) {
|
|
delta.y += 1;
|
|
}
|
|
if (posDelta & 0x4) {
|
|
delta.y -= 1;
|
|
}
|
|
|
|
// get current view matrix
|
|
glm::mat4 mat = GetViewMatrix();
|
|
glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]);
|
|
glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]);
|
|
|
|
// forward vector must be negative to look forward.
|
|
// read :http://in2gpu.com/2015/05/17/view-matrix/
|
|
Position += delta * CameraSpeed;
|
|
|
|
// update the view matrix
|
|
UpdateView();
|
|
}
|
|
|
|
void Camera::MouseMoved(glm::vec2 mouseDelta)
|
|
{
|
|
if (glm::length(mouseDelta) == 0) return;
|
|
// note that yaw and pitch must be converted to radians.
|
|
// this is done in UpdateView() by glm::rotate
|
|
Yaw += MouseSensitivity * (mouseDelta.x / 100);
|
|
Pitch += MouseSensitivity * (mouseDelta.y / 100);
|
|
Pitch = glm::clamp<float>(Pitch, -M_PI / 2, M_PI / 2);
|
|
|
|
UpdateView();
|
|
}
|
|
|
|
void Camera::UpdatePosition(glm::vec3 position)
|
|
{
|
|
Position = position;
|
|
|
|
UpdateView();
|
|
}
|
|
|
|
void Camera::UpdateEulerLookDirection(float roll, float pitch, float yaw)
|
|
{
|
|
Roll = roll; Pitch = pitch; Yaw = yaw;
|
|
LookDirection.x = cos(Yaw) * cos(Pitch);
|
|
LookDirection.y = sin(Yaw) * cos(Pitch);
|
|
LookDirection.z = sin(Pitch);
|
|
|
|
UpdateView();
|
|
}
|
|
|
|
void Camera::UpdateLookDirection(glm::vec3 lookDirection)
|
|
{
|
|
LookDirection = lookDirection;
|
|
Pitch = asin(-lookDirection.y);
|
|
Yaw = atan2(lookDirection.x, lookDirection.z);
|
|
|
|
UpdateView();
|
|
}
|