feat(editor): multi-select rotation

This commit is contained in:
maelstrom 2025-05-31 01:53:28 +02:00
parent 80ec1a9132
commit e5c8bdd2e2
3 changed files with 14 additions and 12 deletions

View file

@ -1,6 +1,7 @@
#include "partassembly.h" #include "partassembly.h"
#include "common.h" #include "common.h"
#include "datatypes/cframe.h" #include "datatypes/cframe.h"
#include "datatypes/meta.h"
#include "datatypes/vector.h" #include "datatypes/vector.h"
#include "math_helper.h" #include "math_helper.h"
#include "objects/base/instance.h" #include "objects/base/instance.h"
@ -48,6 +49,7 @@ void PartAssembly::SetOrigin(CFrame newOrigin) {
for (auto part : parts) { for (auto part : parts) {
part->cframe = newOrigin * (_assemblyOrigin.Inverse() * part->cframe); part->cframe = newOrigin * (_assemblyOrigin.Inverse() * part->cframe);
part->UpdateProperty("CFrame"); part->UpdateProperty("CFrame");
// sendPropertyUpdatedSignal(part, "CFrame", Data::Variant(part->cframe));
} }
_assemblyOrigin = newOrigin; _assemblyOrigin = newOrigin;
@ -57,6 +59,7 @@ void PartAssembly::TransformBy(CFrame transform) {
for (auto part : parts) { for (auto part : parts) {
part->cframe = transform * part->cframe; part->cframe = transform * part->cframe;
part->UpdateProperty("CFrame"); part->UpdateProperty("CFrame");
sendPropertyUpdatedSignal(part, "CFrame", Data::Variant(part->cframe));
} }
_assemblyOrigin = transform * _assemblyOrigin; _assemblyOrigin = transform * _assemblyOrigin;
@ -66,6 +69,7 @@ void PartAssembly::Scale(Vector3 newSize, bool scaleUp) {
if (parts.size() == 1) { if (parts.size() == 1) {
parts[0]->size = newSize; parts[0]->size = newSize;
parts[0]->UpdateProperty("Size"); parts[0]->UpdateProperty("Size");
sendPropertyUpdatedSignal(parts[0], "Size", Data::Variant((Data::Vector3)parts[0]->size));
_bounds = newSize; _bounds = newSize;
return; return;
} }
@ -78,8 +82,10 @@ void PartAssembly::Scale(Vector3 newSize, bool scaleUp) {
localOff = localOff * factor; localOff = localOff * factor;
part->cframe = part->cframe.Rotation() + _assemblyOrigin * localOff; part->cframe = part->cframe.Rotation() + _assemblyOrigin * localOff;
part->UpdateProperty("CFrame"); part->UpdateProperty("CFrame");
sendPropertyUpdatedSignal(part, "CFrame", Data::Variant(part->cframe));
part->size *= factor; part->size *= factor;
part->UpdateProperty("Size"); part->UpdateProperty("Size");
sendPropertyUpdatedSignal(part, "Size", Data::Variant((Data::Vector3)part->size));
} }
_bounds = _bounds * factor; _bounds = _bounds * factor;

View file

@ -556,16 +556,14 @@ void renderRotationArcs() {
// Pass in the camera position // Pass in the camera position
handleShader->set("viewPos", camera.cameraPos); handleShader->set("viewPos", camera.cameraPos);
// TODO: This won't do... Doesn't support rotating multiple objects, and expects the first selected item to be a part, PartAssembly assembly = PartAssembly::FromSelection();
// which isn't always the case
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(getSelection()[0]);
for (HandleFace face : HandleFace::Faces) { for (HandleFace face : HandleFace::Faces) {
if (glm::any(glm::lessThan(face.normal, glm::vec3(0)))) continue; if (glm::any(glm::lessThan(face.normal, glm::vec3(0)))) continue;
glm::mat4 model = part->cframe * CFrame(glm::vec3(0), face.normal, glm::vec3(0, 1.01, 0.1)); glm::mat4 model = assembly.assemblyOrigin() * CFrame(glm::vec3(0), face.normal, glm::vec3(0, 1.01, 0.1));
handleShader->set("model", model); handleShader->set("model", model);
float radius = glm::max(part->size.x, part->size.y, part->size.z) / 2.f + 2.f; float radius = glm::max(assembly.bounds().X(), assembly.bounds().Y(), assembly.bounds().Z()) / 2.f + 2.f;
handleShader->set("material", Material { handleShader->set("material", Material {
.diffuse = glm::abs(face.normal), .diffuse = glm::abs(face.normal),

View file

@ -121,6 +121,7 @@ std::optional<HandleFace> draggingHandle;
Vector3 initialHitPos; Vector3 initialHitPos;
Vector3 initialHitNormal; Vector3 initialHitNormal;
CFrame initialFrame; CFrame initialFrame;
PartAssembly initialAssembly({});
void MainGLWidget::handleObjectDrag(QMouseEvent* evt) { void MainGLWidget::handleObjectDrag(QMouseEvent* evt) {
if (!isMouseDragging || draggingObject.expired() || mainWindow()->selectedTool >= TOOL_SMOOTH) return; if (!isMouseDragging || draggingObject.expired() || mainWindow()->selectedTool >= TOOL_SMOOTH) return;
@ -271,7 +272,6 @@ void MainGLWidget::handleRotationalTransform(QMouseEvent* evt) {
if (!isMouseDragging || !draggingHandle || !editorToolHandles.active) return; if (!isMouseDragging || !draggingHandle || !editorToolHandles.active) return;
glm::vec2 destPoint = glm::vec2(evt->pos().x(), evt->pos().y()); glm::vec2 destPoint = glm::vec2(evt->pos().x(), evt->pos().y());
auto part = getHandleAdornee();
// Calculate part pos as screen point // Calculate part pos as screen point
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)width() / (float)height(), 0.1f, 1000.0f); glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)width() / (float)height(), 0.1f, 1000.0f);
@ -303,11 +303,8 @@ void MainGLWidget::handleRotationalTransform(QMouseEvent* evt) {
glm::vec3 angles = handleNormal * sign * glm::vec3(angle); glm::vec3 angles = handleNormal * sign * glm::vec3(angle);
part->cframe = initialFrame * CFrame::FromEulerAnglesXYZ(-angles); CFrame newFrame = initialFrame * CFrame::FromEulerAnglesXYZ(-angles);
initialAssembly.SetOrigin(newFrame);
gWorkspace()->SyncPartPhysics(part);
part->UpdateProperty("Rotation");
sendPropertyUpdatedSignal(part, "Rotation", part->cframe.ToEulerAnglesXYZ());
} }
std::optional<HandleFace> MainGLWidget::raycastHandle(glm::vec3 pointDir) { std::optional<HandleFace> MainGLWidget::raycastHandle(glm::vec3 pointDir) {
@ -375,7 +372,8 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
auto handle = raycastHandle(pointDir); auto handle = raycastHandle(pointDir);
if (handle.has_value()) { if (handle.has_value()) {
startPoint = glm::vec2(evt->pos().x(), evt->pos().y()); startPoint = glm::vec2(evt->pos().x(), evt->pos().y());
initialFrame = getHandleAdornee()->cframe; initialAssembly = PartAssembly::FromSelection();
initialFrame = initialAssembly.assemblyOrigin();
isMouseDragging = true; isMouseDragging = true;
draggingHandle = handle; draggingHandle = handle;
startLinearTransform(evt); startLinearTransform(evt);