diff --git a/ChairManager/Data/Preditor/ActionSets.xml b/ChairManager/Data/Preditor/ActionSets.xml index c6d445545..05387e2c9 100644 --- a/ChairManager/Data/Preditor/ActionSets.xml +++ b/ChairManager/Data/Preditor/ActionSets.xml @@ -58,6 +58,9 @@ name="transform_tools" description="Transform Tools" priority="60"> + + + diff --git a/Preditor/Common/Preditor/SceneEditor/IObjectManipulator.h b/Preditor/Common/Preditor/SceneEditor/IObjectManipulator.h index e1e697be8..6663d1682 100644 --- a/Preditor/Common/Preditor/SceneEditor/IObjectManipulator.h +++ b/Preditor/Common/Preditor/SceneEditor/IObjectManipulator.h @@ -10,4 +10,7 @@ struct IObjectManipulator //! Sets an object's world translation matrix. virtual void SetObjectWorldTM(SceneObjectId id, const Matrix34& tm) = 0; + + //! Gets the object's local-space bounding box. + virtual void GetObjectLocalBounds(SceneObjectId id, AABB& aabb) = 0; }; diff --git a/Preditor/EditTools/EditToolManager.cpp b/Preditor/EditTools/EditToolManager.cpp index 0a95f4258..f50b51fba 100644 --- a/Preditor/EditTools/EditToolManager.cpp +++ b/Preditor/EditTools/EditToolManager.cpp @@ -23,6 +23,12 @@ EditTools::EditToolManager::EditToolManager(ISceneEditor* pEditor) RegisterToolSelectKey("rotate", m_pRotateTool); RegisterToolSelectKey("scale", m_pScaleTool); + gPreditor->pInput->FindAction("transform_tools.toggle_pivot")->AddListener([this](const KeyActionEventArgs& e) + { + if (e.isPressed) + m_bPivotCenter ^= 1; + }); + gPreditor->pInput->FindAction("transform_tools.toggle_tool_space")->AddListener([this](const KeyActionEventArgs& e) { if (e.isPressed) @@ -39,6 +45,10 @@ EditTools::EditToolManager::~EditToolManager() void EditTools::EditToolManager::ShowSelectionUI() { + if (ImGui::Button(m_bPivotCenter ? ICON_MD_CENTER_FOCUS_WEAK : ICON_MD_TRIP_ORIGIN)) + m_bPivotCenter ^= 1; + ImGui::SameLine(); + if (ImGui::Button(m_bWorldTransform ? ICON_MD_LANGUAGE : ICON_MD_VIEW_IN_AR)) m_bWorldTransform ^= 1; ImGui::SameLine(); diff --git a/Preditor/EditTools/EditToolManager.h b/Preditor/EditTools/EditToolManager.h index ec77ceea0..a7fbedbce 100644 --- a/Preditor/EditTools/EditToolManager.h +++ b/Preditor/EditTools/EditToolManager.h @@ -18,6 +18,9 @@ class EditToolManager final : public IEditToolManager //! @returns the current tool (or nullptr, if none). EditTool* GetCurrentTool() const { return m_pCurTool; } + //! @returns whether transformation tools should pivot around the center instead of local origin. + bool IsPivotCenter() const { return m_bPivotCenter; } + //! @returns whether transformation tools should tranform in the world space. bool IsWorldTransform() const { return m_bWorldTransform; } @@ -33,7 +36,8 @@ class EditToolManager final : public IEditToolManager bool m_bIsActive = false; ISceneEditor* m_pEditor = nullptr; EditTool* m_pCurTool = nullptr; - bool m_bWorldTransform = true; + bool m_bPivotCenter = true; + bool m_bWorldTransform = false; std::unique_ptr m_pSelectTool; std::unique_ptr m_pMoveTool; diff --git a/Preditor/EditTools/ImGuizmoTool.cpp b/Preditor/EditTools/ImGuizmoTool.cpp index c28d86229..de7356117 100644 --- a/Preditor/EditTools/ImGuizmoTool.cpp +++ b/Preditor/EditTools/ImGuizmoTool.cpp @@ -106,8 +106,18 @@ void EditTools::ImGuizmoTool::DrawViewport(const Vec4& bounds, const CCamera& ca if (activeObj != INVALID_SCENE_OBJECT) { IObjectManipulator* pManip = pEditor->GetManipulator(); + Matrix44 pivotTransform(IDENTITY); + + if (GetManager()->IsPivotCenter()) + { + // Get AABB center + AABB aabb; + pManip->GetObjectLocalBounds(activeObj, aabb); + pivotTransform.SetTranslation(aabb.GetCenter()); + } + Matrix44 viewMat = CryToImGuizmo(camera.GetViewMatrix()); - Matrix44 objectTM = CryToImGuizmo(pManip->GetObjectWorldTM(activeObj)); + Matrix44 objectTM = CryToImGuizmo(pManip->GetObjectWorldTM(activeObj) * pivotTransform); Matrix44 projMat; FrustumFromCamera(camera, bounds.z - bounds.x, bounds.w - bounds.y, projMat.GetData()); @@ -119,10 +129,10 @@ void EditTools::ImGuizmoTool::DrawViewport(const Vec4& bounds, const CCamera& ca GetManager()->IsWorldTransform() ? ImGuizmo::WORLD : ImGuizmo::LOCAL, objectTM.GetData(), nullptr, // deltaMatrix - m_pSnapKey->IsHeldDown() ? & m_Snap.x : nullptr); + m_pSnapKey->IsHeldDown() ? &m_Snap.x : nullptr); if (manipulated) - pManip->SetObjectWorldTM(activeObj, Matrix34(ImGuizmoToCry(objectTM))); + pManip->SetObjectWorldTM(activeObj, Matrix34(ImGuizmoToCry(objectTM) * pivotTransform.GetInverted())); } } diff --git a/Preditor/GameEditor/EntityManipulator.cpp b/Preditor/GameEditor/EntityManipulator.cpp index 09b5084e0..c0f0f3e6c 100644 --- a/Preditor/GameEditor/EntityManipulator.cpp +++ b/Preditor/GameEditor/EntityManipulator.cpp @@ -34,3 +34,16 @@ void GameEditor::EntityManipulator::SetObjectWorldTM(SceneObjectId id, const Mat pEnt->SetWorldTM(tm, ENTITY_XFORM_EDITOR); } + +void GameEditor::EntityManipulator::GetObjectLocalBounds(SceneObjectId id, AABB& aabb) +{ + IEntity* pEnt = gEnv->pEntitySystem->GetEntity((EntityId)id); + + if (!pEnt) + { + CryError("GetObjectLocalBounds called with invalid entity id {}", id); + return; + } + + pEnt->GetLocalBounds(aabb); +} diff --git a/Preditor/GameEditor/EntityManipulator.h b/Preditor/GameEditor/EntityManipulator.h index f671bed01..6adf3aa75 100644 --- a/Preditor/GameEditor/EntityManipulator.h +++ b/Preditor/GameEditor/EntityManipulator.h @@ -16,6 +16,7 @@ class EntityManipulator : public IObjectManipulator // IObjectManipulator virtual Matrix34 GetObjectWorldTM(SceneObjectId id) override; virtual void SetObjectWorldTM(SceneObjectId id, const Matrix34& tm) override; + virtual void GetObjectLocalBounds(SceneObjectId id, AABB& aabb) override; private: GameEditMode* m_pEditor = nullptr;