Added basic camera class with firs-person view (wip!)
This commit is contained in:
parent
830e9b75ea
commit
73e18a4c05
3 changed files with 194 additions and 1 deletions
136
base/camera.hpp
Normal file
136
base/camera.hpp
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* Basic camera class
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
|
||||||
|
*
|
||||||
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float fov;
|
||||||
|
float znear, zfar;
|
||||||
|
|
||||||
|
void updateViewMatrix()
|
||||||
|
{
|
||||||
|
glm::mat4 rotM = glm::mat4();
|
||||||
|
glm::mat4 transM;
|
||||||
|
|
||||||
|
rotM = glm::rotate(rotM, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
rotM = glm::rotate(rotM, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
rotM = glm::rotate(rotM, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
transM = glm::translate(glm::mat4(), position);
|
||||||
|
|
||||||
|
if (type == CameraType::firtsperson)
|
||||||
|
{
|
||||||
|
matrices.view = rotM * transM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
matrices.view = transM * rotM;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
enum CameraType { lookat, firtsperson };
|
||||||
|
CameraType type = CameraType::lookat;
|
||||||
|
|
||||||
|
glm::vec3 rotation = glm::vec3();
|
||||||
|
glm::vec3 position = glm::vec3();
|
||||||
|
|
||||||
|
float rotationSpeed = 1.0f;
|
||||||
|
float movementSpeed = 1.0f;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
glm::mat4 perspective;
|
||||||
|
glm::mat4 view;
|
||||||
|
} matrices;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool left = false;
|
||||||
|
bool right = false;
|
||||||
|
bool up = false;
|
||||||
|
bool down = false;
|
||||||
|
} keys;
|
||||||
|
|
||||||
|
bool moving()
|
||||||
|
{
|
||||||
|
return keys.left || keys.right || keys.up || keys.down;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPerspective(float fov, float aspect, float znear, float zfar)
|
||||||
|
{
|
||||||
|
this->fov = fov;
|
||||||
|
this->znear = znear;
|
||||||
|
this->zfar = zfar;
|
||||||
|
matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
|
||||||
|
};
|
||||||
|
|
||||||
|
void updateAspectRatio(float aspect)
|
||||||
|
{
|
||||||
|
matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRotation(glm::vec3 rotation)
|
||||||
|
{
|
||||||
|
this->rotation = rotation;
|
||||||
|
updateViewMatrix();
|
||||||
|
};
|
||||||
|
|
||||||
|
void rotate(glm::vec3 delta)
|
||||||
|
{
|
||||||
|
this->rotation += delta;
|
||||||
|
updateViewMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTranslation(glm::vec3 translation)
|
||||||
|
{
|
||||||
|
this->position = translation;
|
||||||
|
updateViewMatrix();
|
||||||
|
};
|
||||||
|
|
||||||
|
void translate(glm::vec3 delta)
|
||||||
|
{
|
||||||
|
this->position += delta;
|
||||||
|
updateViewMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(float deltaTime)
|
||||||
|
{
|
||||||
|
if (type == CameraType::firtsperson)
|
||||||
|
{
|
||||||
|
if (moving())
|
||||||
|
{
|
||||||
|
glm::vec3 camFront;
|
||||||
|
camFront.x = -cos(glm::radians(rotation.x)) * sin(glm::radians(rotation.y));
|
||||||
|
camFront.y = sin(glm::radians(rotation.x));
|
||||||
|
camFront.z = cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y));
|
||||||
|
camFront = glm::normalize(camFront);
|
||||||
|
|
||||||
|
float moveSpeed = deltaTime * movementSpeed;
|
||||||
|
|
||||||
|
if (keys.up)
|
||||||
|
position += camFront * moveSpeed;
|
||||||
|
if (keys.down)
|
||||||
|
position -= camFront * moveSpeed;
|
||||||
|
if (keys.left)
|
||||||
|
position -= glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed;
|
||||||
|
if (keys.right)
|
||||||
|
position += glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed;
|
||||||
|
|
||||||
|
updateViewMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -426,6 +426,11 @@ void VulkanExampleBase::renderLoop()
|
||||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||||
frameTimer = (float)tDiff / 1000.0f;
|
frameTimer = (float)tDiff / 1000.0f;
|
||||||
|
camera.update(frameTimer);
|
||||||
|
if (camera.moving())
|
||||||
|
{
|
||||||
|
viewChanged();
|
||||||
|
}
|
||||||
// Convert to clamped timer value
|
// Convert to clamped timer value
|
||||||
if (!paused)
|
if (!paused)
|
||||||
{
|
{
|
||||||
|
|
@ -489,6 +494,7 @@ void VulkanExampleBase::renderLoop()
|
||||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||||
frameTimer = tDiff / 1000.0f;
|
frameTimer = tDiff / 1000.0f;
|
||||||
|
camera.update(frameTimer);
|
||||||
// Convert to clamped timer value
|
// Convert to clamped timer value
|
||||||
if (!paused)
|
if (!paused)
|
||||||
{
|
{
|
||||||
|
|
@ -515,11 +521,13 @@ void VulkanExampleBase::renderLoop()
|
||||||
if (std::abs(gamePadState.axes.x) > deadZone)
|
if (std::abs(gamePadState.axes.x) > deadZone)
|
||||||
{
|
{
|
||||||
rotation.y += gamePadState.axes.x * 0.5f * rotationSpeed;
|
rotation.y += gamePadState.axes.x * 0.5f * rotationSpeed;
|
||||||
|
camera.rotate(glm::vec3(0.0f, gamePadState.axes.x * 0.5f, 0.0f));
|
||||||
updateView = true;
|
updateView = true;
|
||||||
}
|
}
|
||||||
if (std::abs(gamePadState.axes.y) > deadZone)
|
if (std::abs(gamePadState.axes.y) > deadZone)
|
||||||
{
|
{
|
||||||
rotation.x -= gamePadState.axes.y * 0.5f * rotationSpeed;
|
rotation.x -= gamePadState.axes.y * 0.5f * rotationSpeed;
|
||||||
|
camera.rotate(glm::vec3(gamePadState.axes.y * 0.5f, 0.0f, 0.0f));
|
||||||
updateView = true;
|
updateView = true;
|
||||||
}
|
}
|
||||||
// Zoom
|
// Zoom
|
||||||
|
|
@ -553,6 +561,7 @@ void VulkanExampleBase::renderLoop()
|
||||||
auto tEnd = std::chrono::high_resolution_clock::now();
|
auto tEnd = std::chrono::high_resolution_clock::now();
|
||||||
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
|
||||||
frameTimer = tDiff / 1000.0f;
|
frameTimer = tDiff / 1000.0f;
|
||||||
|
camera.update(frameTimer);
|
||||||
// Convert to clamped timer value
|
// Convert to clamped timer value
|
||||||
if (!paused)
|
if (!paused)
|
||||||
{
|
{
|
||||||
|
|
@ -1114,8 +1123,48 @@ void VulkanExampleBase::handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (camera.firtsperson)
|
||||||
|
{
|
||||||
|
switch (wParam)
|
||||||
|
{
|
||||||
|
case 0x57:
|
||||||
|
camera.keys.up = true;
|
||||||
|
break;
|
||||||
|
case 0x53:
|
||||||
|
camera.keys.down = true;
|
||||||
|
break;
|
||||||
|
case 0x41:
|
||||||
|
camera.keys.left = true;
|
||||||
|
break;
|
||||||
|
case 0x44:
|
||||||
|
camera.keys.right = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
keyPressed((uint32_t)wParam);
|
keyPressed((uint32_t)wParam);
|
||||||
break;
|
break;
|
||||||
|
case WM_KEYUP:
|
||||||
|
if (camera.firtsperson)
|
||||||
|
{
|
||||||
|
switch (wParam)
|
||||||
|
{
|
||||||
|
case 0x57:
|
||||||
|
camera.keys.up = false;
|
||||||
|
break;
|
||||||
|
case 0x53:
|
||||||
|
camera.keys.down = false;
|
||||||
|
break;
|
||||||
|
case 0x41:
|
||||||
|
camera.keys.left = false;
|
||||||
|
break;
|
||||||
|
case 0x44:
|
||||||
|
camera.keys.right = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
case WM_MBUTTONDOWN:
|
case WM_MBUTTONDOWN:
|
||||||
|
|
@ -1126,6 +1175,7 @@ void VulkanExampleBase::handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||||
{
|
{
|
||||||
short wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
|
short wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||||
zoom += (float)wheelDelta * 0.005f * zoomSpeed;
|
zoom += (float)wheelDelta * 0.005f * zoomSpeed;
|
||||||
|
camera.translate(glm::vec3(0.0f, 0.0f, (float)wheelDelta * 0.005f * zoomSpeed));
|
||||||
viewChanged();
|
viewChanged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1135,6 +1185,7 @@ void VulkanExampleBase::handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||||
int32_t posx = LOWORD(lParam);
|
int32_t posx = LOWORD(lParam);
|
||||||
int32_t posy = HIWORD(lParam);
|
int32_t posy = HIWORD(lParam);
|
||||||
zoom += (mousePos.y - (float)posy) * .005f * zoomSpeed;
|
zoom += (mousePos.y - (float)posy) * .005f * zoomSpeed;
|
||||||
|
camera.translate(glm::vec3(-0.0f, 0.0f, (mousePos.y - (float)posy) * .005f * zoomSpeed));
|
||||||
mousePos = glm::vec2((float)posx, (float)posy);
|
mousePos = glm::vec2((float)posx, (float)posy);
|
||||||
viewChanged();
|
viewChanged();
|
||||||
}
|
}
|
||||||
|
|
@ -1144,6 +1195,7 @@ void VulkanExampleBase::handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||||
int32_t posy = HIWORD(lParam);
|
int32_t posy = HIWORD(lParam);
|
||||||
rotation.x += (mousePos.y - (float)posy) * 1.25f * rotationSpeed;
|
rotation.x += (mousePos.y - (float)posy) * 1.25f * rotationSpeed;
|
||||||
rotation.y -= (mousePos.x - (float)posx) * 1.25f * rotationSpeed;
|
rotation.y -= (mousePos.x - (float)posx) * 1.25f * rotationSpeed;
|
||||||
|
camera.rotate(glm::vec3((mousePos.y - (float)posy), -(mousePos.x - (float)posx), 0.0f));
|
||||||
mousePos = glm::vec2((float)posx, (float)posy);
|
mousePos = glm::vec2((float)posx, (float)posy);
|
||||||
viewChanged();
|
viewChanged();
|
||||||
}
|
}
|
||||||
|
|
@ -1153,6 +1205,7 @@ void VulkanExampleBase::handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||||
int32_t posy = HIWORD(lParam);
|
int32_t posy = HIWORD(lParam);
|
||||||
cameraPos.x -= (mousePos.x - (float)posx) * 0.01f;
|
cameraPos.x -= (mousePos.x - (float)posx) * 0.01f;
|
||||||
cameraPos.y -= (mousePos.y - (float)posy) * 0.01f;
|
cameraPos.y -= (mousePos.y - (float)posy) * 0.01f;
|
||||||
|
camera.translate(glm::vec3(-(mousePos.x - (float)posx) * 0.01f, -(mousePos.y - (float)posy) * 0.01f, 0.0f));
|
||||||
viewChanged();
|
viewChanged();
|
||||||
mousePos.x = (float)posx;
|
mousePos.x = (float)posx;
|
||||||
mousePos.y = (float)posy;
|
mousePos.y = (float)posy;
|
||||||
|
|
@ -1673,6 +1726,8 @@ void VulkanExampleBase::windowResize()
|
||||||
updateTextOverlay();
|
updateTextOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
camera.updateAspectRatio((float)width / (float)height);
|
||||||
|
|
||||||
// Notify derived class
|
// Notify derived class
|
||||||
windowResized();
|
windowResized();
|
||||||
viewChanged();
|
viewChanged();
|
||||||
|
|
@ -1700,4 +1755,3 @@ void VulkanExampleBase::setupSwapChain()
|
||||||
{
|
{
|
||||||
swapChain.create(setupCmdBuffer, &width, &height);
|
swapChain.create(setupCmdBuffer, &width, &height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include "vulkanTextureLoader.hpp"
|
#include "vulkanTextureLoader.hpp"
|
||||||
#include "vulkanMeshLoader.hpp"
|
#include "vulkanMeshLoader.hpp"
|
||||||
#include "vulkantextoverlay.hpp"
|
#include "vulkantextoverlay.hpp"
|
||||||
|
#include "camera.hpp"
|
||||||
|
|
||||||
#define GAMEPAD_BUTTON_A 0x1000
|
#define GAMEPAD_BUTTON_A 0x1000
|
||||||
#define GAMEPAD_BUTTON_B 0x1001
|
#define GAMEPAD_BUTTON_B 0x1001
|
||||||
|
|
@ -160,6 +161,8 @@ public:
|
||||||
// Use to adjust mouse zoom speed
|
// Use to adjust mouse zoom speed
|
||||||
float zoomSpeed = 1.0f;
|
float zoomSpeed = 1.0f;
|
||||||
|
|
||||||
|
Camera camera;
|
||||||
|
|
||||||
glm::vec3 rotation = glm::vec3();
|
glm::vec3 rotation = glm::vec3();
|
||||||
glm::vec3 cameraPos = glm::vec3();
|
glm::vec3 cameraPos = glm::vec3();
|
||||||
glm::vec2 mousePos;
|
glm::vec2 mousePos;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue