[CORE][FIX] Fix placing (partial)

- Change placing calculation logic (without sticking)
- Sticking still not working
This commit is contained in:
Linloir 2022-12-20 00:30:17 +08:00
parent cd75d7a83d
commit e1cfd3932c
No known key found for this signature in database
GPG Key ID: 58EEB209A0F2C366
8 changed files with 85 additions and 34 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -2,7 +2,7 @@
#include <iostream>
#define LOCALLOGLEVEL INFO
#define LOCALLOGLEVEL DEBUG
class Logger {
public:

View File

@ -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 {

View File

@ -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();

View File

@ -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) {

View File

@ -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;
}

View File

@ -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) {