improve camera: fix some bugs

This commit is contained in:
2025-12-12 23:00:12 +03:00
parent ef2a366e8e
commit 2215208c46
3 changed files with 110 additions and 106 deletions

View File

@@ -2,118 +2,126 @@
#include <camera/camera.hpp>
#include <glm/geometric.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
Camera::Camera(glm::vec3 pos, glm::vec3 up, float yaw, float pitch, float radialAngle, float speed, float sensitivity)
: pos(pos), worldUp(up), yaw(yaw), pitch(pitch), radialAngle(radialAngle), speed(speed), sensitivity(sensitivity), type(CameraType::FREE) {
}
Camera::Camera(glm::vec3 up, float coilCenter, float angularSpeed, float radialAngle, float sensitivity)
: worldUp(up), coilCenter(coilCenter), angularSpeed(angularSpeed), radialAngle(radialAngle), sensitivity(sensitivity), type(CameraType::SPINNING) {
updateCameraVectors();
}
Camera::Camera(
CameraType type, glm::vec3 pos, glm::vec3 up, float yaw,
float pitch, float radialAngle, float speed, float angularSpeed,
float sensitivity, float coilCenter, float segmentHeight
)
:
type(type), pos(pos), worldUp(up), yaw(yaw), pitch(pitch),
radialAngle(radialAngle), angularSpeed(angularSpeed),
speed(speed), sensitivity(sensitivity), coilCenter(coilCenter), segmentHeight(segmentHeight)
{}
glm::mat4 Camera::getViewMatrix() { return glm::lookAt(pos, pos + front, up); }
void Camera::processKeyboardInput(CameraMovement direction) {
if (lastTime == -1) {
lastTime = glfwGetTime();
}
float deltaTime = glfwGetTime() - lastTime;
float velocity = speed * deltaTime;
float angularVelocity = angularSpeed * deltaTime;
if (lastTime == -1) {
lastTime = glfwGetTime();
}
float deltaTime = glfwGetTime() - lastTime;
float velocity = speed * deltaTime;
float angularVelocity = angularSpeed * deltaTime;
switch (type) {
case CameraType::FREE: {
switch (direction) {
case CameraMovement::STOP:
break;
case CameraMovement::FORWARD:
pos += front * velocity;
break;
case CameraMovement::BACKWARD:
pos -= front * velocity;
break;
case CameraMovement::LEFT:
pos -= right * velocity;
break;
case CameraMovement::RIGHT:
pos += right * velocity;
break;
}
}
case CameraType::SPINNING: {
switch (direction) {
case CameraMovement::LEFT:
radialAngle += angularVelocity;
break;
case CameraMovement::RIGHT:
radialAngle -= angularVelocity;
break;
default:
break;
}
}
}
lastTime = glfwGetTime();
switch (type) {
case CameraType::FREE: {
switch (direction) {
case CameraMovement::STOP:
break;
case CameraMovement::FORWARD:
pos += front * velocity;
break;
case CameraMovement::BACKWARD:
pos -= front * velocity;
break;
case CameraMovement::LEFT:
pos -= right * velocity;
break;
case CameraMovement::RIGHT:
pos += right * velocity;
break;
}
break;
}
case CameraType::SPINNING: {
switch (direction) {
case CameraMovement::LEFT:
radialAngle += angularVelocity;
pos = glm::vec3(1.2 * coilCenter * cos(radialAngle), glm::degrees(radialAngle)/360. * segmentHeight + 3, 1.2*coilCenter * sin(radialAngle));
break;
case CameraMovement::RIGHT:
radialAngle -= angularVelocity;
pos = glm::vec3(1.2 * coilCenter * cos(radialAngle), glm::degrees(radialAngle)/360. * segmentHeight + 3, 1.2*coilCenter * sin(radialAngle));
break;
default:
break;
}
break;
}
}
lastTime = glfwGetTime();
// if (type == CameraType::SPINNING)
updateCameraVectors();
updateCameraVectors();
}
void Camera::processMouseInput(GLFWwindow *window, double mouseX, double mouseY) {
switch (type) {
case CameraType::FREE: {
float dX = 0, dY = 0;
if (prevX == -1 && prevY == -1) {
prevX = mouseX;
prevY = mouseY;
}
dX = sensitivity * (mouseX - prevX);
dY = -sensitivity * (mouseY - prevY);
switch (type) {
case CameraType::FREE: {
float dX = 0, dY = 0;
if (prevX == -1 && prevY == -1) {
prevX = mouseX;
prevY = mouseY;
}
dX = sensitivity * (mouseX - prevX);
dY = -sensitivity * (mouseY - prevY);
yaw += dX;
pitch += dY;
yaw += dX;
pitch += dY;
pitch = glm::clamp(pitch, (float)-89., (float)89.);
prevX = mouseX;
prevY = mouseY;
}
case CameraType::SPINNING: {
}
}
updateCameraVectors();
pitch = glm::clamp(pitch, (float)-89., (float)89.);
prevX = mouseX;
prevY = mouseY;
}
case CameraType::SPINNING: {
}
}
updateCameraVectors();
}
void Camera::setCameraType(CameraType type) {
this->type = type;
updateCameraVectors();
if (this->type == CameraType::FREE && type == CameraType::SPINNING) {
radialAngle = atan2(pos.z, pos.x);
}
this->type = type;
updateCameraVectors();
}
CameraType Camera::getCameraType() { return type; }
void Camera::updateCameraVectors() {
glm::vec3 front;
glm::vec3 front;
switch (type) {
case CameraType::FREE: {
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
break;
}
case CameraType::SPINNING: {
float x = (coilCenter + 10) * cos(radialAngle);
float z = (coilCenter + 10) * sin(radialAngle);
switch (type) {
case CameraType::FREE: {
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
break;
}
case CameraType::SPINNING: {
float x = coilCenter * cos(radialAngle);
float z = coilCenter * sin(radialAngle);
pos = glm::vec3(x, 0, z);
front = -pos;
break;
}
}
this->front = glm::normalize(front);
right = glm::normalize(glm::cross(front, worldUp));
up = glm::normalize(glm::cross(right, front));
front = -glm::vec3(x, glm::degrees(radialAngle)/360. * segmentHeight, z);
break;
}
}
this->front = glm::normalize(front);
right = glm::normalize(glm::cross(front, worldUp));
up = glm::normalize(glm::cross(right, front));
}

