feat(editor): undoing movement/transformations
This commit is contained in:
parent
cef5db5b2d
commit
ed5aa597ad
3 changed files with 42 additions and 0 deletions
|
@ -117,4 +117,18 @@ void PartAssembly::Scale(Vector3 newSize, bool scaleUp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_bounds = _bounds * factor;
|
_bounds = _bounds * factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PartTransformState> PartAssembly::GetCurrentTransforms() {
|
||||||
|
std::vector<PartTransformState> transforms;
|
||||||
|
|
||||||
|
for (auto part : parts) {
|
||||||
|
PartTransformState t;
|
||||||
|
t.part = part;
|
||||||
|
t.cframe = part->cframe;
|
||||||
|
t.size = part->size;
|
||||||
|
transforms.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return transforms;
|
||||||
}
|
}
|
|
@ -8,6 +8,12 @@ class Part;
|
||||||
class Instance;
|
class Instance;
|
||||||
class Selection;
|
class Selection;
|
||||||
|
|
||||||
|
struct PartTransformState {
|
||||||
|
std::shared_ptr<Part> part;
|
||||||
|
Vector3 size;
|
||||||
|
CFrame cframe;
|
||||||
|
};
|
||||||
|
|
||||||
class PartAssembly {
|
class PartAssembly {
|
||||||
CFrame _assemblyOrigin;
|
CFrame _assemblyOrigin;
|
||||||
Vector3 _bounds;
|
Vector3 _bounds;
|
||||||
|
@ -25,6 +31,9 @@ public:
|
||||||
inline Vector3 size() { return _size; };
|
inline Vector3 size() { return _size; };
|
||||||
inline bool multipleSelected() { return parts.size() > 1; }
|
inline bool multipleSelected() { return parts.size() > 1; }
|
||||||
|
|
||||||
|
// Gets the current transform state of all the parts in the assembly
|
||||||
|
std::vector<PartTransformState> GetCurrentTransforms();
|
||||||
|
|
||||||
// Transforms the assembly such that newOrigin is now this assembly's new assemblyOrigin
|
// Transforms the assembly such that newOrigin is now this assembly's new assemblyOrigin
|
||||||
void SetOrigin(CFrame newOrigin);
|
void SetOrigin(CFrame newOrigin);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "rendering/renderer.h"
|
#include "rendering/renderer.h"
|
||||||
#include "rendering/shader.h"
|
#include "rendering/shader.h"
|
||||||
#include "datatypes/variant.h"
|
#include "datatypes/variant.h"
|
||||||
|
#include "undohistory.h"
|
||||||
|
|
||||||
#define PI 3.14159
|
#define PI 3.14159
|
||||||
#define M_mainWindow dynamic_cast<MainWindow*>(window())
|
#define M_mainWindow dynamic_cast<MainWindow*>(window())
|
||||||
|
@ -120,6 +121,8 @@ CFrame snapCFrame(CFrame frame) {
|
||||||
return CFrame(frame.Position(), frame.Position() + closestVec1, closestVec2);
|
return CFrame(frame.Position(), frame.Position() + closestVec1, closestVec2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PartTransformState> initialTransforms;
|
||||||
|
|
||||||
bool tryMouseContextMenu = false;
|
bool tryMouseContextMenu = false;
|
||||||
bool isMouseDragging = false;
|
bool isMouseDragging = false;
|
||||||
std::weak_ptr<Part> draggingObject;
|
std::weak_ptr<Part> draggingObject;
|
||||||
|
@ -359,6 +362,7 @@ void MainGLWidget::mouseMoveEvent(QMouseEvent* evt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
||||||
|
initialTransforms = {};
|
||||||
tryMouseContextMenu = evt->button() == Qt::RightButton;
|
tryMouseContextMenu = evt->button() == Qt::RightButton;
|
||||||
switch(evt->button()) {
|
switch(evt->button()) {
|
||||||
// Camera drag
|
// Camera drag
|
||||||
|
@ -377,6 +381,8 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
||||||
startPoint = glm::vec2(evt->pos().x(), evt->pos().y());
|
startPoint = glm::vec2(evt->pos().x(), evt->pos().y());
|
||||||
initialAssembly = PartAssembly::FromSelection(gDataModel->GetService<Selection>());
|
initialAssembly = PartAssembly::FromSelection(gDataModel->GetService<Selection>());
|
||||||
initialFrame = initialAssembly.assemblyOrigin();
|
initialFrame = initialAssembly.assemblyOrigin();
|
||||||
|
initialTransforms = PartAssembly::FromSelection(gDataModel->GetService<Selection>()).GetCurrentTransforms();
|
||||||
|
printf("%ld\n", initialTransforms.size());
|
||||||
isMouseDragging = true;
|
isMouseDragging = true;
|
||||||
draggingHandle = handle;
|
draggingHandle = handle;
|
||||||
startLinearTransform(evt);
|
startLinearTransform(evt);
|
||||||
|
@ -430,6 +436,7 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
||||||
//part.selected = true;
|
//part.selected = true;
|
||||||
isMouseDragging = true;
|
isMouseDragging = true;
|
||||||
draggingObject = part;
|
draggingObject = part;
|
||||||
|
initialTransforms = PartAssembly::FromSelection({part}).GetCurrentTransforms();
|
||||||
if (evt->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier)) {
|
if (evt->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier)) {
|
||||||
auto sel = selection->Get();
|
auto sel = selection->Get();
|
||||||
if (std::find(sel.begin(), sel.end(), selObject) == sel.end())
|
if (std::find(sel.begin(), sel.end(), selObject) == sel.end())
|
||||||
|
@ -455,6 +462,17 @@ void MainGLWidget::mouseReleaseEvent(QMouseEvent* evt) {
|
||||||
draggingObject = {};
|
draggingObject = {};
|
||||||
draggingHandle = std::nullopt;
|
draggingHandle = std::nullopt;
|
||||||
|
|
||||||
|
if (!initialTransforms.empty()) {
|
||||||
|
UndoState historyState;
|
||||||
|
|
||||||
|
for (auto t : initialTransforms) {
|
||||||
|
historyState.push_back(UndoStatePropertyChanged { t.part, "CFrame", t.cframe, t.part->cframe });
|
||||||
|
historyState.push_back(UndoStatePropertyChanged { t.part, "Size", t.size, t.part->size });
|
||||||
|
}
|
||||||
|
|
||||||
|
M_mainWindow->undoManager.PushState(historyState);
|
||||||
|
}
|
||||||
|
|
||||||
// Open context menu
|
// Open context menu
|
||||||
if (tryMouseContextMenu)
|
if (tryMouseContextMenu)
|
||||||
contextMenu.exec(QCursor::pos());
|
contextMenu.exec(QCursor::pos());
|
||||||
|
@ -505,6 +523,7 @@ void MainGLWidget::keyPressEvent(QKeyEvent* evt) {
|
||||||
}));
|
}));
|
||||||
gWorkspace()->SyncPartPhysics(lastPart);
|
gWorkspace()->SyncPartPhysics(lastPart);
|
||||||
lastPart->name = "Part" + std::to_string(partId++);
|
lastPart->name = "Part" + std::to_string(partId++);
|
||||||
|
M_mainWindow->undoManager.PushState({ UndoStateInstanceCreated { lastPart, gWorkspace() } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue