Merge pull request #1 from Linloir/camera_linloir

Update Camera
This commit is contained in:
Linloir 2022-12-13 20:43:01 +08:00 committed by GitHub
commit 061461332b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 9 deletions

View File

@ -4,7 +4,7 @@
#include "camera.h"
// If no default input, set camera to (1, 1, 1) looking at (0, 0, 0)
// If no default input, set camera to (0, 0, 1) looking at (0, 0, 0)
Camera::Camera() : Camera(defaultOrigin(), defaultTarget()) {}
Camera::Camera(glm::vec3 position, glm::vec3 target) : _position(position) {
@ -47,3 +47,48 @@ void Camera::updateCameraState() {
// Update up vector
_up = glm::normalize(glm::cross(_right, _front));
}
void Camera::rotate(glm::vec3 center, float deltaPitchAngle, float deltaYawAngle) {
if (deltaPitchAngle + _pitch > 89.0f) {
deltaPitchAngle = 89.0f - _pitch;
}
if (deltaPitchAngle + _pitch < -89.0f) {
deltaPitchAngle = -89.0f - _pitch;
}
// Get the normalized direction vector
glm::vec3 direction = glm::normalize(_position - center);
// Get the original distance from the center
float distance = glm::length(_position - center);
// Rotate the direction vector
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(deltaPitchAngle), _right);
rotation = glm::rotate(rotation, glm::radians(deltaYawAngle), _worldUp);
direction = glm::normalize(glm::vec3(rotation * glm::vec4(direction, 1.0f)));
// Get new position
_position = center + direction * distance;
// Update the position
_pitch += deltaPitchAngle;
_yaw -= deltaYawAngle;
updateCameraState();
}
void Camera::setRotation(glm::vec3 center, float pitchAngle, float yawAngle) {
if (pitchAngle > 89.0f) {
pitchAngle = 89.0f;
}
if (pitchAngle < -89.0f) {
pitchAngle = -89.0f;
}
// Get the direction vector
glm::vec3 direction = _position - center;
// Rotate the direction vector
glm::mat4 rotationMatrix = glm::rotate(glm::mat4(1.0f), glm::radians(pitchAngle), _right);
rotationMatrix = glm::rotate(rotationMatrix, glm::radians(yawAngle), _worldUp);
direction = glm::vec3(rotationMatrix * glm::vec4(direction, 1.0f));
// Update the position
_position = center + direction;
_pitch = pitchAngle;
_yaw = yawAngle;
updateCameraState();
}

View File

