First pass for getting things ready for grid snap button (#1118)
* first pass of change to simplify snapping for snap-to-grid button and fix snapping bug caused by non-uniform scale
This commit is contained in:
committed by
GitHub
parent
f20ae8345a
commit
05e20803a8
+14
-11
@@ -12,17 +12,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
|
||||
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
|
||||
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
{
|
||||
//! Create a linear manipulator with a unit sphere bounds.
|
||||
//! Create a linear manipulator with a unit sphere bound.
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> CreateLinearManipulator(
|
||||
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId,
|
||||
const AZ::Vector3& position = AZ::Vector3::CreateZero(),
|
||||
const float radius = 1.0f);
|
||||
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position = AZ::Vector3::CreateZero(),
|
||||
float radius = 1.0f);
|
||||
|
||||
//! Create a planar manipulator with a unit sphere bound.
|
||||
AZStd::shared_ptr<AzToolsFramework::PlanarManipulator> CreatePlanarManipulator(
|
||||
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position = AZ::Vector3::CreateZero(),
|
||||
float radius = 1.0f);
|
||||
|
||||
//! Create a mouse pick from the specified ray and screen point.
|
||||
AzToolsFramework::ViewportInteraction::MousePick CreateMousePick(
|
||||
@@ -34,14 +39,12 @@ namespace AzManipulatorTestFramework
|
||||
|
||||
//! Create a mouse interaction from the specified pick, buttons, interaction id and keyboard modifiers.
|
||||
AzToolsFramework::ViewportInteraction::MouseInteraction CreateMouseInteraction(
|
||||
const AzToolsFramework::ViewportInteraction::MousePick& mousePick,
|
||||
AzToolsFramework::ViewportInteraction::MouseButtons buttons,
|
||||
const AzToolsFramework::ViewportInteraction::MousePick& mousePick, AzToolsFramework::ViewportInteraction::MouseButtons buttons,
|
||||
AzToolsFramework::ViewportInteraction::InteractionId interactionId,
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifiers modifiers);
|
||||
|
||||
//! Create a mouse buttons from the specified mouse button.
|
||||
AzToolsFramework::ViewportInteraction::MouseButtons CreateMouseButtons(
|
||||
AzToolsFramework::ViewportInteraction::MouseButton button);
|
||||
AzToolsFramework::ViewportInteraction::MouseButtons CreateMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton button);
|
||||
|
||||
//! Create a mouse interaction event from the specified interaction and event.
|
||||
AzToolsFramework::ViewportInteraction::MouseInteractionEvent CreateMouseInteractionEvent(
|
||||
@@ -61,5 +64,5 @@ namespace AzManipulatorTestFramework
|
||||
AzFramework::ScreenPoint GetCameraStateViewportCenter(const AzFramework::CameraState& cameraState);
|
||||
|
||||
//! Default viewport size (1080p) in 16:9 aspect ratio.
|
||||
const auto DefaultViewportSize = AZ::Vector2(1920.0f, 1080.0f);
|
||||
inline const auto DefaultViewportSize = AZ::Vector2(1920.0f, 1080.0f);
|
||||
} // namespace AzManipulatorTestFramework
|
||||
|
||||
+36
-22
@@ -14,7 +14,6 @@
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
@@ -28,22 +27,21 @@ namespace AzManipulatorTestFramework
|
||||
using MouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent;
|
||||
using MousePick = AzToolsFramework::ViewportInteraction::MousePick;
|
||||
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> CreateLinearManipulator(
|
||||
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId,
|
||||
const AZ::Vector3& position,
|
||||
const float radius)
|
||||
// create a default sphere view for a manipulator for simple intersection
|
||||
template<typename Manipulator>
|
||||
void SetupManipulatorView(
|
||||
AZStd::shared_ptr<Manipulator> manipulator, const AzToolsFramework::ManipulatorManagerId manipulatorManagerId,
|
||||
const AZ::Vector3& position, const float radius)
|
||||
{
|
||||
auto manipulator = AzToolsFramework::LinearManipulator::MakeShared(AZ::Transform::CreateIdentity());
|
||||
manipulator->SetLocalPosition(position);
|
||||
|
||||
// unit sphere view
|
||||
auto sphereView = AzToolsFramework::CreateManipulatorViewSphere(
|
||||
AZ::Colors::Red, radius,
|
||||
[](const MouseInteraction& /*mouseInteraction*/, const bool /*mouseOver*/,
|
||||
const AZ::Color& defaultColor)
|
||||
{
|
||||
return defaultColor;
|
||||
}, true);
|
||||
[]([[maybe_unused]] const MouseInteraction& mouseInteraction, [[maybe_unused]] const bool mouseOver,
|
||||
const AZ::Color& defaultColor)
|
||||
{
|
||||
return defaultColor;
|
||||
},
|
||||
true);
|
||||
|
||||
// unit sphere bound
|
||||
AzToolsFramework::Picking::BoundShapeSphere sphereBound;
|
||||
@@ -62,6 +60,26 @@ namespace AzManipulatorTestFramework
|
||||
// this would occur internally when the manipulator is drawn but we must do manually here to ensure that the
|
||||
// bounds will always be valid upon instantiation
|
||||
view->RefreshBound(manipulatorManagerId, manipulator->GetManipulatorId(), sphereBound);
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> CreateLinearManipulator(
|
||||
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position, const float radius)
|
||||
{
|
||||
auto manipulator = AzToolsFramework::LinearManipulator::MakeShared(AZ::Transform::CreateIdentity());
|
||||
manipulator->SetLocalPosition(position);
|
||||
|
||||
SetupManipulatorView(manipulator, manipulatorManagerId, position, radius);
|
||||
|
||||
return manipulator;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzToolsFramework::PlanarManipulator> CreatePlanarManipulator(
|
||||
const AzToolsFramework::ManipulatorManagerId manipulatorManagerId, const AZ::Vector3& position, const float radius)
|
||||
{
|
||||
auto manipulator = AzToolsFramework::PlanarManipulator::MakeShared(AZ::Transform::CreateIdentity());
|
||||
manipulator->SetLocalPosition(position);
|
||||
|
||||
SetupManipulatorView(manipulator, manipulatorManagerId, position, radius);
|
||||
|
||||
return manipulator;
|
||||
}
|
||||
@@ -104,8 +122,7 @@ namespace AzManipulatorTestFramework
|
||||
return buttons;
|
||||
}
|
||||
|
||||
MouseInteractionEvent CreateMouseInteractionEvent(
|
||||
const MouseInteraction& mouseInteraction, MouseEvent event)
|
||||
MouseInteractionEvent CreateMouseInteractionEvent(const MouseInteraction& mouseInteraction, MouseEvent event)
|
||||
{
|
||||
return MouseInteractionEvent(mouseInteraction, event);
|
||||
}
|
||||
@@ -114,8 +131,7 @@ namespace AzManipulatorTestFramework
|
||||
{
|
||||
AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
AzToolsFramework::GetEntityContextId(),
|
||||
&AzToolsFramework::ViewportInteraction::InternalMouseViewportRequests::InternalHandleAllMouseInteractions,
|
||||
event);
|
||||
&AzToolsFramework::ViewportInteraction::InternalMouseViewportRequests::InternalHandleAllMouseInteractions, event);
|
||||
}
|
||||
|
||||
AzFramework::CameraState SetCameraStatePosition(const AZ::Vector3& position, AzFramework::CameraState& cameraState)
|
||||
@@ -133,9 +149,7 @@ namespace AzManipulatorTestFramework
|
||||
|
||||
AzFramework::ScreenPoint GetCameraStateViewportCenter(const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
return {
|
||||
aznumeric_cast<int>(cameraState.m_viewportSize.GetX() / 2.f),
|
||||
aznumeric_cast<int>(cameraState.m_viewportSize.GetY() / 2.f)
|
||||
};
|
||||
return { aznumeric_cast<int>(cameraState.m_viewportSize.GetX() / 2.f),
|
||||
aznumeric_cast<int>(cameraState.m_viewportSize.GetY() / 2.f) };
|
||||
}
|
||||
} // namespace UnitTest
|
||||
} // namespace AzManipulatorTestFramework
|
||||
|
||||
@@ -10,52 +10,55 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AzManipulatorTestFrameworkTestFixtures.h"
|
||||
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
|
||||
#include "AzManipulatorTestFrameworkTestFixtures.h"
|
||||
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
|
||||
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
|
||||
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
|
||||
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
|
||||
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
|
||||
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
|
||||
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
|
||||
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class GridSnappingFixture
|
||||
: public ToolsApplicationFixture
|
||||
class GridSnappingFixture : public ToolsApplicationFixture
|
||||
{
|
||||
public:
|
||||
GridSnappingFixture()
|
||||
: m_viewportManipulatorInteraction(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>())
|
||||
, m_actionDispatcher(AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
|
||||
, m_linearManipulator(
|
||||
AzManipulatorTestFramework::CreateLinearManipulator(
|
||||
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
|
||||
/*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f),
|
||||
/*radius=*/m_boundsRadius))
|
||||
{}
|
||||
, m_actionDispatcher(
|
||||
AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUpEditorFixtureImpl() override
|
||||
{
|
||||
m_cameraState = AzFramework::CreateIdentityDefaultCamera(
|
||||
AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
|
||||
m_cameraState =
|
||||
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
const float m_boundsRadius = 1.0f;
|
||||
AZStd::unique_ptr<AzManipulatorTestFramework::ManipulatorViewportInteraction> m_viewportManipulatorInteraction;
|
||||
AZStd::unique_ptr<AzManipulatorTestFramework::ImmediateModeActionDispatcher> m_actionDispatcher;
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_linearManipulator;
|
||||
AzFramework::CameraState m_cameraState;
|
||||
};
|
||||
|
||||
TEST_F(GridSnappingFixture, MouseDownWithSnappingEnabledSnapsToClosestGridSize)
|
||||
{
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator(
|
||||
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
|
||||
/*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f),
|
||||
/*radius=*/m_boundsRadius));
|
||||
|
||||
// the initial starting position of the manipulator (in front of the camera)
|
||||
const auto initialPositionWorld = m_linearManipulator->GetLocalPosition();
|
||||
const auto initialPositionWorld = linearManipulator->GetLocalPosition();
|
||||
// where the manipulator should end up (in front and to the left of the camera)
|
||||
const auto finalPositionWorld = AZ::Vector3(-10.0f, 50.0f, 0.0f);
|
||||
// perspective scale factor for manipulator distance to camera
|
||||
@@ -66,21 +69,18 @@ namespace UnitTest
|
||||
// adjusted final world position taking into account the manipulator position relative to the camera
|
||||
const auto finalPositionWorldAdjusted = finalPositionWorld - (vectorToInitialPositionWorld * scaledRadiusBound);
|
||||
// calculate the position in screen space of the initial position of the manipulator
|
||||
const auto initialPositionScreen =
|
||||
AzFramework::WorldToScreen(initialPositionWorld, m_cameraState);
|
||||
const auto initialPositionScreen = AzFramework::WorldToScreen(initialPositionWorld, m_cameraState);
|
||||
// calculate the position in screen space of the final position of the manipulator
|
||||
const auto finalPositionScreen = AzFramework::WorldToScreen(finalPositionWorldAdjusted, m_cameraState);
|
||||
|
||||
// callback to update the manipulator's current position
|
||||
m_linearManipulator->InstallMouseMoveCallback(
|
||||
[this](const AzToolsFramework::LinearManipulator::Action& action)
|
||||
{
|
||||
auto pos = action.LocalPosition();
|
||||
m_linearManipulator->SetLocalPosition(pos);
|
||||
});
|
||||
linearManipulator->InstallMouseMoveCallback(
|
||||
[this, linearManipulator](const AzToolsFramework::LinearManipulator::Action& action)
|
||||
{
|
||||
linearManipulator->SetLocalPosition(action.LocalPosition());
|
||||
});
|
||||
|
||||
m_actionDispatcher
|
||||
->EnableSnapToGrid()
|
||||
m_actionDispatcher->EnableSnapToGrid()
|
||||
->GridSize(5.0f)
|
||||
->CameraState(m_cameraState)
|
||||
->MousePosition(initialPositionScreen)
|
||||
@@ -89,7 +89,67 @@ namespace UnitTest
|
||||
->MousePosition(finalPositionScreen)
|
||||
->MouseLButtonUp()
|
||||
->ExpectManipulatorNotBeingInteracted()
|
||||
->ExpectTrue(m_linearManipulator->GetLocalPosition().IsClose(finalPositionWorld, 0.01f))
|
||||
;
|
||||
->ExpectTrue(linearManipulator->GetLocalPosition().IsClose(finalPositionWorld, 0.01f));
|
||||
}
|
||||
|
||||
template<typename Manipulator>
|
||||
void ValidateManipulatorSnappingBehavior(
|
||||
AZStd::shared_ptr<Manipulator> manipulator, AzManipulatorTestFramework::ImmediateModeActionDispatcher* actionDispatcher,
|
||||
const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
manipulator->SetLocalOrientation(AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(180.0f, 0.0f, 135.0f)));
|
||||
|
||||
// the initial starting position of the manipulator (in front of the camera)
|
||||
const auto initialPositionWorld = manipulator->GetLocalPosition() + AZ::Vector3::CreateAxisX(0.15f);
|
||||
// where the manipulator should end up (unmoved)
|
||||
const auto finalPositionWorld = manipulator->GetLocalPosition();
|
||||
// where we should move the mouse to
|
||||
const auto attemptPositionWorld = manipulator->GetLocalPosition() + AZ::Vector3::CreateAxisX(0.35f);
|
||||
// calculate the position in screen space of the initial position of the manipulator
|
||||
const auto initialPositionScreen = AzFramework::WorldToScreen(initialPositionWorld, cameraState);
|
||||
// calculate the position in screen space of the final position of the manipulator
|
||||
const auto attemptPositionScreen = AzFramework::WorldToScreen(attemptPositionWorld, cameraState);
|
||||
|
||||
// callback to update the manipulator's current position
|
||||
manipulator->InstallMouseMoveCallback(
|
||||
[manipulator](const typename Manipulator::Action& action)
|
||||
{
|
||||
manipulator->SetLocalPosition(action.LocalPosition());
|
||||
});
|
||||
|
||||
actionDispatcher->EnableSnapToGrid()
|
||||
->GridSize(1.0f)
|
||||
->CameraState(cameraState)
|
||||
->MousePosition(initialPositionScreen)
|
||||
->MouseLButtonDown()
|
||||
->ExpectManipulatorBeingInteracted()
|
||||
->MousePosition(attemptPositionScreen)
|
||||
->MouseLButtonUp()
|
||||
->ExpectManipulatorNotBeingInteracted()
|
||||
->ExpectThat(manipulator->GetLocalPosition(), IsCloseTolerance(finalPositionWorld, 0.01f));
|
||||
}
|
||||
|
||||
TEST_F(GridSnappingFixture, MouseDownAndMoveLinearManipulatorDoesNotSnapWithMovementSmallerThanHalfGridSize)
|
||||
{
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator(
|
||||
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
|
||||
/*position=*/AZ::Vector3(0.0f, 10.0f, 0.0f),
|
||||
/*radius=*/m_boundsRadius));
|
||||
|
||||
linearManipulator->SetAxis(AZ::Vector3::CreateAxisY());
|
||||
|
||||
ValidateManipulatorSnappingBehavior(linearManipulator, m_actionDispatcher.get(), m_cameraState);
|
||||
}
|
||||
|
||||
TEST_F(GridSnappingFixture, MouseDownAndMovePlanarManipulatorDoesNotSnapWithMovementSmallerThanHalfGridSize)
|
||||
{
|
||||
AZStd::shared_ptr<AzToolsFramework::PlanarManipulator> planarManipulator(AzManipulatorTestFramework::CreatePlanarManipulator(
|
||||
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
|
||||
/*position=*/AZ::Vector3(0.0f, 10.0f, 0.0f),
|
||||
/*radius=*/m_boundsRadius));
|
||||
|
||||
planarManipulator->SetAxes(AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
|
||||
|
||||
ValidateManipulatorSnappingBehavior(planarManipulator, m_actionDispatcher.get(), m_cameraState);
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -433,6 +433,11 @@ namespace AzToolsFramework
|
||||
return m_manipulatorSpaceWithLocalTransform.GetSpace();
|
||||
}
|
||||
|
||||
const AZ::Vector3& Manipulators::GetNonUniformScale() const
|
||||
{
|
||||
return m_manipulatorSpaceWithLocalTransform.GetNonUniformScale();
|
||||
}
|
||||
|
||||
void Manipulators::SetSpace(const AZ::Transform& worldFromLocal)
|
||||
{
|
||||
m_manipulatorSpaceWithLocalTransform.SetSpace(worldFromLocal);
|
||||
|
||||
+13
-14
@@ -192,8 +192,7 @@ namespace AzToolsFramework
|
||||
/// for each vertex associated with the translation manipulator to use with offset calculations when updating.
|
||||
template<typename Vertex>
|
||||
void InitializeVertexLookup(
|
||||
IndexedTranslationManipulator<Vertex>& translationManipulator,
|
||||
const AZ::EntityId entityId, const AZ::Vector3& snapOffset)
|
||||
IndexedTranslationManipulator<Vertex>& translationManipulator, const AZ::EntityId entityId)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
@@ -202,7 +201,7 @@ namespace AzToolsFramework
|
||||
AZ::FixedVerticesRequestBus<Vertex>::Bind(fixedVertices, entityId);
|
||||
|
||||
translationManipulator.Process(
|
||||
[snapOffset, fixedVertices]
|
||||
[fixedVertices]
|
||||
(typename IndexedTranslationManipulator<Vertex>::VertexLookup& vertexLookup)
|
||||
{
|
||||
Vertex vertex;
|
||||
@@ -213,7 +212,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (found)
|
||||
{
|
||||
vertexLookup.m_start = vertex + AZ::AdaptVertexIn<Vertex>(snapOffset);
|
||||
vertexLookup.m_start = vertex;
|
||||
vertexLookup.m_offset = Vertex::CreateZero();
|
||||
}
|
||||
});
|
||||
@@ -250,10 +249,10 @@ namespace AzToolsFramework
|
||||
|
||||
// linear manipulator callbacks
|
||||
m_translationManipulator->m_manipulator.InstallLinearManipulatorMouseDownCallback(
|
||||
[this](const LinearManipulator::Action& action)
|
||||
[this]([[maybe_unused]] const LinearManipulator::Action& action)
|
||||
{
|
||||
BeginBatchMovement();
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId(), action.m_start.m_positionSnapOffset);
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId());
|
||||
});
|
||||
|
||||
m_translationManipulator->m_manipulator.InstallLinearManipulatorMouseMoveCallback(
|
||||
@@ -264,17 +263,17 @@ namespace AzToolsFramework
|
||||
});
|
||||
|
||||
m_translationManipulator->m_manipulator.InstallLinearManipulatorMouseUpCallback(
|
||||
[this](const LinearManipulator::Action& /*action*/)
|
||||
[this]([[maybe_unused]] const LinearManipulator::Action& action)
|
||||
{
|
||||
EndBatchMovement();
|
||||
});
|
||||
|
||||
// planar manipulator callbacks
|
||||
m_translationManipulator->m_manipulator.InstallPlanarManipulatorMouseDownCallback(
|
||||
[this](const PlanarManipulator::Action& action)
|
||||
[this]([[maybe_unused]] const PlanarManipulator::Action& action)
|
||||
{
|
||||
BeginBatchMovement();
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId(), action.m_start.m_snapOffset);
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId());
|
||||
});
|
||||
|
||||
m_translationManipulator->m_manipulator.InstallPlanarManipulatorMouseMoveCallback(
|
||||
@@ -285,17 +284,17 @@ namespace AzToolsFramework
|
||||
});
|
||||
|
||||
m_translationManipulator->m_manipulator.InstallPlanarManipulatorMouseUpCallback(
|
||||
[this](const PlanarManipulator::Action& /*action*/)
|
||||
[this]([[maybe_unused]] const PlanarManipulator::Action& action)
|
||||
{
|
||||
EndBatchMovement();
|
||||
});
|
||||
|
||||
// surface manipulator callbacks
|
||||
m_translationManipulator->m_manipulator.InstallSurfaceManipulatorMouseDownCallback(
|
||||
[this](const SurfaceManipulator::Action& action)
|
||||
[this]([[maybe_unused]] const SurfaceManipulator::Action& action)
|
||||
{
|
||||
BeginBatchMovement();
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId(), action.m_start.m_snapOffset);
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId());
|
||||
});
|
||||
|
||||
m_translationManipulator->m_manipulator.InstallSurfaceManipulatorMouseMoveCallback(
|
||||
@@ -306,7 +305,7 @@ namespace AzToolsFramework
|
||||
});
|
||||
|
||||
m_translationManipulator->m_manipulator.InstallSurfaceManipulatorMouseUpCallback(
|
||||
[this](const SurfaceManipulator::Action& /*action*/)
|
||||
[this]([[maybe_unused]] const SurfaceManipulator::Action& action)
|
||||
{
|
||||
EndBatchMovement();
|
||||
});
|
||||
@@ -893,7 +892,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
BeginBatchMovement();
|
||||
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId(), AZ::Vector3::CreateZero());
|
||||
InitializeVertexLookup(*m_translationManipulator, GetEntityId());
|
||||
// note: AdaptVertexIn/Out is to ensure we clamp the vertex local Z position to 0 if
|
||||
// dealing with Vector2s when setting the position of the manipulator.
|
||||
const AZ::Vector3 localOffset =
|
||||
|
||||
+26
-44
@@ -23,8 +23,8 @@ namespace AzToolsFramework
|
||||
{
|
||||
LinearManipulator::Starter CalculateLinearManipulationDataStart(
|
||||
const LinearManipulator::Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Transform& localTransform, const GridSnapAction& gridSnapAction, const ViewportInteraction::MouseInteraction& interaction,
|
||||
const float intersectionDistance, const AzFramework::CameraState& cameraState)
|
||||
const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, const float intersectionDistance,
|
||||
const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
const ManipulatorInteraction manipulatorInteraction =
|
||||
BuildManipulatorInteraction(
|
||||
@@ -50,28 +50,9 @@ namespace AzToolsFramework
|
||||
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection,
|
||||
localIntersectionPoint, startTransition.m_localNormal, start.m_localHitPosition);
|
||||
|
||||
const float gridSize = gridSnapAction.m_gridSnapParams.m_gridSize;
|
||||
const bool snapping = gridSnapAction.m_gridSnapParams.m_gridSnap;
|
||||
const float scaleRecip = manipulatorInteraction.m_scaleReciprocal;
|
||||
|
||||
// calculate position amount to snap, to align with grid
|
||||
const AZ::Vector3 positionSnapOffset = snapping && !gridSnapAction.m_localSnapping
|
||||
? CalculateSnappedOffset(localTransform.GetTranslation(), axis, gridSize * scaleRecip)
|
||||
: AZ::Vector3::CreateZero();
|
||||
|
||||
const AZ::Vector3 localScale = AZ::Vector3(localTransform.GetUniformScale());
|
||||
const AZ::Quaternion localRotation = QuaternionFromTransformNoScaling(localTransform);
|
||||
// calculate scale amount to snap, to align to round scale value
|
||||
const AZ::Vector3 scaleSnapOffset = snapping && !gridSnapAction.m_localSnapping
|
||||
? localRotation.GetInverseFull().TransformVector(CalculateSnappedOffset(
|
||||
localRotation.TransformVector(localScale), axis, gridSize * scaleRecip))
|
||||
: AZ::Vector3::CreateZero();
|
||||
|
||||
start.m_screenPosition = interaction.m_mousePick.m_screenCoordinates;
|
||||
start.m_positionSnapOffset = positionSnapOffset;
|
||||
start.m_scaleSnapOffset = scaleSnapOffset;
|
||||
start.m_localPosition = localTransform.GetTranslation() + positionSnapOffset;
|
||||
start.m_localScale = localScale + scaleSnapOffset;
|
||||
start.m_localPosition = localTransform.GetTranslation();
|
||||
start.m_localScale = AZ::Vector3(localTransform.GetUniformScale());;
|
||||
start.m_localAxis = axis;
|
||||
// sign to determine which side of the linear axis we pressed
|
||||
// (useful to know when the visual axis flips to face the camera)
|
||||
@@ -87,7 +68,7 @@ namespace AzToolsFramework
|
||||
LinearManipulator::Action CalculateLinearManipulationDataAction(
|
||||
const LinearManipulator::Fixed& fixed, const LinearManipulator::Starter& starter,
|
||||
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
|
||||
const GridSnapAction& gridSnapAction, const ViewportInteraction::MouseInteraction& interaction)
|
||||
const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction)
|
||||
{
|
||||
const ManipulatorInteraction manipulatorInteraction =
|
||||
BuildManipulatorInteraction(
|
||||
@@ -108,31 +89,34 @@ namespace AzToolsFramework
|
||||
GetCameraState(interaction.m_interactionId.m_viewportId));
|
||||
|
||||
const AZ::Vector3 axis = TransformDirectionNoScaling(localTransform, fixed.m_axis);
|
||||
// The local positions have been transformed to the reference frame of the object being manipulated. But they appear in the world
|
||||
// with non-uniform scale applied, and the object being manipulated will want to work with unscaled deltas, so we need to divide by
|
||||
// the non-uniform scale here.
|
||||
// the local positions have been transformed to the reference frame of the object being manipulated, but they appear in the world
|
||||
// with non-uniform scale applied, the object being manipulated will want to work with unscaled deltas, so we need to divide by
|
||||
// the non-uniform scale here
|
||||
const AZ::Vector3 hitDelta = (localHitPosition - start.m_localHitPosition) / nonUniformScale;
|
||||
const AZ::Vector3 unsnappedOffset = axis * axis.Dot(hitDelta);
|
||||
|
||||
const float scaleRecip = manipulatorInteraction.m_scaleReciprocal * axis.Dot(manipulatorInteraction.m_nonUniformScaleReciprocal);
|
||||
const float gridSize = gridSnapAction.m_gridSnapParams.m_gridSize;
|
||||
const bool snapping = gridSnapAction.m_gridSnapParams.m_gridSnap;
|
||||
const float scaleRecip =
|
||||
manipulatorInteraction.m_scaleReciprocal * fixed.m_axis.Dot(manipulatorInteraction.m_nonUniformScaleReciprocal);
|
||||
const float gridSize = gridSnapParams.m_gridSize;
|
||||
const bool snapping = gridSnapParams.m_gridSnap;
|
||||
|
||||
LinearManipulator::Action action;
|
||||
action.m_fixed = fixed;
|
||||
action.m_start = start;
|
||||
action.m_current.m_localPositionOffset = snapping
|
||||
? unsnappedOffset + CalculateSnappedOffset(unsnappedOffset, axis, gridSize * scaleRecip)
|
||||
? CalculateSnappedAmount(unsnappedOffset, axis, gridSize * scaleRecip)
|
||||
: unsnappedOffset;
|
||||
action.m_current.m_screenPosition = interaction.m_mousePick.m_screenCoordinates;
|
||||
action.m_viewportId = interaction.m_interactionId.m_viewportId;
|
||||
|
||||
const AZ::Quaternion localRotation = QuaternionFromTransformNoScaling(localTransform);
|
||||
const AZ::Vector3 scaledUnsnappedOffset = unsnappedOffset * startTransition.m_screenToWorldScale * NonUniformScaleReciprocal(nonUniformScale);
|
||||
const AZ::Vector3 scaledUnsnappedOffset =
|
||||
unsnappedOffset * startTransition.m_screenToWorldScale * NonUniformScaleReciprocal(nonUniformScale);
|
||||
|
||||
// how much to adjust the scale based on movement
|
||||
const AZ::Quaternion invLocalRotation = localRotation.GetInverseFull();
|
||||
action.m_current.m_localScaleOffset = snapping
|
||||
? invLocalRotation.TransformVector((scaledUnsnappedOffset + CalculateSnappedOffset(scaledUnsnappedOffset, axis, gridSize * scaleRecip)))
|
||||
? invLocalRotation.TransformVector(CalculateSnappedAmount(scaledUnsnappedOffset, axis, gridSize * scaleRecip))
|
||||
: invLocalRotation.TransformVector(scaledUnsnappedOffset);
|
||||
|
||||
// record what modifier keys are held during this action
|
||||
@@ -171,19 +155,18 @@ namespace AzToolsFramework
|
||||
const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance)
|
||||
{
|
||||
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
// note: m_localTransform must not be made uniform as it may contain a local scale we want to snap
|
||||
m_starter = CalculateLinearManipulationDataStart(
|
||||
m_fixed, worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction, rayIntersectionDistance,
|
||||
m_fixed, worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, rayIntersectionDistance,
|
||||
GetCameraState(interaction.m_interactionId.m_viewportId));
|
||||
|
||||
if (m_onLeftMouseDownCallback)
|
||||
{
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
m_onLeftMouseDownCallback(CalculateLinearManipulationDataAction(
|
||||
m_fixed, m_starter, worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction));
|
||||
m_fixed, m_starter, worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), gridSnapParams, interaction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,8 +178,8 @@ namespace AzToolsFramework
|
||||
|
||||
// note: m_localTransform must not be made uniform as it may contain a local scale we want to snap
|
||||
m_onMouseMoveCallback(CalculateLinearManipulationDataAction(
|
||||
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction));
|
||||
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams,
|
||||
interaction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,8 +191,7 @@ namespace AzToolsFramework
|
||||
|
||||
// note: m_localTransform must not be made uniform as it may contain a local scale we want to snap
|
||||
m_onLeftMouseUpCallback(CalculateLinearManipulationDataAction(
|
||||
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction));
|
||||
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams, interaction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,8 +214,8 @@ namespace AzToolsFramework
|
||||
GridSnapSettings(mouseInteraction.m_interactionId.m_viewportId);
|
||||
|
||||
const auto action = CalculateLinearManipulationDataAction(
|
||||
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(),
|
||||
GridSnapAction(gridSnapParams, mouseInteraction.m_keyboardModifiers.Alt()), mouseInteraction);
|
||||
m_fixed, m_starter, TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalTransform(), gridSnapParams,
|
||||
mouseInteraction);
|
||||
|
||||
// display the exact hit (ray intersection) of the mouse pick on the manipulator
|
||||
DrawTransformAxes(
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
struct GridSnapAction;
|
||||
struct GridSnapParameters;
|
||||
|
||||
/// LinearManipulator serves as a visual tool for users to modify values
|
||||
/// in one dimension on an axis defined in 3D space.
|
||||
@@ -68,8 +68,6 @@ namespace AzToolsFramework
|
||||
AZ::Vector3 m_localScale; ///< The current scale of the manipulator in local space.
|
||||
AZ::Vector3 m_localHitPosition; ///< The intersection point in local space between the ray and the manipulator when the mouse down event happens.
|
||||
AZ::Vector3 m_localAxis; ///< The axis in the local space of the manipulator itself.
|
||||
AZ::Vector3 m_positionSnapOffset; ///< The snap offset amount to ensure manipulator is aligned to the grid.
|
||||
AZ::Vector3 m_scaleSnapOffset; ///< The snap offset amount to ensure manipulator is aligned to round scale increments.
|
||||
float m_sign; ///< Used to determine which side of the axis we clicked on in case it's flipped to face the camera.
|
||||
AzFramework::ScreenPoint m_screenPosition; ///< The initial position in screen space of the manipulator.
|
||||
};
|
||||
@@ -91,7 +89,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::KeyboardModifiers m_modifiers;
|
||||
int m_viewportId; ///< The id of the viewport this manipulator is being used in.
|
||||
AZ::Vector3 LocalScale() const { return m_start.m_localScale + m_current.m_localScaleOffset; }
|
||||
AZ::Vector3 LocalScaleOffset() const { return m_start.m_scaleSnapOffset + m_current.m_localScaleOffset; }
|
||||
AZ::Vector3 LocalScaleOffset() const { return m_current.m_localScaleOffset; }
|
||||
AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localPositionOffset; }
|
||||
AZ::Vector3 LocalPositionOffset() const { return m_current.m_localPositionOffset; }
|
||||
AZ::Vector2 ScreenOffset() const
|
||||
@@ -162,11 +160,11 @@ namespace AzToolsFramework
|
||||
|
||||
LinearManipulator::Starter CalculateLinearManipulationDataStart(
|
||||
const LinearManipulator::Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Transform& localTransform, const GridSnapAction& gridSnapAction, const ViewportInteraction::MouseInteraction& interaction,
|
||||
float intersectionDistance, const AzFramework::CameraState& cameraState);
|
||||
const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, float intersectionDistance,
|
||||
const AzFramework::CameraState& cameraState);
|
||||
|
||||
LinearManipulator::Action CalculateLinearManipulationDataAction(
|
||||
const LinearManipulator::Fixed& fixed, const LinearManipulator::Starter& starter,
|
||||
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
|
||||
const GridSnapAction& gridSnapAction, const ViewportInteraction::MouseInteraction& interaction);
|
||||
const GridSnapParameters& gridSnapParams, const ViewportInteraction::MouseInteraction& interaction);
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+25
-11
@@ -42,12 +42,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
}
|
||||
|
||||
GridSnapAction::GridSnapAction(const GridSnapParameters& gridSnapParameters, const bool localSnapping)
|
||||
: m_gridSnapParams(gridSnapParameters)
|
||||
, m_localSnapping(localSnapping)
|
||||
{
|
||||
}
|
||||
|
||||
ManipulatorInteraction BuildManipulatorInteraction(
|
||||
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Vector3& worldRayOrigin, const AZ::Vector3& worldRayDirection)
|
||||
@@ -57,19 +51,39 @@ namespace AzToolsFramework
|
||||
|
||||
return {localFromWorldUniform.TransformPoint(worldRayOrigin),
|
||||
TransformDirectionNoScaling(localFromWorldUniform, worldRayDirection),
|
||||
ScaleReciprocal(worldFromLocalUniform),
|
||||
NonUniformScaleReciprocal(nonUniformScale)};
|
||||
NonUniformScaleReciprocal(nonUniformScale),
|
||||
ScaleReciprocal(worldFromLocalUniform)};
|
||||
}
|
||||
|
||||
AZ::Vector3 CalculateSnappedOffset(
|
||||
const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, const float size)
|
||||
struct SnapAdjustment
|
||||
{
|
||||
float m_existingSnapDistance; //!< How far to snap up or down to align to the grid.
|
||||
float m_nextSnapDistance; //!< The snap increment (will return full signed value (grid size) when distance
|
||||
//!< moved is greater than half of the grid size in either direction).
|
||||
};
|
||||
|
||||
static SnapAdjustment CalculateSnapDistance(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, const float size)
|
||||
{
|
||||
// calculate total distance along axis
|
||||
const float axisDistance = axis.Dot(unsnappedPosition);
|
||||
// round to nearest step size
|
||||
const float snappedAxisDistance = floorf((axisDistance / size) + 0.5f) * size;
|
||||
|
||||
return { axisDistance, snappedAxisDistance };
|
||||
}
|
||||
|
||||
AZ::Vector3 CalculateSnappedOffset(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, const float size)
|
||||
{
|
||||
const auto snapAdjustment = CalculateSnapDistance(unsnappedPosition, axis, size);
|
||||
// return offset along axis to snap to step size
|
||||
return axis * (snappedAxisDistance - axisDistance);
|
||||
return axis * (snapAdjustment.m_nextSnapDistance - snapAdjustment.m_existingSnapDistance);
|
||||
}
|
||||
|
||||
AZ::Vector3 CalculateSnappedAmount(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, const float size)
|
||||
{
|
||||
const auto snapAdjustment = CalculateSnapDistance(unsnappedPosition, axis, size);
|
||||
// return offset along axis to snap to step size
|
||||
return axis * snapAdjustment.m_nextSnapDistance;
|
||||
}
|
||||
|
||||
AZ::Vector3 CalculateSnappedTerrainPosition(
|
||||
|
||||
+9
-13
@@ -31,24 +31,15 @@ namespace AzToolsFramework
|
||||
float m_gridSize;
|
||||
};
|
||||
|
||||
/// Structure to encapsulate the current grid snapping state.
|
||||
struct GridSnapAction
|
||||
{
|
||||
GridSnapAction(const GridSnapParameters& gridSnapParameters, bool localSnapping);
|
||||
|
||||
GridSnapParameters m_gridSnapParams;
|
||||
bool m_localSnapping;
|
||||
};
|
||||
|
||||
/// Structure to hold transformed incoming viewport interaction from world space to manipulator space.
|
||||
struct ManipulatorInteraction
|
||||
{
|
||||
AZ::Vector3 m_localRayOrigin; ///< The ray origin (start) in the reference from of the manipulator.
|
||||
AZ::Vector3 m_localRayDirection; ///< The ray direction in the reference from of the manipulator.
|
||||
float m_scaleReciprocal; ///< The scale reciprocal (1.0 / scale) of the transform used to move the
|
||||
///< ray from world space to local space.
|
||||
AZ::Vector3 m_nonUniformScaleReciprocal; ///< Handles inverting any non-uniform scale which was applied
|
||||
///< separately from the transform.
|
||||
float m_scaleReciprocal; ///< The scale reciprocal (1.0 / scale) of the transform used to move the
|
||||
///< ray from world space to local space.
|
||||
};
|
||||
|
||||
/// Build a ManipulatorInteraction structure from the incoming viewport interaction.
|
||||
@@ -56,11 +47,16 @@ namespace AzToolsFramework
|
||||
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Vector3& worldRayOrigin, const AZ::Vector3& worldRayDirection);
|
||||
|
||||
/// Calculate the offset along an axis to adjust a position
|
||||
/// to stay snapped to a given grid size.
|
||||
/// Calculate the offset along an axis to adjust a position to stay snapped to a given grid size.
|
||||
/// @note This is snap up or down to the nearest grid segment (e.g. 0.2 snaps to 0.0 -> delta 0.2,
|
||||
/// 0.7 snaps to 1.0 -> delta 0.3).
|
||||
AZ::Vector3 CalculateSnappedOffset(
|
||||
const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size);
|
||||
|
||||
/// Return the amount to snap from the starting position given the current grid size.
|
||||
/// @note A movement of more than half size (in either direction) will cause a snap by size.
|
||||
AZ::Vector3 CalculateSnappedAmount(const AZ::Vector3& unsnappedPosition, const AZ::Vector3& axis, float size);
|
||||
|
||||
/// For a given point on the terrain, calculate the closest xy position snapped to the grid
|
||||
/// (z position is aligned to terrain height, not snapped to z grid)
|
||||
AZ::Vector3 CalculateSnappedTerrainPosition(
|
||||
|
||||
+10
-18
@@ -59,17 +59,16 @@ namespace AzToolsFramework
|
||||
const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
|
||||
const ViewportInteraction::MouseInteraction& interaction,
|
||||
const AZStd::vector<LinearManipulator::Fixed>& fixedAxes,
|
||||
const AZStd::vector<LinearManipulator::Starter>& starterStates, const GridSnapAction& gridSnapAction)
|
||||
const AZStd::vector<LinearManipulator::Starter>& starterStates, const GridSnapParameters& gridSnapParams)
|
||||
{
|
||||
MultiLinearManipulator::Action action;
|
||||
action.m_viewportId = interaction.m_interactionId.m_viewportId;
|
||||
// build up action state for each axis
|
||||
for (size_t fixedIndex = 0; fixedIndex < fixedAxes.size(); ++fixedIndex)
|
||||
{
|
||||
action.m_actions.push_back(
|
||||
CalculateLinearManipulationDataAction(
|
||||
fixedAxes[fixedIndex], starterStates[fixedIndex], worldFromLocal, nonUniformScale, localTransform,
|
||||
gridSnapAction, interaction));
|
||||
action.m_actions.push_back(CalculateLinearManipulationDataAction(
|
||||
fixedAxes[fixedIndex], starterStates[fixedIndex], worldFromLocal, nonUniformScale, localTransform, gridSnapParams,
|
||||
interaction));
|
||||
}
|
||||
|
||||
return action;
|
||||
@@ -79,8 +78,6 @@ namespace AzToolsFramework
|
||||
const ViewportInteraction::MouseInteraction& interaction, const float rayIntersectionDistance)
|
||||
{
|
||||
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
const AzFramework::CameraState cameraState = GetCameraState(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
// build up initial start state for each axis
|
||||
@@ -88,20 +85,19 @@ namespace AzToolsFramework
|
||||
{
|
||||
// note: m_localTransform must not be made uniform as it may contain a local scale we want to snap
|
||||
const auto linearStart = CalculateLinearManipulationDataStart(
|
||||
fixed, worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction,
|
||||
rayIntersectionDistance, cameraState);
|
||||
fixed, worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(), interaction, rayIntersectionDistance,
|
||||
cameraState);
|
||||
|
||||
m_starters.push_back(linearStart);
|
||||
}
|
||||
|
||||
if (m_onLeftMouseDownCallback)
|
||||
{
|
||||
const GridSnapAction gridSnapAction = GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt());
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
// pass action containing all linear actions for each axis to handler
|
||||
m_onLeftMouseDownCallback(BuildMultiLinearManipulatorAction(
|
||||
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
|
||||
interaction, m_fixedAxes, m_starters, gridSnapAction));
|
||||
interaction, m_fixedAxes, m_starters, gridSnapParams));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +107,9 @@ namespace AzToolsFramework
|
||||
{
|
||||
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
const GridSnapAction gridSnapAction = GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt());
|
||||
|
||||
m_onMouseMoveCallback(BuildMultiLinearManipulatorAction(
|
||||
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
|
||||
interaction, m_fixedAxes, m_starters, gridSnapAction));
|
||||
interaction, m_fixedAxes, m_starters, gridSnapParams));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,11 +119,9 @@ namespace AzToolsFramework
|
||||
{
|
||||
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
const GridSnapAction gridSnapAction = GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt());
|
||||
|
||||
m_onLeftMouseUpCallback(BuildMultiLinearManipulatorAction(
|
||||
worldFromLocalUniformScale, GetNonUniformScale(), GetLocalTransform(),
|
||||
interaction, m_fixedAxes, m_starters, gridSnapAction));
|
||||
interaction, m_fixedAxes, m_starters, gridSnapParams));
|
||||
|
||||
m_starters.clear();
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
struct GridSnapAction;
|
||||
|
||||
//! MultiLinearManipulator serves as a visual tool for users to modify values
|
||||
//! in one or more dimensions on axes defined in 3D space.
|
||||
class MultiLinearManipulator
|
||||
|
||||
+15
-35
@@ -22,8 +22,7 @@
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
PlanarManipulator::StartInternal PlanarManipulator::CalculateManipulationDataStart(
|
||||
const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Transform& localTransform, const GridSnapAction& gridSnapAction,
|
||||
const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
|
||||
const ViewportInteraction::MouseInteraction& interaction, const float intersectionDistance)
|
||||
{
|
||||
const ManipulatorInteraction manipulatorInteraction =
|
||||
@@ -31,8 +30,6 @@ namespace AzToolsFramework
|
||||
worldFromLocal, nonUniformScale, interaction.m_mousePick.m_rayOrigin, interaction.m_mousePick.m_rayDirection);
|
||||
|
||||
const AZ::Vector3 normal = TransformDirectionNoScaling(localTransform, fixed.m_normal);
|
||||
const AZ::Vector3 axis1 = TransformDirectionNoScaling(localTransform, fixed.m_axis1);
|
||||
const AZ::Vector3 axis2 = TransformDirectionNoScaling(localTransform, fixed.m_axis2);
|
||||
|
||||
// initial intersect point
|
||||
const AZ::Vector3 localIntersectionPoint =
|
||||
@@ -43,25 +40,14 @@ namespace AzToolsFramework
|
||||
manipulatorInteraction.m_localRayOrigin, manipulatorInteraction.m_localRayDirection,
|
||||
localIntersectionPoint, normal, startInternal.m_localHitPosition);
|
||||
|
||||
const float scaleRecip = manipulatorInteraction.m_scaleReciprocal;
|
||||
const float gridSize = gridSnapAction.m_gridSnapParams.m_gridSize;
|
||||
const bool snapping = gridSnapAction.m_gridSnapParams.m_gridSnap;
|
||||
|
||||
// calculate amount to snap to align with grid
|
||||
const AZ::Vector3 snapOffset = snapping && !gridSnapAction.m_localSnapping
|
||||
? CalculateSnappedOffset(localTransform.GetTranslation(), axis1, gridSize * scaleRecip) +
|
||||
CalculateSnappedOffset(localTransform.GetTranslation(), axis2, gridSize * scaleRecip)
|
||||
: AZ::Vector3::CreateZero();
|
||||
|
||||
startInternal.m_snapOffset = snapOffset;
|
||||
startInternal.m_localPosition = localTransform.GetTranslation() + snapOffset;
|
||||
startInternal.m_localPosition = localTransform.GetTranslation();
|
||||
|
||||
return startInternal;
|
||||
}
|
||||
|
||||
PlanarManipulator::Action PlanarManipulator::CalculateManipulationDataAction(
|
||||
const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal,
|
||||
const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform, const GridSnapAction& gridSnapAction,
|
||||
const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Transform& localTransform, const GridSnapParameters& gridSnapParams,
|
||||
const ViewportInteraction::MouseInteraction& interaction)
|
||||
{
|
||||
const ManipulatorInteraction manipulatorInteraction =
|
||||
@@ -88,20 +74,18 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3 hitDelta = (localHitPosition - startInternal.m_localHitPosition) / nonUniformScale;
|
||||
const AZ::Vector3 unsnappedOffset = axis1.Dot(hitDelta) * axis1 + axis2.Dot(hitDelta) * axis2;
|
||||
|
||||
const float scaleRecip = manipulatorInteraction.m_scaleReciprocal;
|
||||
const AZ::Vector3 nonUniformScaleRecip = manipulatorInteraction.m_nonUniformScaleReciprocal;
|
||||
const float gridSize = gridSnapAction.m_gridSnapParams.m_gridSize;
|
||||
const bool snapping = gridSnapAction.m_gridSnapParams.m_gridSnap;
|
||||
const float scaleRecip = manipulatorInteraction.m_scaleReciprocal;
|
||||
const float gridSize = gridSnapParams.m_gridSize;
|
||||
const bool snapping = gridSnapParams.m_gridSnap;
|
||||
|
||||
Action action;
|
||||
action.m_fixed = fixed;
|
||||
action.m_start.m_localPosition = startInternal.m_localPosition;
|
||||
action.m_start.m_snapOffset = startInternal.m_snapOffset;
|
||||
action.m_start.m_localHitPosition = startInternal.m_localHitPosition;
|
||||
action.m_current.m_localOffset = snapping
|
||||
? unsnappedOffset +
|
||||
CalculateSnappedOffset(unsnappedOffset, axis1, gridSize * scaleRecip * nonUniformScaleRecip.Dot(axis1)) +
|
||||
CalculateSnappedOffset(unsnappedOffset, axis2, gridSize * scaleRecip * nonUniformScaleRecip.Dot(axis2))
|
||||
? CalculateSnappedAmount(unsnappedOffset, axis1, gridSize * scaleRecip * nonUniformScaleRecip.Dot(fixed.m_axis1)) +
|
||||
CalculateSnappedAmount(unsnappedOffset, axis2, gridSize * scaleRecip * nonUniformScaleRecip.Dot(fixed.m_axis2))
|
||||
: unsnappedOffset;
|
||||
|
||||
// record what modifier keys are held during this action
|
||||
@@ -141,18 +125,17 @@ namespace AzToolsFramework
|
||||
{
|
||||
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
m_startInternal = CalculateManipulationDataStart(
|
||||
m_fixed, worldFromLocalUniformScale, GetNonUniformScale(), TransformNormalizedScale(GetLocalTransform()),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()),
|
||||
interaction, rayIntersectionDistance);
|
||||
|
||||
if (m_onLeftMouseDownCallback)
|
||||
{
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
m_onLeftMouseDownCallback(CalculateManipulationDataAction(
|
||||
m_fixed, m_startInternal, worldFromLocalUniformScale, GetNonUniformScale(), TransformNormalizedScale(GetLocalTransform()),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction));
|
||||
gridSnapParams, interaction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +147,7 @@ namespace AzToolsFramework
|
||||
|
||||
m_onMouseMoveCallback(CalculateManipulationDataAction(
|
||||
m_fixed, m_startInternal, TransformUniformScale(GetSpace()), GetNonUniformScale(),
|
||||
TransformNormalizedScale(GetLocalTransform()),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction));
|
||||
TransformNormalizedScale(GetLocalTransform()), gridSnapParams, interaction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,8 +159,7 @@ namespace AzToolsFramework
|
||||
|
||||
m_onLeftMouseUpCallback(CalculateManipulationDataAction(
|
||||
m_fixed, m_startInternal, TransformUniformScale(GetSpace()), GetNonUniformScale(),
|
||||
TransformNormalizedScale(GetLocalTransform()),
|
||||
GridSnapAction(gridSnapParams, interaction.m_keyboardModifiers.Alt()), interaction));
|
||||
TransformNormalizedScale(GetLocalTransform()), gridSnapParams, interaction));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,8 +176,7 @@ namespace AzToolsFramework
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(mouseInteraction.m_interactionId.m_viewportId);
|
||||
const auto action = CalculateManipulationDataAction(
|
||||
m_fixed, m_startInternal, TransformUniformScale(GetSpace()), GetNonUniformScale(),
|
||||
TransformNormalizedScale(GetLocalTransform()),
|
||||
GridSnapAction(gridSnapParams, mouseInteraction.m_keyboardModifiers.Alt()), mouseInteraction);
|
||||
TransformNormalizedScale(GetLocalTransform()), gridSnapParams, mouseInteraction);
|
||||
|
||||
// display the exact hit (ray intersection) of the mouse pick on the manipulator
|
||||
DrawTransformAxes(
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class ManipulatorView;
|
||||
struct GridSnapAction;
|
||||
struct GridSnapParameters;
|
||||
|
||||
/// PlanarManipulator serves as a visual tool for users to modify values
|
||||
/// in two dimension in a plane defined two non-collinear axes in 3D space.
|
||||
@@ -58,7 +58,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZ::Vector3 m_localPosition; ///< The current position of the manipulator in local space.
|
||||
AZ::Vector3 m_localHitPosition; ///< The intersection point in local space between the ray and the manipulator when the mouse down event happens.
|
||||
AZ::Vector3 m_snapOffset; ///< The snap offset amount to ensure manipulator is aligned to the grid.
|
||||
};
|
||||
|
||||
/// The state of the manipulator during an interaction.
|
||||
@@ -120,7 +119,6 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZ::Vector3 m_localPosition; ///< The starting position of the manipulator in local space.
|
||||
AZ::Vector3 m_localHitPosition; ///< The intersection point in world space between the ray and the manipulator when the mouse down event happens.
|
||||
AZ::Vector3 m_snapOffset; ///< The snap offset amount to ensure manipulator is aligned to the grid.
|
||||
};
|
||||
|
||||
Fixed m_fixed;
|
||||
@@ -134,12 +132,11 @@ namespace AzToolsFramework
|
||||
|
||||
static StartInternal CalculateManipulationDataStart(
|
||||
const Fixed& fixed, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Transform& localTransform, const GridSnapAction& gridSnapAction,
|
||||
const ViewportInteraction::MouseInteraction& interaction, float intersectionDistance);
|
||||
const AZ::Transform& localTransform, const ViewportInteraction::MouseInteraction& interaction, float intersectionDistance);
|
||||
|
||||
static Action CalculateManipulationDataAction(
|
||||
const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal,
|
||||
const AZ::Vector3& nonUniformScale, const AZ::Transform& localTransform,
|
||||
const GridSnapAction& gridSnapAction, const ViewportInteraction::MouseInteraction& interaction);
|
||||
const Fixed& fixed, const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale,
|
||||
const AZ::Transform& localTransform, const GridSnapParameters& gridSnapParams,
|
||||
const ViewportInteraction::MouseInteraction& interaction);
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+28
-20
@@ -37,13 +37,13 @@ namespace AzToolsFramework
|
||||
axisLength, AzFramework::ViewportColors::XAxisColor, AzFramework::ViewportColors::YAxisColor,
|
||||
AzFramework::ViewportColors::ZAxisColor);
|
||||
|
||||
auto mouseDownCallback = [this](const LinearManipulator::Action& action) {
|
||||
auto mouseDownCallback = [this]([[maybe_unused]] const LinearManipulator::Action& action)
|
||||
{
|
||||
AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne();
|
||||
|
||||
AZ::NonUniformScaleRequestBus::EventResult(
|
||||
nonUniformScale, m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::GetScale);
|
||||
|
||||
m_initialScale = nonUniformScale + action.m_start.m_scaleSnapOffset;
|
||||
m_initialScale = nonUniformScale;
|
||||
|
||||
AZ::NonUniformScaleRequestBus::Event(
|
||||
m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale, m_initialScale);
|
||||
@@ -51,29 +51,37 @@ namespace AzToolsFramework
|
||||
|
||||
m_manipulators->InstallAxisLeftMouseDownCallback(mouseDownCallback);
|
||||
|
||||
m_manipulators->InstallAxisMouseMoveCallback([this](const LinearManipulator::Action& action) {
|
||||
const AZ::Vector3 scaleMultiplier =
|
||||
(AZ::Vector3::CreateOne() + ((action.LocalScaleOffset() * action.m_start.m_sign) / m_initialScale));
|
||||
m_manipulators->InstallAxisMouseMoveCallback(
|
||||
[this](const LinearManipulator::Action& action)
|
||||
{
|
||||
const AZ::Vector3 scaleMultiplier =
|
||||
(AZ::Vector3::CreateOne() + ((action.LocalScaleOffset() * action.m_start.m_sign) / m_initialScale));
|
||||
|
||||
AZ::NonUniformScaleRequestBus::Event(
|
||||
m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale,
|
||||
(scaleMultiplier * m_initialScale).GetClamp(AZ::Vector3(AZ::MinTransformScale), AZ::Vector3(AZ::MaxTransformScale)));
|
||||
});
|
||||
AZ::NonUniformScaleRequestBus::Event(
|
||||
m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale,
|
||||
(scaleMultiplier * m_initialScale)
|
||||
.GetClamp(AZ::Vector3(AZ::MinTransformScale), AZ::Vector3(AZ::MaxTransformScale)));
|
||||
});
|
||||
|
||||
m_manipulators->InstallUniformLeftMouseDownCallback(mouseDownCallback);
|
||||
|
||||
m_manipulators->InstallUniformMouseMoveCallback([this](const LinearManipulator::Action& action) {
|
||||
const auto sumVectorElements = [](const AZ::Vector3& vec) { return vec.GetX() + vec.GetY() + vec.GetZ(); };
|
||||
m_manipulators->InstallUniformMouseMoveCallback(
|
||||
[this](const LinearManipulator::Action& action)
|
||||
{
|
||||
const auto sumVectorElements = [](const AZ::Vector3& vec)
|
||||
{
|
||||
return vec.GetX() + vec.GetY() + vec.GetZ();
|
||||
};
|
||||
|
||||
const float minScaleMultiplier = AZ::MinTransformScale / m_initialScale.GetMinElement();
|
||||
const float maxScaleMultiplier = AZ::MaxTransformScale / m_initialScale.GetMaxElement();
|
||||
const float scaleMultiplier = AZ::GetClamp(
|
||||
1.0f + sumVectorElements(action.m_start.m_sign * action.LocalScaleOffset() / m_initialScale), minScaleMultiplier,
|
||||
maxScaleMultiplier);
|
||||
const float minScaleMultiplier = AZ::MinTransformScale / m_initialScale.GetMinElement();
|
||||
const float maxScaleMultiplier = AZ::MaxTransformScale / m_initialScale.GetMaxElement();
|
||||
const float scaleMultiplier = AZ::GetClamp(
|
||||
1.0f + sumVectorElements(action.m_start.m_sign * action.LocalScaleOffset() / m_initialScale), minScaleMultiplier,
|
||||
maxScaleMultiplier);
|
||||
|
||||
AZ::NonUniformScaleRequestBus::Event(
|
||||
m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale, scaleMultiplier * m_initialScale);
|
||||
});
|
||||
AZ::NonUniformScaleRequestBus::Event(
|
||||
m_entityComponentIdPair.GetEntityId(), &AZ::NonUniformScaleRequests::SetScale, scaleMultiplier * m_initialScale);
|
||||
});
|
||||
}
|
||||
|
||||
NonUniformScaleComponentMode::~NonUniformScaleComponentMode()
|
||||
|
||||
+14
-25
@@ -423,15 +423,14 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
static void InitializeTranslationLookup(
|
||||
EntityIdManipulators& entityIdManipulators, const AZ::Vector3& snapOffset)
|
||||
static void InitializeTranslationLookup(EntityIdManipulators& entityIdManipulators)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
for (auto& entityIdLookup : entityIdManipulators.m_lookups)
|
||||
{
|
||||
entityIdLookup.second.m_initial =
|
||||
AZ::Transform::CreateTranslation(GetWorldTranslation(entityIdLookup.first) + snapOffset);
|
||||
AZ::Transform::CreateTranslation(GetWorldTranslation(entityIdLookup.first));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,7 +819,7 @@ namespace AzToolsFramework
|
||||
// moving with ctrl - setting override
|
||||
pivotOverrideFrame.m_translationOverride =
|
||||
entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation();
|
||||
InitializeTranslationLookup(entityIdManipulators, -action.LocalPositionOffset());
|
||||
InitializeTranslationLookup(entityIdManipulators);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1277,12 +1276,12 @@ namespace AzToolsFramework
|
||||
|
||||
// linear
|
||||
translationManipulators->InstallLinearManipulatorMouseDownCallback(
|
||||
[this, manipulatorEntityIds](const LinearManipulator::Action& action) mutable
|
||||
[this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action) mutable
|
||||
{
|
||||
// important to sort entityIds based on hierarchy order when updating transforms
|
||||
BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds);
|
||||
|
||||
InitializeTranslationLookup(m_entityIdManipulators, action.m_start.m_positionSnapOffset);
|
||||
InitializeTranslationLookup(m_entityIdManipulators);
|
||||
|
||||
m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation();
|
||||
m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(
|
||||
@@ -1302,19 +1301,19 @@ namespace AzToolsFramework
|
||||
});
|
||||
|
||||
translationManipulators->InstallLinearManipulatorMouseUpCallback(
|
||||
[this](const LinearManipulator::Action& /*action*/) mutable
|
||||
[this]([[maybe_unused]] const LinearManipulator::Action& action) mutable
|
||||
{
|
||||
EndRecordManipulatorCommand();
|
||||
});
|
||||
|
||||
// planar
|
||||
translationManipulators->InstallPlanarManipulatorMouseDownCallback(
|
||||
[this, manipulatorEntityIds](const PlanarManipulator::Action& action)
|
||||
[this, manipulatorEntityIds]([[maybe_unused]] const PlanarManipulator::Action& action)
|
||||
{
|
||||
// important to sort entityIds based on hierarchy order when updating transforms
|
||||
BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds);
|
||||
|
||||
InitializeTranslationLookup(m_entityIdManipulators, action.m_start.m_snapOffset);
|
||||
InitializeTranslationLookup(m_entityIdManipulators);
|
||||
|
||||
m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation();
|
||||
m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(
|
||||
@@ -1340,11 +1339,11 @@ namespace AzToolsFramework
|
||||
|
||||
// surface
|
||||
translationManipulators->InstallSurfaceManipulatorMouseDownCallback(
|
||||
[this, manipulatorEntityIds](const SurfaceManipulator::Action& action)
|
||||
[this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action)
|
||||
{
|
||||
BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds);
|
||||
|
||||
InitializeTranslationLookup(m_entityIdManipulators, action.m_start.m_snapOffset);
|
||||
InitializeTranslationLookup(m_entityIdManipulators);
|
||||
|
||||
m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation();
|
||||
m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(
|
||||
@@ -3326,26 +3325,16 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
static void DrawManipulatorGrid(
|
||||
AzFramework::DebugDisplayRequests& debugDisplay, const EntityIdManipulators& entityIdManipulators,
|
||||
const float gridSize, const float localSnapping)
|
||||
AzFramework::DebugDisplayRequests& debugDisplay, const EntityIdManipulators& entityIdManipulators, const float gridSize)
|
||||
{
|
||||
const AZ::Matrix3x3 orientation =
|
||||
AZ::Matrix3x3::CreateFromTransform(entityIdManipulators.m_manipulators->GetLocalTransform());
|
||||
|
||||
const AZ::Vector3 unsnappedTranslation =
|
||||
const AZ::Vector3 translation =
|
||||
entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation();
|
||||
|
||||
// calculate the offset to snap by to align the manipulator to the grid
|
||||
// note: only perform this if we are not snapping in local space
|
||||
const AZ::Vector3 snappedOffset = !localSnapping
|
||||
? CalculateSnappedOffset(unsnappedTranslation, orientation.GetBasisX(), gridSize) +
|
||||
CalculateSnappedOffset(unsnappedTranslation, orientation.GetBasisY(), gridSize)
|
||||
: AZ::Vector3::CreateZero();
|
||||
|
||||
const AZ::Vector3 snappedTranslation = unsnappedTranslation + snappedOffset;
|
||||
|
||||
DrawSnappingGrid(
|
||||
debugDisplay, AZ::Transform::CreateFromMatrix3x3AndTranslation(orientation, snappedTranslation),
|
||||
debugDisplay, AZ::Transform::CreateFromMatrix3x3AndTranslation(orientation, translation),
|
||||
gridSize);
|
||||
}
|
||||
|
||||
@@ -3484,7 +3473,7 @@ namespace AzToolsFramework
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportInfo.m_viewportId);
|
||||
if (gridSnapParams.m_gridSnap && m_entityIdManipulators.m_manipulators)
|
||||
{
|
||||
DrawManipulatorGrid(debugDisplay, m_entityIdManipulators, gridSnapParams.m_gridSize, modifiers.Alt());
|
||||
DrawManipulatorGrid(debugDisplay, m_entityIdManipulators, gridSnapParams.m_gridSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user