View File

@@ -27,11 +27,10 @@ class Camera {
float lastTime = -1;
float speed, angularSpeed, sensitivity;
float coilCenter;
float coilCenter, segmentHeight;
public:
Camera(glm::vec3 pos, glm::vec3 up, float yaw, float pitch, float radialAngle, float speed, float sensitivity);
Camera(glm::vec3 up, float coilCenter, float angularSpeed, float radialAngle, float sensitivity);
public:
Camera(CameraType type, glm::vec3 pos, glm::vec3 up, float yaw, float pitch, float radialAngle, float speed, float angularSpeed, float sensitivity, float coilCenter, float segmentHeight);
glm::mat4 getViewMatrix();
void processKeyboardInput(CameraMovement direction = CameraMovement::STOP);

View File

@@ -8,15 +8,11 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <coil/coil.hpp>
#include <coil/segment.hpp>
#include <utils/utils.hpp>
#include <camera/camera.hpp>
using std::cerr;
using std::cout;
using std::endl;
@@ -31,12 +27,13 @@ void framebufferSizeCallback(GLFWwindow *window, int width, int height) {
float coilRadius = 50;
float coilWidth = 10;
float segmentHeight = 10;
// Camera cam = Camera(glm::vec3(0., 0., 70), glm::vec3(0., 1.,0.),-89, 0, 0, 20, 0.1);
Camera cam = Camera(glm::vec3(0, 1, 0), coilRadius + (coilWidth / 2), 1, 0, 0.1);
Camera cam = Camera(CameraType::FREE, glm::vec3(0., 0., 70.),
glm::vec3(0., 1., 0.), -90, 0, 0, 40,
1, 0.1, coilRadius + (coilWidth / 2), segmentHeight);
void processClickInput(GLFWwindow* window, int key, int scancode, int action, int mods)
{
void processClickInput(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_R && action == GLFW_PRESS) {
CameraType type = cam.getCameraType();
++type;
@@ -46,10 +43,10 @@ void processClickInput(GLFWwindow* window, int key, int scancode, int action, in
}
void processPressInput(GLFWwindow *window) {
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
return;
}
}
CameraMovement dir;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
@@ -69,7 +66,7 @@ void processMousePosCallback(GLFWwindow *window, double deltaX, double deltaY) {
}
int main () {
Coil coil = Coil(2024, 1, 10, 2, coilRadius, coilWidth);
Coil coil = Coil(2024, 1, segmentHeight, 8, coilRadius, coilWidth);
srand(time(0));
glfwInit();