From a4d5587183d66dd5bf606472fccdd6fa065b0e5a Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 4 Feb 2022 18:30:09 +0000 Subject: [PATCH] fix scaling manipulator for sphere collider with non-uniform scale Signed-off-by: greerdv --- Gems/PhysX/Code/Editor/ColliderSphereMode.cpp | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/Gems/PhysX/Code/Editor/ColliderSphereMode.cpp b/Gems/PhysX/Code/Editor/ColliderSphereMode.cpp index ba0fd76ea9..335d1339a8 100644 --- a/Gems/PhysX/Code/Editor/ColliderSphereMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderSphereMode.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -24,10 +25,27 @@ namespace PhysX static const float MinSphereRadius = 0.01f; static const AZ::Vector3 ManipulatorAxis = AZ::Vector3::CreateAxisX(); + AZ::Transform GetColliderLocalTransform(const AZ::EntityComponentIdPair& idPair) + { + AZ::Quaternion colliderRotation = AZ::Quaternion::CreateIdentity(); + PhysX::EditorColliderComponentRequestBus::EventResult(colliderRotation, idPair, &PhysX::EditorColliderComponentRequests::GetColliderRotation); + + AZ::Vector3 colliderOffset = AZ::Vector3::CreateZero(); + PhysX::EditorColliderComponentRequestBus::EventResult(colliderOffset, idPair, &PhysX::EditorColliderComponentRequests::GetColliderOffset); + + return AZ::Transform::CreateFromQuaternionAndTranslation(colliderRotation, colliderOffset); + } + void ColliderSphereMode::Setup(const AZ::EntityComponentIdPair& idPair) { AZ::Transform colliderWorldTransform = AZ::Transform::Identity(); - PhysX::EditorColliderComponentRequestBus::EventResult(colliderWorldTransform, idPair, &PhysX::EditorColliderComponentRequests::GetColliderWorldTransform); + AZ::TransformBus::EventResult(colliderWorldTransform, idPair.GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); + //PhysX::EditorColliderComponentRequestBus::EventResult(colliderWorldTransform, idPair, &PhysX::EditorColliderComponentRequests::GetColliderWorldTransform); + + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); + AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, idPair.GetEntityId(), &AZ::NonUniformScaleRequests::GetScale); + + const AZ::Transform colliderLocalTransform = GetColliderLocalTransform(idPair); float sphereRadius = 0.0f; PhysX::EditorColliderComponentRequestBus::EventResult(sphereRadius, idPair, &PhysX::EditorColliderComponentRequests::GetSphereRadius); @@ -36,7 +54,10 @@ namespace PhysX m_radiusManipulator->AddEntityComponentIdPair(idPair); m_radiusManipulator->SetAxis(ManipulatorAxis); m_radiusManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId); - m_radiusManipulator->SetLocalPosition(ManipulatorAxis * sphereRadius); + //m_radiusManipulator->SetLocalPosition(ManipulatorAxis * sphereRadius); + m_radiusManipulator->SetLocalTransform(colliderLocalTransform * AZ::Transform::CreateTranslation(ManipulatorAxis * sphereRadius)); + m_radiusManipulator->SetNonUniformScale(nonUniformScale); + m_radiusManipulator->SetBoundsDirty(); AzToolsFramework::ManipulatorViews views; views.emplace_back(AzToolsFramework::CreateManipulatorViewQuadBillboard(AzFramework::ViewportColors::DefaultManipulatorHandleColor, AzFramework::ViewportConstants::DefaultManipulatorHandleSize)); @@ -53,12 +74,19 @@ namespace PhysX void ColliderSphereMode::Refresh(const AZ::EntityComponentIdPair& idPair) { AZ::Transform colliderWorldTransform = AZ::Transform::Identity(); - PhysX::EditorColliderComponentRequestBus::EventResult(colliderWorldTransform, idPair, &PhysX::EditorColliderComponentRequests::GetColliderWorldTransform); + AZ::TransformBus::EventResult(colliderWorldTransform, idPair.GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); + //PhysX::EditorColliderComponentRequestBus::EventResult(colliderWorldTransform, idPair, &PhysX::EditorColliderComponentRequests::GetColliderWorldTransform); m_radiusManipulator->SetSpace(colliderWorldTransform); + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); + AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, idPair.GetEntityId(), &AZ::NonUniformScaleRequests::GetScale); + + const AZ::Transform colliderLocalTransform = GetColliderLocalTransform(idPair); + float sphereRadius = 0.0f; PhysX::EditorColliderComponentRequestBus::EventResult(sphereRadius, idPair, &PhysX::EditorColliderComponentRequests::GetSphereRadius); - m_radiusManipulator->SetLocalPosition(ManipulatorAxis * sphereRadius); + m_radiusManipulator->SetLocalTransform(colliderLocalTransform * AZ::Transform::CreateTranslation(ManipulatorAxis * sphereRadius)); + m_radiusManipulator->SetBoundsDirty(); } void ColliderSphereMode::Teardown(const AZ::EntityComponentIdPair& idPair) @@ -80,22 +108,35 @@ namespace PhysX AZ_UNUSED(debugDisplay); const AzFramework::CameraState cameraState = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId); - float radius = m_radiusManipulator->GetLocalPosition().GetLength(); - m_radiusManipulator->SetAxis(cameraState.m_side); - m_radiusManipulator->SetLocalPosition(cameraState.m_side * radius); + if (!m_radiusManipulator->EntityComponentIdPairs().empty()) + { + const AZ::EntityComponentIdPair idPair = *m_radiusManipulator->EntityComponentIdPairs().begin(); + float radius = 0.0f; + PhysX::EditorColliderComponentRequestBus::EventResult(radius, idPair, &PhysX::EditorColliderComponentRequests::GetSphereRadius); + const AZ::Transform colliderLocalTransform = GetColliderLocalTransform(idPair); + m_radiusManipulator->SetAxis(cameraState.m_side); + m_radiusManipulator->SetLocalTransform(GetColliderLocalTransform(idPair) * AZ::Transform::CreateTranslation(cameraState.m_side * radius)); + } } void ColliderSphereMode::OnManipulatorMoved(const AzToolsFramework::LinearManipulator::Action& action, const AZ::EntityComponentIdPair& idPair) { + // manipulator offsets do not take transform scale into account, need to handle it here + AZ::Transform colliderWorldTransform = AZ::Transform::CreateIdentity(); + AZ::TransformBus::EventResult(colliderWorldTransform, idPair.GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); + const float transformScale = AZ::GetMax(AZ::MinTransformScale, colliderWorldTransform.GetUniformScale()); + const AZ::Vector3 localPosition = action.m_start.m_localPosition + action.m_current.m_localPositionOffset / transformScale; + // Get the distance the manipulator has moved along the axis. - float extent = action.LocalPosition().Dot(action.m_fixed.m_axis); + float extent = localPosition.Dot(action.m_fixed.m_axis); // Clamp the distance to a small value to prevent it going negative. extent = AZ::GetMax(extent, MinSphereRadius); // Update the manipulator and sphere radius - m_radiusManipulator->SetLocalPosition(extent * action.m_fixed.m_axis); + m_radiusManipulator->SetLocalTransform( + GetColliderLocalTransform(idPair) * AZ::Transform::CreateTranslation(extent * action.m_fixed.m_axis)); PhysX::EditorColliderComponentRequestBus::Event(idPair, &PhysX::EditorColliderComponentRequests::SetSphereRadius, extent); } }