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"
|
||||
|
||||
// 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) {
|
||||
@ -46,4 +46,49 @@ 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();
|
||||
}
|
||||
|
||||
@ -3,9 +3,12 @@
|
||||
#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); }
|
||||
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:
|
||||
@ -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,36 @@ public:
|
||||
Camera(glm::vec3 position, float yaw, float pitch);
|
||||
|
||||
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::vec3 position() const { return _position; }
|
||||
|
||||
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);
|
||||
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:
|
||||
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 +89,58 @@ inline void Camera::setYaw(float angle) {
|
||||
_yaw = angle;
|
||||
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)));
|
||||
|
||||
_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,20 +67,11 @@ void SceneViewer::initializeGL() {
|
||||
|
||||
Model* backpackModel = new Model("D:/code/ComputerGraphic/SceneEditor/obj/nanosuit/nanosuit.obj");
|
||||
Logger::info("Model loaded");
|
||||
Renderable renderable(backpackModel);
|
||||
_objects.push_back(backpackModel);
|
||||
Renderable backpack(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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
_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
|
||||
|
||||
#include <qwidget.h>
|
||||
#include <qevent.h>
|
||||
#include <qopenglfunctions.h>
|
||||
#include <QtOpenGLWidgets/qopenglwidget.h>
|
||||
|
||||
@ -17,17 +18,36 @@ 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;
|
||||
// Rotate center
|
||||
glm::vec3 _rotateCenter = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// 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;
|
||||
|
||||
};
|
||||
@ -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_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
|
||||
int width, height, nrChannels;
|
||||
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