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;