VOXEDIT: allow to transform a group of nodes

master
Martin Gerhardy 2022-05-24 17:20:16 +02:00
parent 1e1f4cd4f3
commit 0fee146e5b
3 changed files with 34 additions and 17 deletions

View File

@ -256,12 +256,15 @@ void Viewport::renderGizmo(video::Camera &camera, const float headerSize, const
const uint32_t keyFrame = node.keyFrameForFrame(sceneMgr().currentFrame()); const uint32_t keyFrame = node.keyFrameForFrame(sceneMgr().currentFrame());
const voxelformat::SceneGraphTransform &transform = node.transform(keyFrame); const voxelformat::SceneGraphTransform &transform = node.transform(keyFrame);
glm::mat4 transformMatrix = transform.matrix(); 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()) { if (ImGuizmo::IsUsing()) {
_guizmoActivated = true; _guizmoActivated = true;
sceneMgr().nodeUpdateTransform(activeNode, transformMatrix, keyFrame, false); sceneMgr().nodeUpdateTransform(-1, transformMatrix, &deltaMatrix, keyFrame, false);
} else if (_guizmoActivated) { } else if (_guizmoActivated) {
sceneMgr().nodeUpdateTransform(activeNode, transformMatrix, keyFrame, true); sceneMgr().nodeUpdateTransform(-1, transformMatrix, &deltaMatrix, keyFrame, true);
_guizmoActivated = false; _guizmoActivated = false;
} }

View File

@ -524,7 +524,7 @@ bool SceneManager::undo() {
return nodeMove(s.nodeId, s.parentId); return nodeMove(s.nodeId, s.parentId);
} else if (s.type == MementoType::SceneNodeTransform) { } else if (s.type == MementoType::SceneNodeTransform) {
Log::debug("Memento: Undo transform of node %i", s.nodeId); 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) { } else if (s.type == MementoType::SceneNodeRemoved) {
voxel::RawVolume* v = MementoData::toVolume(s.data); voxel::RawVolume* v = MementoData::toVolume(s.data);
voxelformat::SceneGraphNode node(voxelformat::SceneGraphNodeType::Model); voxelformat::SceneGraphNode node(voxelformat::SceneGraphNodeType::Model);
@ -579,7 +579,7 @@ bool SceneManager::redo() {
return nodeMove(s.nodeId, s.parentId); return nodeMove(s.nodeId, s.parentId);
} else if (s.type == MementoType::SceneNodeTransform) { } else if (s.type == MementoType::SceneNodeTransform) {
Log::debug("Memento: Undo transform of node %i", s.nodeId); 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) { } 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); 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); return nodeRemove(s.nodeId, true);
@ -2342,25 +2342,39 @@ void SceneManager::setLockedAxis(math::Axis axis, bool unlock) {
updateLockedPlane(math::Axis::Z); updateLockedPlane(math::Axis::Z);
} }
bool SceneManager::nodeUpdateTransform(int nodeId, const glm::mat4 &matrix, uint32_t keyFrame, bool memento) { bool SceneManager::nodeUpdateTransform(int nodeId, const glm::mat4 &matrix, const glm::mat4 *deltaMatrix, uint32_t keyFrame, bool memento) {
if (voxelformat::SceneGraphNode *node = sceneGraphNode(nodeId)) { if (nodeId != -1) {
return nodeUpdateTransform(*node, matrix, keyFrame, memento); 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::vec3 translation;
glm::quat orientation; glm::quat orientation;
glm::vec3 scale; glm::vec3 scale;
glm::vec3 skew; glm::vec3 skew;
glm::vec4 perspective; glm::vec4 perspective;
glm::decompose(matrix, scale, orientation, translation, skew, perspective);
voxelformat::SceneGraphTransform &transform = node.transform(keyFrame); voxelformat::SceneGraphTransform &transform = node.transform(keyFrame);
transform.setTranslation(translation); if (deltaMatrix) {
transform.setOrientation(orientation); glm::decompose(*deltaMatrix, scale, orientation, translation, skew, perspective);
//transform.setScale(glm::length(scale)); 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(); transform.update();
if (memento) { if (memento) {

View File

@ -423,10 +423,10 @@ private:
void onNewNodeAdded(int newNodeId); void onNewNodeAdded(int newNodeId);
bool nodeRename(voxelformat::SceneGraphNode &node, const core::String &name); bool nodeRename(voxelformat::SceneGraphNode &node, const core::String &name);
bool nodeRemove(voxelformat::SceneGraphNode &node, bool recursive); 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); void nodeDuplicate(const voxelformat::SceneGraphNode &node);
public: 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 nodeMove(int sourceNodeId, int targetNodeId);
bool nodeRename(int nodeId, const core::String &name); bool nodeRename(int nodeId, const core::String &name);
bool nodeRemove(int nodeId, bool recursive); bool nodeRemove(int nodeId, bool recursive);