mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-18 07:58:11 +08:00
[CORE][FIX] Fix placing (partial)
- Change placing calculation logic (without sticking) - Sticking still not working
This commit is contained in:
parent
cd75d7a83d
commit
e1cfd3932c
@ -20,6 +20,7 @@ public:
|
|||||||
inline glm::vec3 bottomControlPoint() const { return _bottomControlPoint; }
|
inline glm::vec3 bottomControlPoint() const { return _bottomControlPoint; }
|
||||||
inline glm::vec3 topControlPoint() const { return _topControlPoint; }
|
inline glm::vec3 topControlPoint() const { return _topControlPoint; }
|
||||||
inline glm::vec3 bottomCenterPoint() const;
|
inline glm::vec3 bottomCenterPoint() const;
|
||||||
|
inline glm::vec3 centerPoint() const;
|
||||||
|
|
||||||
bool hit(const Ray& ray) const;
|
bool hit(const Ray& ray) const;
|
||||||
|
|
||||||
@ -29,3 +30,7 @@ public:
|
|||||||
inline glm::vec3 Boundary::bottomCenterPoint() const {
|
inline glm::vec3 Boundary::bottomCenterPoint() const {
|
||||||
return glm::vec3((_bottomControlPoint.x + _topControlPoint.x) / 2.0f, _bottomControlPoint.y, (_bottomControlPoint.z + _topControlPoint.z) / 2.0f);
|
return glm::vec3((_bottomControlPoint.x + _topControlPoint.x) / 2.0f, _bottomControlPoint.y, (_bottomControlPoint.z + _topControlPoint.z) / 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline glm::vec3 Boundary::centerPoint() const {
|
||||||
|
return glm::vec3((_bottomControlPoint.x + _topControlPoint.x) / 2.0f, (_bottomControlPoint.y + _topControlPoint.y) / 2.0f, (_bottomControlPoint.z + _topControlPoint.z) / 2.0f);
|
||||||
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
Logger::LogLevel Logger::_level = Logger::LogLevel::LOCALLOGLEVEL;
|
Logger::LogLevel Logger::_level = Logger::LogLevel::LOCALLOGLEVEL;
|
||||||
|
std::string Logger::_previous = "";
|
||||||
|
|
||||||
void Logger::setLogLevel(LogLevel level) {
|
void Logger::setLogLevel(LogLevel level) {
|
||||||
_level = level;
|
_level = level;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define LOCALLOGLEVEL INFO
|
#define LOCALLOGLEVEL DEBUG
|
||||||
|
|
||||||
class Logger {
|
class Logger {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -190,13 +190,14 @@ void Model::render(const ShaderProgram& shader) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HitRecord Model::hit(const Ray& ray, const glm::mat4& modelMatrix) const {
|
HitRecord Model::hit(const Ray& ray, const glm::mat4& modelMatrix) const {
|
||||||
|
HitRecord record = HitRecord();
|
||||||
for (unsigned int i = 0; i < _meshes.size(); i++) {
|
for (unsigned int i = 0; i < _meshes.size(); i++) {
|
||||||
HitRecord hitRecord = _meshes[i].hit(ray, modelMatrix);
|
HitRecord hitRecord = _meshes[i].hit(ray, modelMatrix);
|
||||||
if (hitRecord.hitted()) {
|
if (hitRecord.hitted() && hitRecord.t() < record.t()) {
|
||||||
return hitRecord;
|
record = hitRecord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HitRecord();
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
Model* Model::copyToCurrentContext() const {
|
Model* Model::copyToCurrentContext() const {
|
||||||
|
|||||||
@ -448,14 +448,24 @@ void ModelSetter::update(Renderable* object) {
|
|||||||
_rotateY->setEnabled();
|
_rotateY->setEnabled();
|
||||||
_rotateZ->setEnabled();
|
_rotateZ->setEnabled();
|
||||||
}
|
}
|
||||||
// Extract x, y, z axis rotation from rotation matrix
|
// Extract x, y, z axis rotation degree from rotation matrix
|
||||||
glm::mat4 rotationMatrix = object->rotation();
|
glm::quat quat(object->rotation());
|
||||||
float rotateX = glm::degrees(glm::asin(-rotationMatrix[1][2]));
|
glm::vec3 euler = glm::eulerAngles(quat);
|
||||||
float rotateY = glm::degrees(glm::atan(rotationMatrix[0][2] / rotationMatrix[2][2]));
|
float x = glm::degrees(euler.x);
|
||||||
float rotateZ = glm::degrees(glm::atan(rotationMatrix[1][0] / rotationMatrix[1][1]));
|
float y = glm::degrees(euler.y);
|
||||||
_rotateX->setValue(rotateX);
|
float z = glm::degrees(euler.z);
|
||||||
_rotateY->setValue(rotateY);
|
if (x < 0) {
|
||||||
_rotateZ->setValue(rotateZ);
|
x += 360;
|
||||||
|
}
|
||||||
|
if (y < 0) {
|
||||||
|
y += 360;
|
||||||
|
}
|
||||||
|
if (z < 0) {
|
||||||
|
z += 360;
|
||||||
|
}
|
||||||
|
_rotateX->setValue(x);
|
||||||
|
_rotateY->setValue(y);
|
||||||
|
_rotateZ->setValue(z);
|
||||||
|
|
||||||
if (_object == nullptr) {
|
if (_object == nullptr) {
|
||||||
_lightSwitch->setEnabled();
|
_lightSwitch->setEnabled();
|
||||||
|
|||||||
@ -31,11 +31,11 @@ void Renderable::setPosition(glm::vec3 position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderable::rotate(glm::vec3 axis, float deltaAngle) {
|
void Renderable::rotate(glm::vec3 axis, float deltaAngle) {
|
||||||
_rotation = glm::rotate(_rotation, deltaAngle, axis);
|
_rotation = glm::rotate(_rotation, glm::radians(deltaAngle), axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderable::setRotation(glm::vec3 axis, float angle) {
|
void Renderable::setRotation(glm::vec3 axis, float angle) {
|
||||||
_rotation = glm::rotate(glm::mat4(1.0f), angle, axis);
|
_rotation = glm::rotate(glm::mat4(1.0f), glm::radians(angle), axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderable::scale(float deltaScale) {
|
void Renderable::scale(float deltaScale) {
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <GLM/glm.hpp>
|
#include <GLM/glm.hpp>
|
||||||
#include <GLM/ext/matrix_transform.hpp>
|
#include <GLM/ext/matrix_transform.hpp>
|
||||||
|
#include <GLM/gtx/quaternion.hpp>
|
||||||
|
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "illuminer.h"
|
#include "illuminer.h"
|
||||||
@ -35,6 +36,7 @@ public:
|
|||||||
glm::vec3 position() const { return _position; }
|
glm::vec3 position() const { return _position; }
|
||||||
glm::mat4 rotation() const { return _rotation; }
|
glm::mat4 rotation() const { return _rotation; }
|
||||||
glm::vec3 scaleVal() const { return _scale; }
|
glm::vec3 scaleVal() const { return _scale; }
|
||||||
|
Model* model() const { return _model; }
|
||||||
|
|
||||||
void setModel(Model* model);
|
void setModel(Model* model);
|
||||||
void move(glm::vec3 deltaVec);
|
void move(glm::vec3 deltaVec);
|
||||||
@ -61,9 +63,23 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline glm::mat4 Renderable::modelMatrix() const {
|
inline glm::mat4 Renderable::modelMatrix() const {
|
||||||
|
// Calculate rotate direction and angle from rotation matrix _rotation without glm
|
||||||
|
glm::vec3 axis;
|
||||||
|
float angle;
|
||||||
|
glm::quat quat(_rotation);
|
||||||
|
glm::vec3 axisAngle = glm::axis(quat);
|
||||||
|
axis = glm::normalize(axisAngle);
|
||||||
|
angle = glm::angle(quat);
|
||||||
|
//float rotateX = glm::degrees(glm::asin(-_rotation[1][2]));
|
||||||
|
//float rotateY = glm::degrees(glm::atan(_rotation[0][2] / _rotation[2][2]));
|
||||||
|
//float rotateZ = glm::degrees(glm::atan(_rotation[1][0] / _rotation[1][1]));
|
||||||
|
// Calculate model matrix
|
||||||
glm::mat4 model = glm::mat4(1.0f);
|
glm::mat4 model = glm::mat4(1.0f);
|
||||||
model = glm::translate(model, _position);
|
model = glm::translate(model, _position);
|
||||||
model = _rotation * model;
|
model = glm::rotate(model, angle, axis);
|
||||||
|
//model = glm::rotate(model, glm::radians(rotateX), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
//model = glm::rotate(model, glm::radians(rotateY), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
//model = glm::rotate(model, glm::radians(rotateZ), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
model = glm::scale(model, _scale);
|
model = glm::scale(model, _scale);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
@ -300,10 +300,18 @@ void SceneViewer::mouseReleaseEvent(QMouseEvent* event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_pressedObject != nullptr && _pressedObject == _selectedObject) {
|
else if (_pressedObject != nullptr && _pressedObject == _selectedObject) {
|
||||||
// Double select on an object, set in operating mode
|
if (!_dragged) {
|
||||||
_operatingObject = _selectedObject;
|
// Double select on an object, set in operating mode
|
||||||
_hideBound = true;
|
_operatingObject = _selectedObject;
|
||||||
startOperatingObject = true;
|
_hideBound = true;
|
||||||
|
startOperatingObject = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// keep it selected
|
||||||
|
_dragged = false;
|
||||||
|
_hideBound = false;
|
||||||
|
_selectedObject->updateBoundary();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (_dragged) {
|
else if (_dragged) {
|
||||||
_dragged = false;
|
_dragged = false;
|
||||||
@ -347,9 +355,9 @@ void SceneViewer::mouseMoveEvent(QMouseEvent* event) {
|
|||||||
_hideBound = true;
|
_hideBound = true;
|
||||||
// Rotate around camera up
|
// Rotate around camera up
|
||||||
glm::vec2 delta = glm::vec2(event->x() - _lastMousePosition.x(), event->y() - _lastMousePosition.y());
|
glm::vec2 delta = glm::vec2(event->x() - _lastMousePosition.x(), event->y() - _lastMousePosition.y());
|
||||||
_selectedObject->rotate(_camera.up(), delta.x * 0.01f);
|
_selectedObject->rotate(_camera.up(), delta.x * 1.0f);
|
||||||
// Rotate around camera right
|
// Rotate around camera right
|
||||||
_selectedObject->rotate(_camera.right(), delta.y * 0.01f);
|
_selectedObject->rotate(_camera.right(), delta.y * 1.0f);
|
||||||
emit onUpdate(_selectedObject);
|
emit onUpdate(_selectedObject);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -490,34 +498,39 @@ void SceneViewer::moveOperatingObject(const Ray& ray) {
|
|||||||
}
|
}
|
||||||
// Move the object so that the bottom center of the object is at the hit point
|
// Move the object so that the bottom center of the object is at the hit point
|
||||||
else if (_stickToSurface) {
|
else if (_stickToSurface) {
|
||||||
// Stick the bottom center of the model to the surface
|
|
||||||
|
|
||||||
// Clear current translation and rotation while keeping scale
|
|
||||||
_operatingObject->setPosition(glm::vec3(0.0f));
|
|
||||||
_operatingObject->setRotation(glm::vec3(0.0f, 0.0f, 0.0f), 0.0f);
|
|
||||||
_operatingObject->updateBoundary();
|
|
||||||
|
|
||||||
// Set the bottom center of the model at local origin
|
// Set the bottom center of the model at local origin
|
||||||
glm::vec3 bottomCenter = _operatingObject->boundary().bottomCenterPoint();
|
glm::vec3 bottomCenter = _operatingObject->boundary().bottomCenterPoint();
|
||||||
_operatingObject->move(-bottomCenter);
|
glm::vec3 modelCenter = _operatingObject->modelMatrix() * glm::vec4(glm::vec3(0.0f), 1.0f); // model center in world space
|
||||||
|
|
||||||
// Rotate the model to align with the surface normal
|
// Rotate the model to align with the surface normal
|
||||||
glm::vec3 normal = _hitRecord.normal();
|
glm::vec3 normal = _hitRecord.normal();
|
||||||
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
|
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||||
glm::vec3 axis = glm::cross(up, normal);
|
glm::vec3 axis = glm::cross(up, normal);
|
||||||
float angle = glm::acos(glm::dot(up, normal));
|
float angle = glm::acos(glm::dot(up, normal));
|
||||||
_operatingObject->rotate(axis, angle);
|
_operatingObject->setRotation(axis, angle);
|
||||||
|
|
||||||
// Move the model to the hit point
|
// Move the model to the hit point
|
||||||
glm::vec3 hitPoint = _hitRecord.position();
|
glm::vec3 hitPoint = _hitRecord.position();
|
||||||
_operatingObject->move(hitPoint);
|
glm::vec3 newCenter = hitPoint + normal * (modelCenter.y - bottomCenter.y);
|
||||||
|
|
||||||
|
// Move the model to the new center
|
||||||
|
_operatingObject->setPosition(newCenter);
|
||||||
|
|
||||||
// Update boundary
|
// Update the boundary
|
||||||
_operatingObject->updateBoundary();
|
_operatingObject->updateBoundary();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Move the object to the hit point
|
// Move the object to the hit point
|
||||||
_operatingObject->setPosition(_hitRecord.position());
|
Logger::debug("Hit point: " + std::to_string(_hitRecord.position().x) + ", " + std::to_string(_hitRecord.position().y) + ", " + std::to_string(_hitRecord.position().z));
|
||||||
|
Logger::debug("Bottom center: " + std::to_string(_operatingObject->boundary().bottomCenterPoint().x) + ", " + std::to_string(_operatingObject->boundary().bottomCenterPoint().y) + ", " + std::to_string(_operatingObject->boundary().bottomCenterPoint().z));
|
||||||
|
glm::vec3 target = _hitRecord.position();
|
||||||
|
glm::vec3 modelCenter = _operatingObject->modelMatrix() * glm::vec4(glm::vec3(0.0f), 1.0f); // model center in world space
|
||||||
|
glm::vec3 bottomCenter = _operatingObject->modelMatrix() * glm::vec4(_operatingObject->model()->boundBox().bottomCenterPoint(), 1.0f); // model center in world space
|
||||||
|
glm::vec3 newCenter = target + modelCenter - bottomCenter;
|
||||||
|
_operatingObject->setPosition(newCenter);
|
||||||
|
|
||||||
|
// Update the boundary
|
||||||
|
_operatingObject->updateBoundary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,7 +572,12 @@ void SceneViewer::deleteObject() {
|
|||||||
void SceneViewer::updateSetting(QPair<QString, QString> setting) {
|
void SceneViewer::updateSetting(QPair<QString, QString> setting) {
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
if (setting.first == "stickSurface") {
|
if (setting.first == "stickSurface") {
|
||||||
_stickToSurface = true;
|
if (setting.second == "true") {
|
||||||
|
_stickToSurface = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_stickToSurface = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (setting.first == "skybox") {
|
else if (setting.first == "skybox") {
|
||||||
if (_sky != nullptr) {
|
if (_sky != nullptr) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user