@ -8,7 +8,7 @@
class Camera {
public:
inline glm::vec3 defaultOrigin() { return glm::vec3(1.0f, 1.0f, 1.0f); }
inline glm::vec3 defaultOrigin() { return glm::vec3(0.0f, 0.0f, 1.0f); }
inline glm::vec3 defaultTarget() { return glm::vec3(0.0f, 0.0f, 0.0f); }
private:
@ -32,9 +32,12 @@ public:
Camera(glm::vec3 position, float yaw, float pitch);
public:
inline glm::vec3 front() const { return _front; }
inline float zoomVal() const { return _zoom; }
inline glm::mat4 viewMatrix();
inline glm::vec3 position() const { return _position; }
public:
inline void move(glm::vec2 offset);
inline void setPosition(glm::vec3 position);
@ -44,6 +47,8 @@ public:
inline void setYaw(float angle);
inline void rotate(float deltaPitchAngle, float deltaYawAngle);
inline void setRotation(float pitchAngle, float yawAngle);
void rotate(glm::vec3 center, float deltaPitchAngle, float deltaYawAngle);
void setRotation(glm::vec3 center, float pitchAngle, float yawAngle);
inline void zoom(float deltaZoom);
inline void setZoom(float zoom);
inline void push(float distance);
@ -87,7 +92,19 @@ inline void Camera::setYaw(float angle) {
inline void Camera::rotate(float deltaPitchAngle, float deltaYawAngle) {
_pitch += deltaPitchAngle;
if (_pitch > 89.0f) {
_pitch = 89.0f;
}
if (_pitch < -89.0f) {
_pitch = -89.0f;
}
_yaw += deltaYawAngle;
if (_yaw > 360.0f) {
_yaw -= 360.0f;
}
if (_yaw < 0.0f) {
_yaw += 360.0f;
}
updateCameraState();
}

View File

@ -70,9 +70,7 @@ void SceneViewer::initializeGL() {
Renderable backpack(backpackModel);
_objects.push_back(backpack);
_camera.setPosition(glm::vec3(0.0f, 0.0f, 3.0f));
_camera.setYaw(-90.0f);
_camera.setPitch(0.0f);
_camera.setPosition(glm::vec3(0.0f, 0.0f, 5.0f));
}
void SceneViewer::resizeGL(int w, int h) {
@ -93,6 +91,8 @@ void SceneViewer::paintGL() {
for (auto object : _objects) {
object.render(_shaderProgram);
}
_shaderProgram.unbind();
}
void SceneViewer::mousePressEvent(QMouseEvent* event) {
@ -122,8 +122,12 @@ void SceneViewer::mouseMoveEvent(QMouseEvent* event) {
float yoffset = _lastMousePosition.y() - event->y(); // reversed since y-coordinates go from bottom to top
float xmovement = xoffset * _cameraMovementSpeed;
float ymovement = yoffset * _cameraMovementSpeed;
Logger::debug("Camera movement: " + std::to_string(xmovement) + ", " + std::to_string(ymovement));
glm::vec3 cameraPrevPos = _camera.position();
_camera.move({ -xmovement, -ymovement });
glm::vec3 cameraNewPos = _camera.position();
_rotateCenter += cameraNewPos - cameraPrevPos;
Logger::debug("Camera moved to: " + std::to_string(_camera.position().x) + ", " + std::to_string(_camera.position().y) + ", " + std::to_string(_camera.position().z));
Logger::debug("New center: " + std::to_string(_rotateCenter.x) + ", " + std::to_string(_rotateCenter.y) + ", " + std::to_string(_rotateCenter.z));
break;
}
case Qt::MiddleButton: {
@ -134,8 +138,9 @@ void SceneViewer::mouseMoveEvent(QMouseEvent* event) {
float pitch = yoffset * _cameraRotationSpeed;
// Calculate yaw angle
float yaw = xoffset * _cameraRotationSpeed;
Logger::debug("Camera rotation: " + std::to_string(pitch) + ", " + std::to_string(yaw));
_camera.rotate(pitch, yaw);
_camera.rotate(_rotateCenter, pitch, -yaw);
Logger::debug("Camera rotated to: " + std::to_string(_camera.position().x) + ", " + std::to_string(_camera.position().y) + ", " + std::to_string(_camera.position().z));
Logger::debug("Center at: " + std::to_string(_rotateCenter.x) + ", " + std::to_string(_rotateCenter.y) + ", " + std::to_string(_rotateCenter.z));
break;
}
default: {
@ -155,6 +160,10 @@ void SceneViewer::wheelEvent(QWheelEvent* event) {
float wheelOffset = event->angleDelta().y();
Logger::debug("Wheel offset: " + std::to_string(wheelOffset));
_camera.push(wheelOffset * _cameraPushSpeed);
glm::vec3 cameraFront = _camera.front();
_rotateCenter += wheelOffset * _cameraPushSpeed * cameraFront;
Logger::debug("New camera position: " + std::to_string(_camera.position().x) + ", " + std::to_string(_camera.position().y) + ", " + std::to_string(_camera.position().z));
Logger::debug("New center position: " + std::to_string(_rotateCenter.x) + ", " + std::to_string(_rotateCenter.y) + ", " + std::to_string(_rotateCenter.z));
// Update the view
update();
}

View File

@ -28,6 +28,8 @@ private:
float _cameraMovementSpeed = 0.02f;
float _cameraRotationSpeed = 0.3f;
float _cameraPushSpeed = 0.02f;
// Rotate center
glm::vec3 _rotateCenter = glm::vec3(0.0f, 0.0f, 0.0f);
// User Interaction flags section---------------------
QPoint _lastMousePosition;