Camera movement
This commit is contained in:
parent
dfce02cd1c
commit
419ab8261d
85
src/main.cpp
85
src/main.cpp
|
@ -1,5 +1,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
@ -20,6 +21,10 @@
|
||||||
int width = 800;
|
int width = 800;
|
||||||
int height = 800;
|
int height = 800;
|
||||||
|
|
||||||
|
bool trapCursor = true;
|
||||||
|
|
||||||
|
std::function<void(GLFWwindow*, float, float)> handleMouseCallback;
|
||||||
|
|
||||||
void LogGlfwError(const char* message)
|
void LogGlfwError(const char* message)
|
||||||
{
|
{
|
||||||
const char* error;
|
const char* error;
|
||||||
|
@ -56,6 +61,63 @@ void FramebufferSizeCallback(GLFWwindow* window, int w, int h)
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||||
|
{
|
||||||
|
if (trapCursor)
|
||||||
|
handleMouseCallback(window, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyCallback(GLFWwindow* window, int key, int mode, int action, int mods)
|
||||||
|
{
|
||||||
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||||
|
{
|
||||||
|
trapCursor = !trapCursor;
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, (trapCursor ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL));
|
||||||
|
glfwSetCursorPos(window, width / 2, height / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleKeyboard(GLFWwindow* window, Camera& cam, float frametime)
|
||||||
|
{
|
||||||
|
static float movementSpeed = 4.5f;
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||||
|
cam.Move(cam.front * movementSpeed * frametime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||||
|
cam.Move(-cam.front * movementSpeed * frametime);
|
||||||
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||||
|
cam.Move(-cam.right * movementSpeed * frametime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||||
|
cam.Move(cam.right * movementSpeed * frametime);
|
||||||
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||||
|
cam.Move(glm::vec3(0.0f, 1.0f, 0.0f) * movementSpeed * frametime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||||
|
cam.Move(-glm::vec3(0.0f, 1.0f, 0.0f) * movementSpeed * frametime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleMouse(GLFWwindow* window, Camera* cam, float x, float y)
|
||||||
|
{
|
||||||
|
static const float sensitivity = 0.1f;
|
||||||
|
|
||||||
|
static float pitch = 0.0f;
|
||||||
|
static float yaw = -90.0f;
|
||||||
|
|
||||||
|
pitch += (height / 2 - y) * sensitivity;
|
||||||
|
yaw += (x - width / 2) * sensitivity;
|
||||||
|
|
||||||
|
if (pitch > 89.0f)
|
||||||
|
pitch = 89.0f;
|
||||||
|
else if (pitch < -89.0f)
|
||||||
|
pitch = -89.0f;
|
||||||
|
|
||||||
|
cam->SetRotation(glm::vec2(pitch, yaw));
|
||||||
|
|
||||||
|
glfwSetCursorPos(window, width / 2.0f, height / 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
// Initialize ImGui
|
// Initialize ImGui
|
||||||
|
@ -135,18 +197,27 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A camera
|
// A camera
|
||||||
Camera cam(glm::vec3(0.0f, 0.0f, 10.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
Camera cam(glm::vec3(0.0f, 0.0f, 10.0f), glm::vec2(0.0f, -90.0f));
|
||||||
|
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
glfwSetCursorPos(window, width / 2, height / 2);
|
||||||
|
handleMouseCallback = std::bind(HandleMouse, std::placeholders::_1, &cam, std::placeholders::_2, std::placeholders::_3);
|
||||||
|
glfwSetCursorPosCallback(window, CursorPosCallback);
|
||||||
|
glfwSetKeyCallback(window, KeyCallback);
|
||||||
|
|
||||||
// So that stuff isnt clipping through each other
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
|
||||||
|
float lastTime = glfwGetTime();
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
|
float currentTime = glfwGetTime();
|
||||||
|
HandleKeyboard(window, cam, currentTime - lastTime);
|
||||||
|
lastTime = currentTime;
|
||||||
|
|
||||||
float t = glfwGetTime();
|
float t = glfwGetTime();
|
||||||
|
|
||||||
static float PI = glm::pi<float>();
|
static float PI = glm::pi<float>();
|
||||||
|
@ -175,12 +246,6 @@ int main(int argc, char** argv)
|
||||||
ImGui::SliderFloat("zFar", &zFar, 10.0f, 100.0f);
|
ImGui::SliderFloat("zFar", &zFar, 10.0f, 100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::CollapsingHeader("Orbit"))
|
|
||||||
{
|
|
||||||
ImGui::SliderFloat("Speed", &orbitSpeed, 0.0f, 4 * PI, "%.2f rad/s");
|
|
||||||
ImGui::SliderFloat("Radius", &orbitRadius, 1.0f, 50.0f, "%.1f u");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
perspective = glm::perspective(fov, (float)width/(float)height, zNear, zFar);
|
perspective = glm::perspective(fov, (float)width/(float)height, zNear, zFar);
|
||||||
|
@ -188,8 +253,6 @@ int main(int argc, char** argv)
|
||||||
cubeTexture.Bind();
|
cubeTexture.Bind();
|
||||||
cubeShader.Use();
|
cubeShader.Use();
|
||||||
cubeShader.SetUniformMat4("projection", &perspective[0][0]);
|
cubeShader.SetUniformMat4("projection", &perspective[0][0]);
|
||||||
|
|
||||||
cam.SetPosition(orbitRadius * glm::vec3(cos(orbitSpeed * t), 0.0f, sin(orbitSpeed * t)));
|
|
||||||
cam.Use(cubeShader);
|
cam.Use(cubeShader);
|
||||||
|
|
||||||
for (Cube* cube : cubes)
|
for (Cube* cube : cubes)
|
||||||
|
|
|
@ -2,8 +2,20 @@
|
||||||
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
Camera::Camera(glm::vec3 position, glm::vec3 target) :
|
Camera::Camera(glm::vec3 position, glm::vec3 direction) :
|
||||||
position(position), target(target)
|
position(position), direction(direction)
|
||||||
|
{
|
||||||
|
CalculateCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::Camera(glm::vec3 position, glm::vec2 pitchYaw) :
|
||||||
|
position(position), direction(
|
||||||
|
glm::vec3(
|
||||||
|
cos(glm::radians(pitchYaw.y)) * cos(glm::radians(pitchYaw.x)),
|
||||||
|
sin(glm::radians(pitchYaw.x)),
|
||||||
|
sin(glm::radians(pitchYaw.y)) * cos(glm::radians(pitchYaw.x))
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
CalculateCamera();
|
CalculateCamera();
|
||||||
}
|
}
|
||||||
|
@ -14,18 +26,32 @@ void Camera::SetPosition(glm::vec3 newPos)
|
||||||
CalculateCamera();
|
CalculateCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::SetTarget(glm::vec3 newTarget)
|
|
||||||
{
|
|
||||||
target = newTarget;
|
|
||||||
CalculateCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::Move(glm::vec3 movement)
|
void Camera::Move(glm::vec3 movement)
|
||||||
{
|
{
|
||||||
position += movement;
|
position += movement;
|
||||||
CalculateCamera();
|
CalculateCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Camera::SetRotation(glm::vec2 pitchYaw)
|
||||||
|
{
|
||||||
|
direction = glm::vec3(
|
||||||
|
cos(glm::radians(pitchYaw.y)) * cos(glm::radians(pitchYaw.x)),
|
||||||
|
sin(glm::radians(pitchYaw.x)),
|
||||||
|
sin(glm::radians(pitchYaw.y)) * cos(glm::radians(pitchYaw.x))
|
||||||
|
);
|
||||||
|
CalculateCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::Rotate(glm::vec2 pitchYaw)
|
||||||
|
{
|
||||||
|
direction += glm::vec3(
|
||||||
|
cos(glm::radians(pitchYaw.y)) * cos(glm::radians(pitchYaw.x)),
|
||||||
|
sin(glm::radians(pitchYaw.x)),
|
||||||
|
sin(glm::radians(pitchYaw.y)) * cos(glm::radians(pitchYaw.x))
|
||||||
|
);
|
||||||
|
CalculateCamera();
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::Use(const Shader& program)
|
void Camera::Use(const Shader& program)
|
||||||
{
|
{
|
||||||
program.SetUniformMat4("view", &viewMatrix[0][0]);
|
program.SetUniformMat4("view", &viewMatrix[0][0]);
|
||||||
|
@ -33,9 +59,10 @@ void Camera::Use(const Shader& program)
|
||||||
|
|
||||||
void Camera::CalculateCamera()
|
void Camera::CalculateCamera()
|
||||||
{
|
{
|
||||||
direction = glm::normalize(target - position);
|
front = glm::normalize(direction);
|
||||||
right = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), direction));
|
right = glm::normalize(glm::cross(front, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||||
up = glm::cross(direction, right);
|
// right = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), front));
|
||||||
|
up = glm::cross(right, front);
|
||||||
|
|
||||||
viewMatrix = glm::lookAt(position, target, up);
|
viewMatrix = glm::lookAt(position, position + front, up);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,20 +8,24 @@ class Camera
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Camera() = default;
|
Camera() = default;
|
||||||
Camera(glm::vec3 position, glm::vec3 target);
|
Camera(glm::vec3 position, glm::vec3 direction);
|
||||||
|
Camera(glm::vec3 position, glm::vec2 pitchYaw);
|
||||||
|
|
||||||
void SetPosition(glm::vec3 newPos);
|
void SetPosition(glm::vec3 newPos);
|
||||||
void SetTarget(glm::vec3 newTarget);
|
|
||||||
|
|
||||||
void Move(glm::vec3 movement);
|
void Move(glm::vec3 movement);
|
||||||
|
|
||||||
|
void SetRotation(glm::vec2 pitchYaw);
|
||||||
|
void Rotate(glm::vec2 pitchYaw);
|
||||||
|
|
||||||
void Use(const Shader& program);
|
void Use(const Shader& program);
|
||||||
|
|
||||||
|
public:
|
||||||
|
glm::vec3 front, up, right;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CalculateCamera();
|
void CalculateCamera();
|
||||||
|
|
||||||
glm::vec3 position, target;
|
glm::vec3 position, direction;
|
||||||
glm::vec3 direction, up, right;
|
|
||||||
|
|
||||||
glm::mat4 viewMatrix;
|
glm::mat4 viewMatrix;
|
||||||
};
|
};
|
Loading…
Reference in a new issue