mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-17 15:38:11 +08:00
Merge branch 'master' into boundingBox
This commit is contained in:
commit
8fa81048c3
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "camera.h"
|
#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() : Camera(defaultOrigin(), defaultTarget()) {}
|
||||||
|
|
||||||
Camera::Camera(glm::vec3 position, glm::vec3 target) : _position(position) {
|
Camera::Camera(glm::vec3 position, glm::vec3 target) : _position(position) {
|
||||||
@ -46,4 +46,49 @@ void Camera::updateCameraState() {
|
|||||||
|
|
||||||
// Update up vector
|
// Update up vector
|
||||||
_up = glm::normalize(glm::cross(_right, _front));
|
_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();
|
||||||
|
}
|
||||||
|
|||||||
@ -3,9 +3,12 @@
|
|||||||
#include <GLM/glm.hpp>
|
#include <GLM/glm.hpp>
|
||||||
#include <GLM/ext/matrix_transform.hpp>
|
#include <GLM/ext/matrix_transform.hpp>
|
||||||
|
|
||||||
|
#define CAMERA_MAX_ZOOM 90.0f
|
||||||
|
#define CAMERA_MIN_ZOOM 1.0f
|
||||||
|
|
||||||
class Camera {
|
class Camera {
|
||||||
public:
|
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); }
|
inline glm::vec3 defaultTarget() { return glm::vec3(0.0f, 0.0f, 0.0f); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -16,11 +19,7 @@ private:
|
|||||||
glm::vec3 _up;
|
glm::vec3 _up;
|
||||||
float _yaw = 0.0f;
|
float _yaw = 0.0f;
|
||||||
float _pitch = 0.0f;
|
float _pitch = 0.0f;
|
||||||
float _zoom = 90.0f;
|
float _zoom = 45.0f;
|
||||||
|
|
||||||
private:
|
|
||||||
// Camera settings
|
|
||||||
float _moveStep = 1.0f;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// World settings
|
// World settings
|
||||||
@ -33,27 +32,36 @@ public:
|
|||||||
Camera(glm::vec3 position, float yaw, float pitch);
|
Camera(glm::vec3 position, float yaw, float pitch);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline float zoom() const { return _zoom; }
|
inline glm::vec3 front() const { return _front; }
|
||||||
|
inline float zoomVal() const { return _zoom; }
|
||||||
inline glm::mat4 viewMatrix();
|
inline glm::mat4 viewMatrix();
|
||||||
|
|
||||||
|
inline glm::vec3 position() const { return _position; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void move(glm::vec3 direction, float step);
|
inline void move(glm::vec2 offset);
|
||||||
inline void setPosition(glm::vec3 position);
|
inline void setPosition(glm::vec3 position);
|
||||||
inline void pitch(float deltaAngle);
|
inline void pitch(float deltaAngle);
|
||||||
inline void setPitch(float angle);
|
inline void setPitch(float angle);
|
||||||
inline void yaw(float deltaAngle);
|
inline void yaw(float deltaAngle);
|
||||||
inline void setYaw(float angle);
|
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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateCameraState();
|
void updateCameraState();
|
||||||
};
|
};
|
||||||
|
|
||||||
inline glm::mat4 Camera::viewMatrix() {
|
inline void Camera::move(glm::vec2 offset) {
|
||||||
return glm::lookAt(_position, _position + _front, _up);
|
// 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;
|
||||||
inline void Camera::move(glm::vec3 direction, float step) {
|
_position += worldSpaceOffset;
|
||||||
_position += direction * step;
|
|
||||||
updateCameraState();
|
updateCameraState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,3 +89,58 @@ inline void Camera::setYaw(float angle) {
|
|||||||
_yaw = angle;
|
_yaw = angle;
|
||||||
updateCameraState();
|
updateCameraState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
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();
|
_shaderProgram.ensureInitialized();
|
||||||
Logger::info("Shader Program initialized");
|
Logger::info("Shader Program initialized");
|
||||||
|
|
||||||
@ -83,20 +67,11 @@ void SceneViewer::initializeGL() {
|
|||||||
|
|
||||||
Model* backpackModel = new Model("D:/code/ComputerGraphic/SceneEditor/obj/nanosuit/nanosuit.obj");
|
Model* backpackModel = new Model("D:/code/ComputerGraphic/SceneEditor/obj/nanosuit/nanosuit.obj");
|
||||||
Logger::info("Model loaded");
|
Logger::info("Model loaded");
|
||||||
Renderable renderable(backpackModel);
|
Renderable backpack(backpackModel);
|
||||||
_objects.push_back(backpackModel);
|
_objects.push_back(backpack);
|
||||||
|
|
||||||
renderable.move(glm::vec3(100.0f, 0.0f, 0.0f));
|
|
||||||
renderable.rotate(glm::vec3(0, 1, 0), 3.1415926f/2);
|
|
||||||
renderable.check_boundary();
|
|
||||||
auto t1 = renderable.get_lower_boundary();
|
|
||||||
auto t2 = renderable.get_upper_boundary();
|
|
||||||
|
|
||||||
_camera.setPosition(glm::vec3(0.0f, 15.0f, 8.0f));
|
|
||||||
_camera.setYaw(-90.0f);
|
|
||||||
_camera.setPitch(-30.0f);
|
|
||||||
|
|
||||||
|
|
||||||
|
_camera.setPosition(glm::vec3(0.0f, 0.0f, 5.0f));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,11 +86,86 @@ void SceneViewer::paintGL() {
|
|||||||
|
|
||||||
// Set view and projection matrices
|
// Set view and projection matrices
|
||||||
glm::mat4 view = _camera.viewMatrix();
|
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("view", view);
|
||||||
_shaderProgram.setUniform("projection", projection);
|
_shaderProgram.setUniform("projection", projection);
|
||||||
|
|
||||||
for (auto object : _objects) {
|
for (auto object : _objects) {
|
||||||
object.render(_shaderProgram);
|
object.render(_shaderProgram);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
_shaderProgram.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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: {
|
||||||
|
// 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;
|
||||||
|
_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: {
|
||||||
|
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);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <qwidget.h>
|
#include <qwidget.h>
|
||||||
|
#include <qevent.h>
|
||||||
#include <qopenglfunctions.h>
|
#include <qopenglfunctions.h>
|
||||||
#include <QtOpenGLWidgets/qopenglwidget.h>
|
#include <QtOpenGLWidgets/qopenglwidget.h>
|
||||||
|
|
||||||
@ -17,17 +18,36 @@ class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// OpenGL section-------------------------------------
|
||||||
|
// List of objects currently in the scene
|
||||||
std::vector<Renderable> _objects;
|
std::vector<Renderable> _objects;
|
||||||
|
// Shader program for objects
|
||||||
ShaderProgram _shaderProgram = ShaderProgram::empty();
|
ShaderProgram _shaderProgram = ShaderProgram::empty();
|
||||||
VertexArrayObject _vao = VertexArrayObject::empty();
|
// Main camera
|
||||||
Camera _camera;
|
Camera _camera;
|
||||||
|
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;
|
||||||
|
Renderable* _selectedObject = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SceneViewer(QWidget* parent = 0);
|
SceneViewer(QWidget* parent = 0);
|
||||||
~SceneViewer();
|
~SceneViewer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// OpenGL functions
|
||||||
virtual void initializeGL() override;
|
virtual void initializeGL() override;
|
||||||
virtual void paintGL() override;
|
virtual void paintGL() override;
|
||||||
virtual void resizeGL(int w, int h) 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;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -25,6 +25,9 @@ Texture::Texture(TextureType type, std::string path) {
|
|||||||
OPENGL_FUNCTIONS->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
OPENGL_FUNCTIONS->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
OPENGL_FUNCTIONS->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
OPENGL_FUNCTIONS->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
// Set stbi to reverse the y-axis
|
||||||
|
stbi_set_flip_vertically_on_load(true);
|
||||||
|
|
||||||
// Load image, create texture and generate mipmaps
|
// Load image, create texture and generate mipmaps
|
||||||
int width, height, nrChannels;
|
int width, height, nrChannels;
|
||||||
unsigned char* data = stbi_load(path.c_str(), &width, &height, &nrChannels, 0);
|
unsigned char* data = stbi_load(path.c_str(), &width, &height, &nrChannels, 0);
|
||||||
|
|||||||
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