|
@@ -8,6 +8,7 @@
|
|
|
|
|
|
#include "EditorTransformComponentSelection.h"
|
|
|
|
|
|
+#include <AzCore/Math/MathStringConversions.h>
|
|
|
#include <AzCore/Math/Matrix3x3.h>
|
|
|
#include <AzCore/Math/Matrix3x4.h>
|
|
|
#include <AzCore/Math/Matrix4x4.h>
|
|
@@ -81,6 +82,13 @@ namespace AzToolsFramework
|
|
|
nullptr,
|
|
|
AZ::ConsoleFunctorFlags::Null,
|
|
|
"The screen position of the gizmo in normalized (0-1) ndc space");
|
|
|
+ AZ_CVAR(
|
|
|
+ bool,
|
|
|
+ ed_viewportDisplayManipulatorPosition,
|
|
|
+ false,
|
|
|
+ nullptr,
|
|
|
+ AZ::ConsoleFunctorFlags::Null,
|
|
|
+ "Display the position of the manipulator to the viewport as debug text");
|
|
|
|
|
|
// strings related to new viewport interaction model (EditorTransformComponentSelection)
|
|
|
static const char* const TogglePivotTitleRightClick = "Toggle pivot";
|
|
@@ -174,41 +182,20 @@ namespace AzToolsFramework
|
|
|
return m_translationOverride.has_value() || m_orientationOverride.has_value();
|
|
|
}
|
|
|
|
|
|
- bool OptionalFrame::HasEntityOverride() const
|
|
|
- {
|
|
|
- return m_pickedEntityIdOverride.IsValid();
|
|
|
- }
|
|
|
-
|
|
|
- bool OptionalFrame::PickedTranslation() const
|
|
|
- {
|
|
|
- return (m_pickTypes & PickType::Translation) != 0;
|
|
|
- }
|
|
|
-
|
|
|
- bool OptionalFrame::PickedOrientation() const
|
|
|
- {
|
|
|
- return (m_pickTypes & PickType::Orientation) != 0;
|
|
|
- }
|
|
|
-
|
|
|
void OptionalFrame::Reset()
|
|
|
{
|
|
|
m_orientationOverride.reset();
|
|
|
m_translationOverride.reset();
|
|
|
- m_pickedEntityIdOverride.SetInvalid();
|
|
|
- m_pickTypes = PickType::None;
|
|
|
}
|
|
|
|
|
|
void OptionalFrame::ResetPickedTranslation()
|
|
|
{
|
|
|
m_translationOverride.reset();
|
|
|
- m_pickedEntityIdOverride.SetInvalid();
|
|
|
- m_pickTypes &= ~PickType::Translation;
|
|
|
}
|
|
|
|
|
|
void OptionalFrame::ResetPickedOrientation()
|
|
|
{
|
|
|
m_orientationOverride.reset();
|
|
|
- m_pickedEntityIdOverride.SetInvalid();
|
|
|
- m_pickTypes &= ~PickType::Orientation;
|
|
|
}
|
|
|
|
|
|
using EntityIdTransformMap = AZStd::unordered_map<AZ::EntityId, AZ::Transform>;
|
|
@@ -261,6 +248,14 @@ namespace AzToolsFramework
|
|
|
mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt();
|
|
|
}
|
|
|
|
|
|
+ static bool ManipulatorDittoExact(
|
|
|
+ const AzFramework::ClickDetector::ClickOutcome clickOutcome, const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
|
|
|
+ {
|
|
|
+ return clickOutcome == AzFramework::ClickDetector::ClickOutcome::Click &&
|
|
|
+ mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl() &&
|
|
|
+ mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Shift();
|
|
|
+ }
|
|
|
+
|
|
|
static bool IndividualSelect(const AzFramework::ClickDetector::ClickOutcome clickOutcome)
|
|
|
{
|
|
|
return clickOutcome == AzFramework::ClickDetector::ClickOutcome::Click;
|
|
@@ -271,7 +266,8 @@ namespace AzToolsFramework
|
|
|
{
|
|
|
return clickOutcome == AzFramework::ClickDetector::ClickOutcome::Click &&
|
|
|
mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl() &&
|
|
|
- !mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt();
|
|
|
+ !mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt() &&
|
|
|
+ !mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Shift();
|
|
|
}
|
|
|
} // namespace Input
|
|
|
|
|
@@ -533,7 +529,7 @@ namespace AzToolsFramework
|
|
|
buttonIdFromFrameFn(referenceFrame));
|
|
|
}
|
|
|
|
|
|
- namespace ETCS
|
|
|
+ namespace Etcs
|
|
|
{
|
|
|
PivotOrientationResult CalculatePivotOrientation(const AZ::EntityId entityId, const ReferenceFrame referenceFrame)
|
|
|
{
|
|
@@ -568,17 +564,17 @@ namespace AzToolsFramework
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
- } // namespace ETCS
|
|
|
+ } // namespace Etcs
|
|
|
|
|
|
// return parent space from selection - if entity(s) share a common parent,
|
|
|
// return that space, otherwise return world space
|
|
|
template<typename EntityIdMapIterator>
|
|
|
- static ETCS::PivotOrientationResult CalculateParentSpace(EntityIdMapIterator begin, EntityIdMapIterator end)
|
|
|
+ static Etcs::PivotOrientationResult CalculateParentSpace(EntityIdMapIterator begin, EntityIdMapIterator end)
|
|
|
{
|
|
|
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
|
|
|
|
|
// initialize to world with no parent
|
|
|
- ETCS::PivotOrientationResult result{ AZ::Quaternion::CreateIdentity(), AZ::EntityId() };
|
|
|
+ Etcs::PivotOrientationResult result{ AZ::Quaternion::CreateIdentity(), AZ::EntityId() };
|
|
|
|
|
|
AZ::EntityId commonParentId;
|
|
|
for (EntityIdMapIterator entityIdLookupIt = begin; entityIdLookupIt != end; ++entityIdLookupIt)
|
|
@@ -647,7 +643,7 @@ namespace AzToolsFramework
|
|
|
return AZ::Vector3::CreateZero();
|
|
|
}
|
|
|
|
|
|
- namespace ETCS
|
|
|
+ namespace Etcs
|
|
|
{
|
|
|
template<typename EntityIdMap>
|
|
|
PivotOrientationResult CalculatePivotOrientationForEntityIds(const EntityIdMap& entityIdMap, const ReferenceFrame referenceFrame)
|
|
@@ -659,7 +655,7 @@ namespace AzToolsFramework
|
|
|
// simple case with one entity
|
|
|
if (entityIdMap.size() == 1)
|
|
|
{
|
|
|
- return ETCS::CalculatePivotOrientation(entityIdMap.begin()->first, referenceFrame);
|
|
|
+ return Etcs::CalculatePivotOrientation(entityIdMap.begin()->first, referenceFrame);
|
|
|
}
|
|
|
|
|
|
// local/parent logic the same
|
|
@@ -674,9 +670,9 @@ namespace AzToolsFramework
|
|
|
return { AZ::Quaternion::CreateIdentity(), AZ::EntityId() };
|
|
|
}
|
|
|
}
|
|
|
- } // namespace ETCS
|
|
|
+ } // namespace Etcs
|
|
|
|
|
|
- namespace ETCS
|
|
|
+ namespace Etcs
|
|
|
{
|
|
|
template<typename EntityIdMap>
|
|
|
PivotOrientationResult CalculateSelectionPivotOrientation(
|
|
@@ -730,7 +726,7 @@ namespace AzToolsFramework
|
|
|
|
|
|
return pivot;
|
|
|
}
|
|
|
- } // namespace ETCS
|
|
|
+ } // namespace Etcs
|
|
|
|
|
|
template<typename EntityIdMap>
|
|
|
static AZ::Vector3 RecalculateAverageManipulatorTranslation(
|
|
@@ -749,7 +745,7 @@ namespace AzToolsFramework
|
|
|
{
|
|
|
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
|
|
|
|
|
- return ETCS::CalculateSelectionPivotOrientation(entityIdMap, pivotOverrideFrame, referenceFrame).m_worldOrientation;
|
|
|
+ return Etcs::CalculateSelectionPivotOrientation(entityIdMap, pivotOverrideFrame, referenceFrame).m_worldOrientation;
|
|
|
}
|
|
|
|
|
|
template<typename EntityIdMap>
|
|
@@ -825,7 +821,7 @@ namespace AzToolsFramework
|
|
|
|
|
|
// note: used for parent and world depending on the current reference frame
|
|
|
const auto pivotOrientation =
|
|
|
- ETCS::CalculateSelectionPivotOrientation(entityIdManipulators.m_lookups, pivotOverrideFrame, referenceFrame);
|
|
|
+ Etcs::CalculateSelectionPivotOrientation(entityIdManipulators.m_lookups, pivotOverrideFrame, referenceFrame);
|
|
|
|
|
|
// note: must use sorted entityIds based on hierarchy order when updating transforms
|
|
|
for (AZ::EntityId entityId : entityIdContainer)
|
|
@@ -856,7 +852,7 @@ namespace AzToolsFramework
|
|
|
entityItLookupIt->second.m_initial = AZ::Transform::CreateTranslation(worldTranslation - localOffset);
|
|
|
}
|
|
|
|
|
|
- ETCS::SetEntityWorldTranslation(
|
|
|
+ Etcs::SetEntityWorldTranslation(
|
|
|
entityId, entityItLookupIt->second.m_initial.GetTranslation() + localOffset, transformChangedInternally);
|
|
|
}
|
|
|
break;
|
|
@@ -872,7 +868,7 @@ namespace AzToolsFramework
|
|
|
entityItLookupIt->second.m_initial = AZ::Transform::CreateTranslation(worldTranslation - localOffset);
|
|
|
}
|
|
|
|
|
|
- ETCS::SetEntityWorldTranslation(
|
|
|
+ Etcs::SetEntityWorldTranslation(
|
|
|
entityId, entityItLookupIt->second.m_initial.GetTranslation() + localOffset, transformChangedInternally);
|
|
|
}
|
|
|
break;
|
|
@@ -988,7 +984,7 @@ namespace AzToolsFramework
|
|
|
ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
|
|
|
}
|
|
|
|
|
|
- // leaves focus mode by focusing on the parent of the current perfab in the entity outliner
|
|
|
+ // leaves focus mode by focusing on the parent of the current prefab in the entity outliner
|
|
|
static void LeaveFocusMode()
|
|
|
{
|
|
|
if (auto prefabFocusPublicInterface = AZ::Interface<Prefab::PrefabFocusPublicInterface>::Get())
|
|
@@ -997,6 +993,20 @@ namespace AzToolsFramework
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ static AZ::Vector3 EtcsPickEntity(const AZ::EntityId entityId, const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
|
|
|
+ {
|
|
|
+ float distance;
|
|
|
+ const auto& origin = mouseInteraction.m_mouseInteraction.m_mousePick.m_rayOrigin;
|
|
|
+ const auto& direction = mouseInteraction.m_mouseInteraction.m_mousePick.m_rayDirection;
|
|
|
+ if (AzToolsFramework::PickEntity(
|
|
|
+ entityId, origin, direction, distance, mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId))
|
|
|
+ {
|
|
|
+ return origin + direction * distance;
|
|
|
+ }
|
|
|
+
|
|
|
+ return origin + direction * GetDefaultEntityPlacementDistance();
|
|
|
+ }
|
|
|
+
|
|
|
EditorTransformComponentSelection::EditorTransformComponentSelection(const EditorVisibleEntityDataCacheInterface* entityDataCache)
|
|
|
: m_entityDataCache(entityDataCache)
|
|
|
{
|
|
@@ -1184,8 +1194,7 @@ namespace AzToolsFramework
|
|
|
}
|
|
|
|
|
|
return { BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()),
|
|
|
- TransformNormalizedScale(m_entityIdManipulators.m_manipulators->GetLocalTransform()),
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride };
|
|
|
+ TransformNormalizedScale(m_entityIdManipulators.m_manipulators->GetLocalTransform()) };
|
|
|
}
|
|
|
|
|
|
void EditorTransformComponentSelection::BeginRecordManipulatorCommand()
|
|
@@ -1908,9 +1917,33 @@ namespace AzToolsFramework
|
|
|
}
|
|
|
|
|
|
// set manipulator pivot override translation or orientation (update manipulators)
|
|
|
- if (Input::ManipulatorDitto(clickOutcome, mouseInteraction))
|
|
|
- {
|
|
|
- PerformManipulatorDitto(entityIdUnderCursor);
|
|
|
+ const bool manipulatorDitto = Input::ManipulatorDitto(clickOutcome, mouseInteraction);
|
|
|
+ const bool manipulatorDittoExact = Input::ManipulatorDittoExact(clickOutcome, mouseInteraction);
|
|
|
+ if (manipulatorDitto || manipulatorDittoExact)
|
|
|
+ {
|
|
|
+ PerformManipulatorDitto(
|
|
|
+ entityIdUnderCursor,
|
|
|
+ [manipulatorDitto, manipulatorDittoExact, &mouseInteraction,
|
|
|
+ entityId = entityIdUnderCursor]() -> AZStd::optional<AZ::Vector3>
|
|
|
+ {
|
|
|
+ if (manipulatorDitto)
|
|
|
+ {
|
|
|
+ if (entityId.IsValid())
|
|
|
+ {
|
|
|
+ return GetWorldTranslation(entityId);
|
|
|
+ }
|
|
|
+
|
|
|
+ return AZStd::nullopt;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (manipulatorDittoExact)
|
|
|
+ {
|
|
|
+ return EtcsPickEntity(entityId, mouseInteraction);
|
|
|
+ }
|
|
|
+
|
|
|
+ return AZStd::nullopt;
|
|
|
+ });
|
|
|
+
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -2032,7 +2065,9 @@ namespace AzToolsFramework
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- void EditorTransformComponentSelection::PerformManipulatorDitto(const AZ::EntityId entityId)
|
|
|
+ template<typename ManipulatorTranslationFn>
|
|
|
+ void EditorTransformComponentSelection::PerformManipulatorDitto(
|
|
|
+ const AZ::EntityId entityId, ManipulatorTranslationFn&& manipulatorTranslationFn)
|
|
|
{
|
|
|
if (m_entityIdManipulators.m_manipulators)
|
|
|
{
|
|
@@ -2041,19 +2076,28 @@ namespace AzToolsFramework
|
|
|
auto manipulatorCommand =
|
|
|
AZStd::make_unique<EntityManipulatorCommand>(CreateManipulatorCommandStateFromSelf(), ManipulatorUndoRedoName);
|
|
|
|
|
|
- if (entityId.IsValid())
|
|
|
+ auto overrideManipulatorTranslationFn = [this, &manipulatorTranslationFn]
|
|
|
{
|
|
|
- AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
|
|
- AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM);
|
|
|
+ if (const auto translation = manipulatorTranslationFn(); translation.has_value())
|
|
|
+ {
|
|
|
+ OverrideManipulatorTranslation(translation.value());
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
+ if (entityId.IsValid())
|
|
|
+ {
|
|
|
// set orientation/translation to match picked entity
|
|
|
switch (m_mode)
|
|
|
{
|
|
|
case Mode::Rotation:
|
|
|
- OverrideManipulatorOrientation(QuaternionFromTransformNoScaling(worldFromLocal));
|
|
|
+ {
|
|
|
+ AZ::Quaternion worldOrientation = AZ::Quaternion::CreateIdentity();
|
|
|
+ AZ::TransformBus::EventResult(worldOrientation, entityId, &AZ::TransformBus::Events::GetWorldRotationQuaternion);
|
|
|
+ OverrideManipulatorOrientation(worldOrientation.GetNormalized());
|
|
|
+ }
|
|
|
break;
|
|
|
case Mode::Translation:
|
|
|
- OverrideManipulatorTranslation(worldFromLocal.GetTranslation());
|
|
|
+ overrideManipulatorTranslationFn();
|
|
|
break;
|
|
|
case Mode::Scale:
|
|
|
// do nothing
|
|
@@ -2061,17 +2105,15 @@ namespace AzToolsFramework
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
- // only update pivot override when in translation or rotation mode
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
switch (m_mode)
|
|
|
{
|
|
|
- case Mode::Rotation:
|
|
|
- m_pivotOverrideFrame.m_pickTypes |= OptionalFrame::PickType::Orientation;
|
|
|
- [[fallthrough]];
|
|
|
case Mode::Translation:
|
|
|
- m_pivotOverrideFrame.m_pickTypes |= OptionalFrame::PickType::Translation;
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride = entityId;
|
|
|
+ overrideManipulatorTranslationFn();
|
|
|
break;
|
|
|
+ case Mode::Rotation:
|
|
|
case Mode::Scale:
|
|
|
// do nothing
|
|
|
break;
|
|
@@ -2079,15 +2121,10 @@ namespace AzToolsFramework
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- // match the same behavior as if we pressed Ctrl+R to reset the manipulator
|
|
|
- DelegateClearManipulatorOverride();
|
|
|
- }
|
|
|
|
|
|
manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State(
|
|
|
BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()),
|
|
|
- m_entityIdManipulators.m_manipulators->GetLocalTransform(), entityId));
|
|
|
+ m_entityIdManipulators.m_manipulators->GetLocalTransform()));
|
|
|
|
|
|
manipulatorCommand->SetParent(undoBatch.GetUndoBatch());
|
|
|
manipulatorCommand.release();
|
|
@@ -2148,13 +2185,12 @@ namespace AzToolsFramework
|
|
|
case Mode::Rotation:
|
|
|
ClearManipulatorOrientationOverride();
|
|
|
break;
|
|
|
- case Mode::Scale:
|
|
|
- SetManipulatorViewBaseScale(DefaultManipulatorViewBaseScale);
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride.SetInvalid();
|
|
|
- break;
|
|
|
case Mode::Translation:
|
|
|
ClearManipulatorTranslationOverride();
|
|
|
break;
|
|
|
+ case Mode::Scale:
|
|
|
+ SetManipulatorViewBaseScale(DefaultManipulatorViewBaseScale);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2753,8 +2789,7 @@ namespace AzToolsFramework
|
|
|
RegenerateManipulators();
|
|
|
}
|
|
|
|
|
|
- void EditorTransformComponentSelection::UndoRedoEntityManipulatorCommand(
|
|
|
- const AZ::u8 pivotOverride, const AZ::Transform& transform, const AZ::EntityId entityId)
|
|
|
+ void EditorTransformComponentSelection::UndoRedoEntityManipulatorCommand(const AZ::u8 pivotOverride, const AZ::Transform& transform)
|
|
|
{
|
|
|
m_pivotOverrideFrame.Reset();
|
|
|
|
|
@@ -2773,11 +2808,6 @@ namespace AzToolsFramework
|
|
|
{
|
|
|
m_pivotOverrideFrame.m_translationOverride = transform.GetTranslation();
|
|
|
}
|
|
|
-
|
|
|
- if (entityId.IsValid())
|
|
|
- {
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride = entityId;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2889,7 +2919,6 @@ namespace AzToolsFramework
|
|
|
AZStd::make_unique<EntityManipulatorCommand>(CreateManipulatorCommandStateFromSelf(), ManipulatorUndoRedoName);
|
|
|
|
|
|
m_pivotOverrideFrame.ResetPickedTranslation();
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride.SetInvalid();
|
|
|
|
|
|
m_entityIdManipulators.m_manipulators->SetLocalTransform(RecalculateAverageManipulatorTransform(
|
|
|
m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame));
|
|
@@ -2915,11 +2944,10 @@ namespace AzToolsFramework
|
|
|
AZStd::make_unique<EntityManipulatorCommand>(CreateManipulatorCommandStateFromSelf(), ManipulatorUndoRedoName);
|
|
|
|
|
|
m_pivotOverrideFrame.ResetPickedOrientation();
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride.SetInvalid();
|
|
|
|
|
|
// parent reference frame is the default (when no modifiers are held)
|
|
|
m_entityIdManipulators.m_manipulators->SetLocalTransform(AZ::Transform::CreateFromQuaternionAndTranslation(
|
|
|
- ETCS::CalculatePivotOrientationForEntityIds(m_entityIdManipulators.m_lookups, ReferenceFrame::Parent).m_worldOrientation,
|
|
|
+ Etcs::CalculatePivotOrientationForEntityIds(m_entityIdManipulators.m_lookups, ReferenceFrame::Parent).m_worldOrientation,
|
|
|
m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation()));
|
|
|
|
|
|
m_entityIdManipulators.m_manipulators->SetBoundsDirty();
|
|
@@ -2991,8 +3019,7 @@ namespace AzToolsFramework
|
|
|
manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State(
|
|
|
BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()),
|
|
|
AZ::Transform::CreateFromQuaternionAndTranslation(
|
|
|
- QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation),
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride));
|
|
|
+ QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation)));
|
|
|
|
|
|
manipulatorCommand->SetParent(undoBatch.GetUndoBatch());
|
|
|
manipulatorCommand.release();
|
|
@@ -3044,8 +3071,7 @@ namespace AzToolsFramework
|
|
|
manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State(
|
|
|
BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()),
|
|
|
AZ::Transform::CreateFromQuaternionAndTranslation(
|
|
|
- QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation),
|
|
|
- m_pivotOverrideFrame.m_pickedEntityIdOverride));
|
|
|
+ QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()), translation)));
|
|
|
|
|
|
manipulatorCommand->SetParent(undoBatch.GetUndoBatch());
|
|
|
manipulatorCommand.release();
|
|
@@ -3457,30 +3483,11 @@ namespace AzToolsFramework
|
|
|
|
|
|
if (!m_selectedEntityIds.empty())
|
|
|
{
|
|
|
- if (m_pivotOverrideFrame.m_pickedEntityIdOverride.IsValid())
|
|
|
- {
|
|
|
- const AZ::Transform pickedEntityWorldTransform = AZ::Transform::CreateFromQuaternionAndTranslation(
|
|
|
- ETCS::CalculatePivotOrientation(m_pivotOverrideFrame.m_pickedEntityIdOverride, referenceFrame).m_worldOrientation,
|
|
|
- CalculatePivotTranslation(m_pivotOverrideFrame.m_pickedEntityIdOverride, m_pivotMode));
|
|
|
-
|
|
|
- const float scaledSize =
|
|
|
- PivotSize * CalculateScreenToWorldMultiplier(pickedEntityWorldTransform.GetTranslation(), cameraState);
|
|
|
-
|
|
|
- debugDisplay.DepthWriteOff();
|
|
|
- debugDisplay.DepthTestOff();
|
|
|
- debugDisplay.SetColor(PickedOrientationColor);
|
|
|
-
|
|
|
- debugDisplay.DrawWireSphere(pickedEntityWorldTransform.GetTranslation(), scaledSize);
|
|
|
-
|
|
|
- debugDisplay.DepthTestOn();
|
|
|
- debugDisplay.DepthWriteOn();
|
|
|
- }
|
|
|
-
|
|
|
// check what pivot orientation we are in (based on if a modifier is
|
|
|
// held to move us from parent to world space or parent to local space)
|
|
|
// or if we set a pivot override
|
|
|
const auto pivotResult =
|
|
|
- ETCS::CalculateSelectionPivotOrientation(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_referenceFrame);
|
|
|
+ Etcs::CalculateSelectionPivotOrientation(m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_referenceFrame);
|
|
|
|
|
|
// if the reference frame was parent space and the selection does have a
|
|
|
// valid parent, draw a preview axis at its position/orientation
|
|
@@ -3630,6 +3637,25 @@ namespace AzToolsFramework
|
|
|
{
|
|
|
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
|
|
|
|
|
+ // debug draw manipulator position (when one exists) in screen space
|
|
|
+ if (ed_viewportDisplayManipulatorPosition)
|
|
|
+ {
|
|
|
+ const int viewportId = viewportInfo.m_viewportId;
|
|
|
+ const AzFramework::CameraState editorCameraState = GetCameraState(viewportId);
|
|
|
+ const auto viewportSize = AzFramework::Vector2FromScreenSize(editorCameraState.m_viewportSize);
|
|
|
+
|
|
|
+ AZStd::string manipulatorPosition = "none";
|
|
|
+ if (const auto manipulatorTransform = GetManipulatorTransform(); manipulatorTransform.has_value())
|
|
|
+ {
|
|
|
+ AZStd::to_string(manipulatorPosition, manipulatorTransform->GetTranslation());
|
|
|
+ }
|
|
|
+
|
|
|
+ debugDisplay.SetColor(AZ::Colors::White);
|
|
|
+ debugDisplay.Draw2dTextLabel(
|
|
|
+ 15.0f, viewportSize.GetY() - 25.0f, 0.6f,
|
|
|
+ AZStd::string::format("Manipulator World Position: %s", manipulatorPosition.c_str()).c_str());
|
|
|
+ }
|
|
|
+
|
|
|
DrawAxisGizmo(viewportInfo, debugDisplay);
|
|
|
|
|
|
m_boxSelect.Display2d(viewportInfo, debugDisplay);
|
|
@@ -3826,32 +3852,32 @@ namespace AzToolsFramework
|
|
|
|
|
|
void EditorTransformComponentSelection::SetEntityWorldTranslation(const AZ::EntityId entityId, const AZ::Vector3& worldTranslation)
|
|
|
{
|
|
|
- ETCS::SetEntityWorldTranslation(entityId, worldTranslation, m_transformChangedInternally);
|
|
|
+ Etcs::SetEntityWorldTranslation(entityId, worldTranslation, m_transformChangedInternally);
|
|
|
}
|
|
|
|
|
|
void EditorTransformComponentSelection::SetEntityLocalTranslation(const AZ::EntityId entityId, const AZ::Vector3& localTranslation)
|
|
|
{
|
|
|
- ETCS::SetEntityLocalTranslation(entityId, localTranslation, m_transformChangedInternally);
|
|
|
+ Etcs::SetEntityLocalTranslation(entityId, localTranslation, m_transformChangedInternally);
|
|
|
}
|
|
|
|
|
|
void EditorTransformComponentSelection::SetEntityWorldTransform(const AZ::EntityId entityId, const AZ::Transform& worldTransform)
|
|
|
{
|
|
|
- ETCS::SetEntityWorldTransform(entityId, worldTransform, m_transformChangedInternally);
|
|
|
+ Etcs::SetEntityWorldTransform(entityId, worldTransform, m_transformChangedInternally);
|
|
|
}
|
|
|
|
|
|
void EditorTransformComponentSelection::SetEntityLocalScale(const AZ::EntityId entityId, const float localScale)
|
|
|
{
|
|
|
- ETCS::SetEntityLocalScale(entityId, localScale, m_transformChangedInternally);
|
|
|
+ Etcs::SetEntityLocalScale(entityId, localScale, m_transformChangedInternally);
|
|
|
}
|
|
|
|
|
|
void EditorTransformComponentSelection::SetEntityLocalRotation(const AZ::EntityId entityId, const AZ::Vector3& localRotation)
|
|
|
{
|
|
|
- ETCS::SetEntityLocalRotation(entityId, localRotation, m_transformChangedInternally);
|
|
|
+ Etcs::SetEntityLocalRotation(entityId, localRotation, m_transformChangedInternally);
|
|
|
}
|
|
|
|
|
|
void EditorTransformComponentSelection::SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Quaternion& localRotation)
|
|
|
{
|
|
|
- ETCS::SetEntityLocalRotation(entityId, localRotation, m_transformChangedInternally);
|
|
|
+ Etcs::SetEntityLocalRotation(entityId, localRotation, m_transformChangedInternally);
|
|
|
}
|
|
|
|
|
|
void EditorTransformComponentSelection::OnStartPlayInEditor()
|
|
@@ -3877,7 +3903,7 @@ namespace AzToolsFramework
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- namespace ETCS
|
|
|
+ namespace Etcs
|
|
|
{
|
|
|
// little raii wrapper to switch a value from true to false and back
|
|
|
class ScopeSwitch
|
|
@@ -3933,11 +3959,11 @@ namespace AzToolsFramework
|
|
|
ScopeSwitch sw(internal);
|
|
|
AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, localRotation);
|
|
|
}
|
|
|
- } // namespace ETCS
|
|
|
+ } // namespace Etcs
|
|
|
|
|
|
// explicit instantiations
|
|
|
- template ETCS::PivotOrientationResult ETCS::CalculatePivotOrientationForEntityIds<EntityIdManipulatorLookups>(
|
|
|
+ template Etcs::PivotOrientationResult Etcs::CalculatePivotOrientationForEntityIds<EntityIdManipulatorLookups>(
|
|
|
const EntityIdManipulatorLookups&, ReferenceFrame);
|
|
|
- template ETCS::PivotOrientationResult ETCS::CalculateSelectionPivotOrientation<EntityIdManipulatorLookups>(
|
|
|
+ template Etcs::PivotOrientationResult Etcs::CalculateSelectionPivotOrientation<EntityIdManipulatorLookups>(
|
|
|
const EntityIdManipulatorLookups&, const OptionalFrame&, const ReferenceFrame referenceFrame);
|
|
|
} // namespace AzToolsFramework
|