From 0fee146e5b260528c9fc3e1b99479487ffd0c204 Mon Sep 17 00:00:00 2001 From: Martin Gerhardy Date: Tue, 24 May 2022 17:20:16 +0200 Subject: [PATCH] VOXEDIT: allow to transform a group of nodes --- .../voxedit/modules/voxedit-ui/Viewport.cpp | 9 +++-- .../modules/voxedit-util/SceneManager.cpp | 38 +++++++++++++------ .../modules/voxedit-util/SceneManager.h | 4 +- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/tools/voxedit/modules/voxedit-ui/Viewport.cpp b/src/tools/voxedit/modules/voxedit-ui/Viewport.cpp index 6fb21d070..ae7202781 100644 --- a/src/tools/voxedit/modules/voxedit-ui/Viewport.cpp +++ b/src/tools/voxedit/modules/voxedit-ui/Viewport.cpp @@ -256,12 +256,15 @@ void Viewport::renderGizmo(video::Camera &camera, const float headerSize, const const uint32_t keyFrame = node.keyFrameForFrame(sceneMgr().currentFrame()); const voxelformat::SceneGraphTransform &transform = node.transform(keyFrame); glm::mat4 transformMatrix = transform.matrix(); - ImGuizmo::Manipulate(glm::value_ptr(camera.viewMatrix()), glm::value_ptr(camera.projectionMatrix()), (ImGuizmo::OPERATION)operation, mode, glm::value_ptr(transformMatrix), nullptr, _guizmoSnap->boolVal() ? snap: nullptr); + glm::mat4 deltaMatrix(0.0f); + ImGuizmo::Manipulate(glm::value_ptr(camera.viewMatrix()), glm::value_ptr(camera.projectionMatrix()), + (ImGuizmo::OPERATION)operation, mode, glm::value_ptr(transformMatrix), + glm::value_ptr(deltaMatrix), _guizmoSnap->boolVal() ? snap : nullptr); if (ImGuizmo::IsUsing()) { _guizmoActivated = true; - sceneMgr().nodeUpdateTransform(activeNode, transformMatrix, keyFrame, false); + sceneMgr().nodeUpdateTransform(-1, transformMatrix, &deltaMatrix, keyFrame, false); } else if (_guizmoActivated) { - sceneMgr().nodeUpdateTransform(activeNode, transformMatrix, keyFrame, true); + sceneMgr().nodeUpdateTransform(-1, transformMatrix, &deltaMatrix, keyFrame, true); _guizmoActivated = false; } diff --git a/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp b/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp index 4ef8459a3..5c0987d45 100644 --- a/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp +++ b/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp @@ -524,7 +524,7 @@ bool SceneManager::undo() { return nodeMove(s.nodeId, s.parentId); } else if (s.type == MementoType::SceneNodeTransform) { Log::debug("Memento: Undo transform of node %i", s.nodeId); - return nodeUpdateTransform(s.nodeId, s.transformMatrix, s.keyFrame, false); + return nodeUpdateTransform(s.nodeId, s.transformMatrix, nullptr, s.keyFrame, false); } else if (s.type == MementoType::SceneNodeRemoved) { voxel::RawVolume* v = MementoData::toVolume(s.data); voxelformat::SceneGraphNode node(voxelformat::SceneGraphNodeType::Model); @@ -579,7 +579,7 @@ bool SceneManager::redo() { return nodeMove(s.nodeId, s.parentId); } else if (s.type == MementoType::SceneNodeTransform) { Log::debug("Memento: Undo transform of node %i", s.nodeId); - return nodeUpdateTransform(s.nodeId, s.transformMatrix, s.keyFrame, false); + return nodeUpdateTransform(s.nodeId, s.transformMatrix, nullptr, s.keyFrame, false); } else if (s.type == MementoType::SceneNodeRemoved) { Log::debug("Memento: Redo remove of node %i (%s) from parent %i", s.nodeId, s.name.c_str(), s.parentId); return nodeRemove(s.nodeId, true); @@ -2342,25 +2342,39 @@ void SceneManager::setLockedAxis(math::Axis axis, bool unlock) { updateLockedPlane(math::Axis::Z); } -bool SceneManager::nodeUpdateTransform(int nodeId, const glm::mat4 &matrix, uint32_t keyFrame, bool memento) { - if (voxelformat::SceneGraphNode *node = sceneGraphNode(nodeId)) { - return nodeUpdateTransform(*node, matrix, keyFrame, memento); +bool SceneManager::nodeUpdateTransform(int nodeId, const glm::mat4 &matrix, const glm::mat4 *deltaMatrix, uint32_t keyFrame, bool memento) { + if (nodeId != -1) { + if (voxelformat::SceneGraphNode *node = sceneGraphNode(nodeId)) { + return nodeUpdateTransform(*node, matrix, deltaMatrix, keyFrame, memento); + } + return false; } - return false; + nodeForeachGroup([&] (int nodeId) { + if (voxelformat::SceneGraphNode *node = sceneGraphNode(nodeId)) { + nodeUpdateTransform(*node, matrix, deltaMatrix, keyFrame, memento); + } + }); + return true; } -bool SceneManager::nodeUpdateTransform(voxelformat::SceneGraphNode &node, const glm::mat4 &matrix, uint32_t keyFrame, bool memento) { +bool SceneManager::nodeUpdateTransform(voxelformat::SceneGraphNode &node, const glm::mat4 &matrix, const glm::mat4 *deltaMatrix, uint32_t keyFrame, bool memento) { glm::vec3 translation; glm::quat orientation; glm::vec3 scale; glm::vec3 skew; glm::vec4 perspective; - glm::decompose(matrix, scale, orientation, translation, skew, perspective); - voxelformat::SceneGraphTransform &transform = node.transform(keyFrame); - transform.setTranslation(translation); - transform.setOrientation(orientation); - //transform.setScale(glm::length(scale)); + if (deltaMatrix) { + glm::decompose(*deltaMatrix, scale, orientation, translation, skew, perspective); + transform.setTranslation(transform.translation() + translation); + transform.setOrientation(transform.orientation() * orientation); + //transform.setScale(glm::length(scale)); + } else { + glm::decompose(matrix, scale, orientation, translation, skew, perspective); + transform.setTranslation(translation); + transform.setOrientation(orientation); + //transform.setScale(glm::length(scale)); + } transform.update(); if (memento) { diff --git a/src/tools/voxedit/modules/voxedit-util/SceneManager.h b/src/tools/voxedit/modules/voxedit-util/SceneManager.h index 9d7c002df..a57f52ab0 100644 --- a/src/tools/voxedit/modules/voxedit-util/SceneManager.h +++ b/src/tools/voxedit/modules/voxedit-util/SceneManager.h @@ -423,10 +423,10 @@ private: void onNewNodeAdded(int newNodeId); bool nodeRename(voxelformat::SceneGraphNode &node, const core::String &name); bool nodeRemove(voxelformat::SceneGraphNode &node, bool recursive); - bool nodeUpdateTransform(voxelformat::SceneGraphNode &node, const glm::mat4 &matrix, uint32_t keyFrame, bool memento); + bool nodeUpdateTransform(voxelformat::SceneGraphNode &node, const glm::mat4 &matrix, const glm::mat4 *deltaMatrix, uint32_t keyFrame, bool memento); void nodeDuplicate(const voxelformat::SceneGraphNode &node); public: - bool nodeUpdateTransform(int nodeId, const glm::mat4 &matrix, uint32_t keyFrame, bool memento); + bool nodeUpdateTransform(int nodeId, const glm::mat4 &matrix, const glm::mat4 *deltaMatrix, uint32_t keyFrame, bool memento); bool nodeMove(int sourceNodeId, int targetNodeId); bool nodeRename(int nodeId, const core::String &name); bool nodeRemove(int nodeId, bool recursive);