mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-17 07:28:12 +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 topControlPoint() const { return _topControlPoint; }
|
||||
inline glm::vec3 bottomCenterPoint() const;
|
||||
inline glm::vec3 centerPoint() const;
|
||||
|
||||
bool hit(const Ray& ray) const;
|
||||
|
||||
@ -29,3 +30,7 @@ public:
|
||||
inline glm::vec3 Boundary::bottomCenterPoint() const {
|
||||
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"
|
||||
|
||||
Logger::LogLevel Logger::_level = Logger::LogLevel::LOCALLOGLEVEL;
|
||||
std::string Logger::_previous = "";
|
||||
|
||||
void Logger::setLogLevel(LogLevel level) {
|
||||
_level = level;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define LOCALLOGLEVEL INFO
|
||||
#define LOCALLOGLEVEL DEBUG
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
|
||||
@ -190,13 +190,14 @@ void Model::render(const ShaderProgram& shader) const {
|
||||
}
|
||||
|
||||
HitRecord Model::hit(const Ray& ray, const glm::mat4& modelMatrix) const {
|
||||
HitRecord record = HitRecord();
|
||||
for (unsigned int i = 0; i < _meshes.size(); i++) {
|
||||
HitRecord hitRecord = _meshes[i].hit(ray, modelMatrix);
|
||||
if (hitRecord.hitted()) {
|
||||
return hitRecord;
|
||||
if (hitRecord.hitted() && hitRecord.t() < record.t()) {
|
||||
record = hitRecord;
|
||||
}
|
||||
}
|
||||
return HitRecord();
|
||||
return record;
|
||||
}
|
||||
|
||||
Model* Model::copyToCurrentContext() const {
|
||||
|
||||
@ -448,14 +448,24 @@ void ModelSetter::update(Renderable* object) {
|
||||
_rotateY->setEnabled();
|
||||
_rotateZ->setEnabled();
|
||||
}
|
||||
// Extract x, y, z axis rotation from rotation matrix
|
||||
glm::mat4 rotationMatrix = object->rotation();
|
||||
float rotateX = glm::degrees(glm::asin(-rotationMatrix[1][2]));
|
||||
float rotateY = glm::degrees(glm::atan(rotationMatrix[0][2] / rotationMatrix[2][2]));
|
||||
float rotateZ = glm::degrees(glm::atan(rotationMatrix[1][0] / rotationMatrix[1][1]));
|
||||
_rotateX->setValue(rotateX);
|
||||
_rotateY->setValue(rotateY);
|
||||
_rotateZ->setValue(rotateZ);
|
||||
// Extract x, y, z axis rotation degree from rotation matrix
|
||||
glm::quat quat(object->rotation());
|
||||
glm::vec3 euler = glm::eulerAngles(quat);
|
||||
float x = glm::degrees(euler.x);
|
||||
float y = glm::degrees(euler.y);
|
||||
float z = glm::degrees(euler.z);
|
||||
if (x < 0) {
|
||||
x += 360;
|
||||
}
|
||||
if (y < 0) {
|
||||
y += 360;
|
||||
}
|
||||
if (z < 0) {
|
||||
z += 360;
|
||||
}
|
||||
_rotateX->setValue(x);
|
||||
_rotateY->setValue(y);
|
||||
_rotateZ->setValue(z);
|
||||
|
||||
if (_object == nullptr) {
|
||||
_lightSwitch->setEnabled();
|
||||
|
||||
@ -31,11 +31,11 @@ void Renderable::setPosition(glm::vec3 position) {
|
||||
}
|
||||
|
||||
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) {
|
||||
_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) {
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <GLM/glm.hpp>
|
||||
#include <GLM/ext/matrix_transform.hpp>
|
||||
#include <GLM/gtx/quaternion.hpp>
|
||||
|
||||
#include "model.h"
|
||||
#include "illuminer.h"
|
||||
@ -35,6 +36,7 @@ public:
|
||||
glm::vec3 position() const { return _position; }
|
||||
glm::mat4 rotation() const { return _rotation; }
|
||||
glm::vec3 scaleVal() const { return _scale; }
|
||||
Model* model() const { return _model; }
|
||||
|
||||
void setModel(Model* model);
|
||||
void move(glm::vec3 deltaVec);
|
||||
@ -61,9 +63,23 @@ public:
|
||||
};
|
||||
|
||||
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);
|
||||
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);
|
||||
return model;
|
||||
}
|
||||
@ -300,10 +300,18 @@ void SceneViewer::mouseReleaseEvent(QMouseEvent* event) {
|
||||
}
|
||||
}
|
||||
else if (_pressedObject != nullptr && _pressedObject == _selectedObject) {
|
||||
// Double select on an object, set in operating mode
|
||||
_operatingObject = _selectedObject;
|
||||
_hideBound = true;
|
||||
startOperatingObject = true;
|
||||
if (!_dragged) {
|
||||
// Double select on an object, set in operating mode
|
||||
_operatingObject = _selectedObject;
|
||||
_hideBound = true;
|
||||
startOperatingObject = true;
|
||||
}
|
||||
else {
|
||||
// keep it selected
|
||||
_dragged = false;
|
||||
_hideBound = false;
|
||||
_selectedObject->updateBoundary();
|
||||
}
|
||||
}
|
||||
else if (_dragged) {
|
||||
_dragged = false;
|
||||
@ -347,9 +355,9 @@ void SceneViewer::mouseMoveEvent(QMouseEvent* event) {
|
||||
_hideBound = true;
|
||||
// Rotate around camera up
|
||||
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
|
||||
_selectedObject->rotate(_camera.right(), delta.y * 0.01f);
|
||||
_selectedObject->rotate(_camera.right(), delta.y * 1.0f);
|
||||
emit onUpdate(_selectedObject);
|
||||
}
|
||||
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
|
||||
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
|
||||
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
|
||||
glm::vec3 normal = _hitRecord.normal();
|
||||
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 axis = glm::cross(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
|
||||
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();
|
||||
}
|
||||
else {
|
||||
// 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) {
|
||||
makeCurrent();
|
||||
if (setting.first == "stickSurface") {
|
||||
_stickToSurface = true;
|
||||
if (setting.second == "true") {
|
||||
_stickToSurface = true;
|
||||
}
|
||||
else {
|
||||
_stickToSurface = false;
|
||||
}
|
||||
}
|
||||
else if (setting.first == "skybox") {
|
||||
if (_sky != nullptr) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user