From 08eb115e26c646440672f4e44ad341960c7bdcee Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 4 Feb 2022 14:02:24 +0000 Subject: [PATCH] fix various issues with collider manipulators and non-uniform scale Signed-off-by: greerdv --- .../ComponentModes/BoxViewportEdit.cpp | 43 +++++++++++-------- .../Manipulators/BoxManipulatorRequestBus.h | 5 +++ .../EditorAxisAlignedBoxShapeComponent.cpp | 5 +++ .../EditorAxisAlignedBoxShapeComponent.h | 1 + .../Source/Shape/EditorBoxShapeComponent.cpp | 5 +++ .../Source/Shape/EditorBoxShapeComponent.h | 1 + Gems/PhysX/Code/Editor/ColliderOffsetMode.cpp | 5 +++ .../Code/Editor/ColliderRotationMode.cpp | 13 +++++- .../Code/Source/EditorColliderComponent.cpp | 19 +++++--- .../Code/Source/EditorColliderComponent.h | 2 + 10 files changed, 74 insertions(+), 25 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentModes/BoxViewportEdit.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentModes/BoxViewportEdit.cpp index 7e496390c8..19d19563f9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentModes/BoxViewportEdit.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentModes/BoxViewportEdit.cpp @@ -40,25 +40,26 @@ namespace AzToolsFramework BoxManipulatorRequestBus::EventResult( boxWorldFromLocal, m_entityComponentIdPair, &BoxManipulatorRequests::GetCurrentTransform); - AZ::Vector3 boxScale = AZ::Vector3::CreateOne(); + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); BoxManipulatorRequestBus::EventResult( - boxScale, m_entityComponentIdPair, &BoxManipulatorRequests::GetBoxScale); + nonUniformScale, m_entityComponentIdPair, &BoxManipulatorRequests::GetCurrentNonUniformScale); AZ::Vector3 boxDimensions = AZ::Vector3::CreateZero(); BoxManipulatorRequestBus::EventResult( boxDimensions, m_entityComponentIdPair, &BoxManipulatorRequests::GetDimensions); - // ensure we apply the entity scale to the box dimensions so - // the manipulators appear in the correct location - boxDimensions *= boxScale; + AZ::Transform boxLocalTransform = AZ::Transform::CreateIdentity(); + BoxManipulatorRequestBus::EventResult( + boxLocalTransform, m_entityComponentIdPair, &BoxManipulatorRequests::GetCurrentLocalTransform); for (size_t manipulatorIndex = 0; manipulatorIndex < m_linearManipulators.size(); ++manipulatorIndex) { if (auto& linearManipulator = m_linearManipulators[manipulatorIndex]) { linearManipulator->SetSpace(boxWorldFromLocal); - linearManipulator->SetLocalTransform( - AZ::Transform::CreateTranslation(s_boxAxes[manipulatorIndex] * 0.5f * boxDimensions)); + linearManipulator->SetLocalTransform(boxLocalTransform * AZ::Transform::CreateTranslation( + s_boxAxes[manipulatorIndex] * 0.5f * boxDimensions)); + linearManipulator->SetNonUniformScale(nonUniformScale); linearManipulator->SetBoundsDirty(); } } @@ -92,29 +93,35 @@ namespace AzToolsFramework [this, entityComponentIdPair]( const LinearManipulator::Action& action) { + AZ::Transform boxLocalTransform = AZ::Transform::CreateIdentity(); + BoxManipulatorRequestBus::EventResult( + boxLocalTransform, entityComponentIdPair, &BoxManipulatorRequests::GetCurrentLocalTransform); + + AZ::Transform boxWorldTransform = AZ::Transform::CreateIdentity(); + BoxManipulatorRequestBus::EventResult( + boxWorldTransform, entityComponentIdPair, &BoxManipulatorRequests::GetCurrentTransform); + float boxScale = AZ::GetMax(AZ::MinTransformScale, boxWorldTransform.GetUniformScale()); + + // calculate the position of the manipulator in the reference frame of the box + // the local position offset of the manipulator does not take the transform scale into account, so need to apply it here + const AZ::Vector3 localPosition = boxLocalTransform.GetInverse().TransformPoint( + action.m_start.m_localPosition + action.m_current.m_localPositionOffset / boxScale); + // calculate the amount of displacement along an axis this manipulator has moved // clamp movement so it cannot go negative based on axis direction const AZ::Vector3 axisDisplacement = - action.LocalPosition().GetAbs() * 2.0f - * AZ::GetMax(0.0f, action.LocalPosition().GetNormalized().Dot(action.m_fixed.m_axis)); - - AZ::Vector3 boxScale = AZ::Vector3::CreateOne(); - BoxManipulatorRequestBus::EventResult( - boxScale, entityComponentIdPair, &BoxManipulatorRequests::GetBoxScale); + localPosition.GetAbs() * 2.0f + * AZ::GetMax(0.0f, localPosition.GetNormalized().Dot(action.m_fixed.m_axis)); AZ::Vector3 boxDimensions = AZ::Vector3::CreateZero(); BoxManipulatorRequestBus::EventResult( boxDimensions, entityComponentIdPair, &BoxManipulatorRequests::GetDimensions); - // ensure we take into account the entity scale using the axis displacement - const AZ::Vector3 scaledAxisDisplacement = - axisDisplacement / boxScale; - // update dimensions - preserve dimensions not effected by this // axis, and update current axis displacement BoxManipulatorRequestBus::Event( entityComponentIdPair, &BoxManipulatorRequests::SetDimensions, - (NotAxis(action.m_fixed.m_axis) * boxDimensions).GetMax(scaledAxisDisplacement)); + (NotAxis(action.m_fixed.m_axis) * boxDimensions).GetMax(axisDisplacement)); UpdateManipulators(); }); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h index b0bcdf47f2..f1440e3d55 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/BoxManipulatorRequestBus.h @@ -31,12 +31,17 @@ namespace AzToolsFramework //! because a collider may have an additional translation/orientation offset from //! the Entity transform. virtual AZ::Transform GetCurrentTransform() = 0; + //! + //! + virtual AZ::Transform GetCurrentLocalTransform() = 0; //! Get the scale currently applied to the box. //! With the Box Shape, the largest x/y/z component is taken //! so scale is always uniform, with colliders the scale may //! be different per component. virtual AZ::Vector3 GetBoxScale() = 0; + virtual AZ::Vector3 GetCurrentNonUniformScale() { return AZ::Vector3::CreateOne(); } + protected: ~BoxManipulatorRequests() = default; }; diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.cpp index f78f2f048d..953bc9d349 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.cpp @@ -161,6 +161,11 @@ namespace LmbrCentral return AzToolsFramework::TransformNormalizedScale(m_aaboxShape.GetCurrentTransform()); } + AZ::Transform EditorAxisAlignedBoxShapeComponent::GetCurrentLocalTransform() + { + return AZ::Transform::CreateIdentity(); + } + AZ::Vector3 EditorAxisAlignedBoxShapeComponent::GetBoxScale() { return AZ::Vector3(m_aaboxShape.GetCurrentTransform().GetUniformScale() * m_aaboxShape.GetCurrentNonUniformScale()); diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.h index 8bff4ea7e1..a906b10129 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorAxisAlignedBoxShapeComponent.h @@ -58,6 +58,7 @@ namespace LmbrCentral AZ::Vector3 GetDimensions() override; void SetDimensions(const AZ::Vector3& dimensions) override; AZ::Transform GetCurrentTransform() override; + AZ::Transform GetCurrentLocalTransform() override; AZ::Vector3 GetBoxScale() override; void ConfigurationChanged(); diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.cpp index 2983ca7753..777e2f728b 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.cpp @@ -167,6 +167,11 @@ namespace LmbrCentral return AzToolsFramework::TransformNormalizedScale(m_boxShape.GetCurrentTransform()); } + AZ::Transform EditorBoxShapeComponent::GetCurrentLocalTransform() + { + return AZ::Transform::CreateIdentity(); + } + AZ::Vector3 EditorBoxShapeComponent::GetBoxScale() { return AZ::Vector3(m_boxShape.GetCurrentTransform().GetUniformScale() * m_boxShape.GetCurrentNonUniformScale()); diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.h b/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.h index aa24bda5c4..499a20497c 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.h +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorBoxShapeComponent.h @@ -57,6 +57,7 @@ namespace LmbrCentral AZ::Vector3 GetDimensions() override; void SetDimensions(const AZ::Vector3& dimensions) override; AZ::Transform GetCurrentTransform() override; + AZ::Transform GetCurrentLocalTransform() override; AZ::Vector3 GetBoxScale() override; void ConfigurationChanged(); diff --git a/Gems/PhysX/Code/Editor/ColliderOffsetMode.cpp b/Gems/PhysX/Code/Editor/ColliderOffsetMode.cpp index 21f27e4622..026eb177ac 100644 --- a/Gems/PhysX/Code/Editor/ColliderOffsetMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderOffsetMode.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -28,10 +29,14 @@ namespace PhysX AZ::Transform worldTransform; AZ::TransformBus::EventResult(worldTransform, idPair.GetEntityId(), &AZ::TransformInterface::GetWorldTM); + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); + AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, idPair.GetEntityId(), &AZ::NonUniformScaleRequests::GetScale); + AZ::Vector3 colliderOffset; PhysX::EditorColliderComponentRequestBus::EventResult(colliderOffset, idPair, &PhysX::EditorColliderComponentRequests::GetColliderOffset); m_translationManipulators.SetSpace(worldTransform); + m_translationManipulators.SetNonUniformScale(nonUniformScale); m_translationManipulators.SetLocalPosition(colliderOffset); m_translationManipulators.AddEntityComponentIdPair(idPair); m_translationManipulators.Register(AzToolsFramework::g_mainManipulatorManagerId); diff --git a/Gems/PhysX/Code/Editor/ColliderRotationMode.cpp b/Gems/PhysX/Code/Editor/ColliderRotationMode.cpp index 5f3c98bcee..d39fd001e4 100644 --- a/Gems/PhysX/Code/Editor/ColliderRotationMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderRotationMode.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,9 @@ namespace PhysX AZ::Transform worldTransform; AZ::TransformBus::EventResult(worldTransform, idPair.GetEntityId(), &AZ::TransformInterface::GetWorldTM); + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); + AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, idPair.GetEntityId(), &AZ::NonUniformScaleRequests::GetScale); + AZ::Quaternion colliderRotation; PhysX::EditorColliderComponentRequestBus::EventResult(colliderRotation, idPair, &PhysX::EditorColliderComponentRequests::GetColliderRotation); @@ -36,7 +40,8 @@ namespace PhysX PhysX::EditorColliderComponentRequestBus::EventResult(colliderOffset, idPair, &PhysX::EditorColliderComponentRequests::GetColliderOffset); m_rotationManipulators.SetSpace(worldTransform); - m_rotationManipulators.SetLocalPosition(colliderOffset); + m_rotationManipulators.SetNonUniformScale(nonUniformScale); + m_rotationManipulators.SetLocalPosition(nonUniformScale * colliderOffset); m_rotationManipulators.SetLocalOrientation(colliderRotation); m_rotationManipulators.AddEntityComponentIdPair(idPair); m_rotationManipulators.Register(AzToolsFramework::g_mainManipulatorManagerId); @@ -70,7 +75,11 @@ namespace PhysX AZ::Vector3 colliderOffset = AZ::Vector3::CreateZero(); PhysX::EditorColliderComponentRequestBus::EventResult(colliderOffset, idPair, &PhysX::EditorColliderComponentRequests::GetColliderOffset); - m_rotationManipulators.SetLocalPosition(colliderOffset); + + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); + AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, idPair.GetEntityId(), &AZ::NonUniformScaleRequests::GetScale); + + m_rotationManipulators.SetLocalPosition(nonUniformScale * colliderOffset); } void ColliderRotationMode::Teardown(const AZ::EntityComponentIdPair& idPair) diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index 7e1d1c341f..1adc4b941f 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -581,9 +581,8 @@ namespace PhysX AZ::Transform EditorColliderComponent::GetColliderLocalTransform() const { - const AZ::Vector3 nonUniformScale = Utils::GetTransformScale(GetEntityId()); return AZ::Transform::CreateFromQuaternionAndTranslation( - m_configuration.m_rotation, m_configuration.m_position * nonUniformScale); + m_configuration.m_rotation, m_configuration.m_position); } void EditorColliderComponent::UpdateMeshAsset() @@ -1053,12 +1052,22 @@ namespace PhysX AZ::Transform EditorColliderComponent::GetCurrentTransform() { - return GetColliderWorldTransform(); + return GetWorldTM(); + } + + AZ::Transform EditorColliderComponent::GetCurrentLocalTransform() + { + return GetColliderLocalTransform(); } AZ::Vector3 EditorColliderComponent::GetBoxScale() { - return AZ::Vector3(GetWorldTM().GetUniformScale()); + return AZ::Vector3::CreateOne(); + } + + AZ::Vector3 EditorColliderComponent::GetCurrentNonUniformScale() + { + return m_cachedNonUniformScale; } void EditorColliderComponent::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) @@ -1202,7 +1211,7 @@ namespace PhysX AZ::Transform EditorColliderComponent::GetColliderWorldTransform() { - return AzToolsFramework::TransformNormalizedScale(GetWorldTM()) * GetColliderLocalTransform(); + return GetWorldTM() * GetColliderLocalTransform(); } bool EditorColliderComponent::ShouldUpdateCollisionMeshFromRender() const diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.h b/Gems/PhysX/Code/Source/EditorColliderComponent.h index 773dd0a9b8..52d788ecef 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.h +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.h @@ -171,7 +171,9 @@ namespace PhysX AZ::Vector3 GetDimensions() override; void SetDimensions(const AZ::Vector3& dimensions) override; AZ::Transform GetCurrentTransform() override; + AZ::Transform GetCurrentLocalTransform() override; AZ::Vector3 GetBoxScale() override; + AZ::Vector3 GetCurrentNonUniformScale() override; // AZ::Render::MeshComponentNotificationBus void OnModelReady(const AZ::Data::Asset& modelAsset,