mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-16 23:18:12 +08:00
Add camera movement
- Add camera API - Add mouse event - Add member
This commit is contained in:
parent
f5f2247274
commit
069aca1cf2
@ -3,6 +3,9 @@
|
||||
#include <GLM/glm.hpp>
|
||||
#include <GLM/ext/matrix_transform.hpp>
|
||||
|
||||
#define CAMERA_MAX_ZOOM 90.0f
|
||||
#define CAMERA_MIN_ZOOM 1.0f
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
inline glm::vec3 defaultOrigin() { return glm::vec3(1.0f, 1.0f, 1.0f); }
|
||||
@ -16,11 +19,7 @@ private:
|
||||
glm::vec3 _up;
|
||||
float _yaw = 0.0f;
|
||||
float _pitch = 0.0f;
|
||||
float _zoom = 90.0f;
|
||||
|
||||
private:
|
||||
// Camera settings
|
||||
float _moveStep = 1.0f;
|
||||
float _zoom = 45.0f;
|
||||
|
||||
private:
|
||||
// World settings
|
||||
@ -33,27 +32,31 @@ public:
|
||||
Camera(glm::vec3 position, float yaw, float pitch);
|
||||
|
||||
public:
|
||||
inline float zoom() const { return _zoom; }
|
||||
inline float zoomVal() const { return _zoom; }
|
||||
inline glm::mat4 viewMatrix();
|
||||
|
||||
public:
|
||||
inline void move(glm::vec3 direction, float step);
|
||||
inline void move(glm::vec2 offset);
|
||||
inline void setPosition(glm::vec3 position);
|
||||
inline void pitch(float deltaAngle);
|
||||
inline void setPitch(float angle);
|
||||
inline void yaw(float deltaAngle);
|
||||
inline void setYaw(float angle);
|
||||
inline void rotate(float deltaPitchAngle, float deltaYawAngle);
|
||||
inline void setRotation(float pitchAngle, float yawAngle);
|
||||
inline void zoom(float deltaZoom);
|
||||
inline void setZoom(float zoom);
|
||||
inline void push(float distance);
|
||||
|
||||
private:
|
||||
void updateCameraState();
|
||||
};
|
||||
|
||||
inline glm::mat4 Camera::viewMatrix() {
|
||||
return glm::lookAt(_position, _position + _front, _up);
|
||||
}
|
||||
|
||||
inline void Camera::move(glm::vec3 direction, float step) {
|
||||
_position += direction * step;
|
||||
inline void Camera::move(glm::vec2 offset) {
|
||||
// Offset describe the movement on the xy plane in the camera's coordinate system
|
||||
// Should convert to the movement of position vector in world coordinate system
|
||||
glm::vec3 worldSpaceOffset = offset.x * _right + offset.y * _up;
|
||||
_position += worldSpaceOffset;
|
||||
updateCameraState();
|
||||
}
|
||||
|
||||
@ -81,3 +84,46 @@ inline void Camera::setYaw(float angle) {
|
||||
_yaw = angle;
|
||||
updateCameraState();
|
||||
}
|
||||
|
||||
inline void Camera::rotate(float deltaPitchAngle, float deltaYawAngle) {
|
||||
_pitch += deltaPitchAngle;
|
||||
_yaw += deltaYawAngle;
|
||||
updateCameraState();
|
||||
}
|
||||
|
||||
inline void Camera::setRotation(float pitchAngle, float yawAngle) {
|
||||
_pitch = pitchAngle;
|
||||
_yaw = yawAngle;
|
||||
updateCameraState();
|
||||
}
|
||||
|
||||
inline void Camera::zoom(float deltaZoom) {
|
||||
_zoom += deltaZoom;
|
||||
if (_zoom > CAMERA_MAX_ZOOM) {
|
||||
_zoom = CAMERA_MAX_ZOOM;
|
||||
}
|
||||
else if (_zoom < CAMERA_MIN_ZOOM) {
|
||||
_zoom = CAMERA_MIN_ZOOM;
|
||||
}
|
||||
updateCameraState();
|
||||
}
|
||||
|
||||
inline void Camera::setZoom(float zoom) {
|
||||
_zoom = zoom;
|
||||
if (_zoom > CAMERA_MAX_ZOOM) {
|
||||
_zoom = CAMERA_MAX_ZOOM;
|
||||
}
|
||||
else if (_zoom < CAMERA_MIN_ZOOM) {
|
||||
_zoom = CAMERA_MIN_ZOOM;
|
||||
}
|
||||
updateCameraState();
|
||||
}
|
||||
|
||||
inline void Camera::push(float distance) {
|
||||
_position += distance * _front;
|
||||
updateCameraState();
|
||||
}
|
||||
|
||||
inline glm::mat4 Camera::viewMatrix() {
|
||||
return glm::lookAt(_position, _position + _front, _up);
|
||||
}
|
||||
|
||||
@ -55,22 +55,6 @@ void SceneViewer::initializeGL() {
|
||||
|
||||
Logger::info("Currently running on OpenGL version: " + std::string((const char*)glGetString(GL_VERSION)));
|
||||
|
||||
_vao.ensureInitialized();
|
||||
Logger::info("Vertex Array Object initialized");
|
||||
|
||||
vector<Vertex> vertices = {
|
||||
{ { -0.5f, -0.5f, 0.0f } },
|
||||
{ { 0.5f, -0.5f, 0.0f } },
|
||||
{ { 0.0f, 0.5f, 0.0f } }
|
||||
};
|
||||
VertexBufferObject vbo(vertices);
|
||||
Logger::info("Vertex Buffer Object initialized");
|
||||
|
||||
_vao.bindVertexBufferObject(vbo);
|
||||
_vao.setVertexAttributePointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
|
||||
_vao.enableVertexAttribute(0);
|
||||
Logger::info("Vertex Buffer Object bound to Vertex Array Object");
|
||||
|
||||
_shaderProgram.ensureInitialized();
|
||||
Logger::info("Shader Program initialized");
|
||||
|
||||
@ -83,8 +67,8 @@ void SceneViewer::initializeGL() {
|
||||
|
||||
Model* backpackModel = new Model("E:\\Repositories\\CollegeProjects\\CGAssignments\\FinalProject\\Models\\backpack\\backpack.obj");
|
||||
Logger::info("Model loaded");
|
||||
Renderable renderable(backpackModel);
|
||||
_objects.push_back(backpackModel);
|
||||
Renderable backpack(backpackModel);
|
||||
_objects.push_back(backpack);
|
||||
|
||||
_camera.setPosition(glm::vec3(0.0f, 0.0f, 3.0f));
|
||||
_camera.setYaw(-90.0f);
|
||||
@ -102,11 +86,75 @@ void SceneViewer::paintGL() {
|
||||
|
||||
// Set view and projection matrices
|
||||
glm::mat4 view = _camera.viewMatrix();
|
||||
glm::mat4 projection = glm::perspective(glm::radians(_camera.zoom()), (float)width() / (float)height(), 0.1f, 100.0f);
|
||||
glm::mat4 projection = glm::perspective(glm::radians(_camera.zoomVal()), (float)width() / (float)height(), 0.1f, 100.0f);
|
||||
_shaderProgram.setUniform("view", view);
|
||||
_shaderProgram.setUniform("projection", projection);
|
||||
|
||||
for (auto object : _objects) {
|
||||
object.render(_shaderProgram);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneViewer::mousePressEvent(QMouseEvent* event) {
|
||||
Logger::debug("Mouse pressed at: " + std::to_string(event->x()) + ", " + std::to_string(event->y()));
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
// TODO: Hit test on objects
|
||||
}
|
||||
else {
|
||||
_lastMousePosition = event->pos();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneViewer::mouseMoveEvent(QMouseEvent* event) {
|
||||
Logger::debug("Mouse moved with offset: " + std::to_string(event->x() - _lastMousePosition.x()) + ", " + std::to_string(event->y() - _lastMousePosition.y()));
|
||||
// Check the type of button pressed
|
||||
switch (event->buttons()) {
|
||||
case Qt::LeftButton: {
|
||||
// Move the selected object
|
||||
if (_selectedObject != nullptr) {
|
||||
// TODO: move the selected object
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::RightButton: {
|
||||
// Move the camera
|
||||
float xoffset = event->x() - _lastMousePosition.x();
|
||||
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));
|
||||
_camera.move({ -xmovement, -ymovement });
|
||||
break;
|
||||
}
|
||||
case Qt::MiddleButton: {
|
||||
// Rotate the camera
|
||||
float xoffset = event->x() - _lastMousePosition.x();
|
||||
float yoffset = _lastMousePosition.y() - event->y(); // reversed since y-coordinates go from bottom to top
|
||||
// Calculate pitch angle
|
||||
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);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Logger::warning("Unknown mouse button input");
|
||||
Logger::warning("Mouse button: " + std::to_string(event->buttons()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Update the last mouse position
|
||||
_lastMousePosition = event->pos();
|
||||
// Update the view
|
||||
update();
|
||||
}
|
||||
|
||||
void SceneViewer::wheelEvent(QWheelEvent* event) {
|
||||
// Zoom in or out
|
||||
float wheelOffset = event->angleDelta().y();
|
||||
Logger::debug("Wheel offset: " + std::to_string(wheelOffset));
|
||||
_camera.push(wheelOffset * _cameraPushSpeed);
|
||||
// Update the view
|
||||
update();
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <qwidget.h>
|
||||
#include <qevent.h>
|
||||
#include <qopenglfunctions.h>
|
||||
#include <QtOpenGLWidgets/qopenglwidget.h>
|
||||
|
||||
@ -17,17 +18,34 @@ class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
// OpenGL section-------------------------------------
|
||||
// List of objects currently in the scene
|
||||
std::vector<Renderable> _objects;
|
||||
// Shader program for objects
|
||||
ShaderProgram _shaderProgram = ShaderProgram::empty();
|
||||
VertexArrayObject _vao = VertexArrayObject::empty();
|
||||
// Main camera
|
||||
Camera _camera;
|
||||
float _cameraMovementSpeed = 0.02f;
|
||||
float _cameraRotationSpeed = 0.3f;
|
||||
float _cameraPushSpeed = 0.02f;
|
||||
|
||||
// User Interaction flags section---------------------
|
||||
QPoint _lastMousePosition;
|
||||
Renderable* _selectedObject = nullptr;
|
||||
|
||||
public:
|
||||
SceneViewer(QWidget* parent = 0);
|
||||
~SceneViewer();
|
||||
|
||||
protected:
|
||||
// OpenGL functions
|
||||
virtual void initializeGL() override;
|
||||
virtual void paintGL() override;
|
||||
virtual void resizeGL(int w, int h) override;
|
||||
|
||||
// Mouse events
|
||||
virtual void mousePressEvent(QMouseEvent* event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent* event) override;
|
||||
virtual void wheelEvent(QWheelEvent* event) override;
|
||||
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.4 MiB After Width: | Height: | Size: 5.2 MiB |
Loading…
x
Reference in New Issue
Block a user