diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Decals/DecalFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Decals/DecalFeatureProcessorInterface.h index 214feb2040..a7aebf5aa4 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Decals/DecalFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Decals/DecalFeatureProcessorInterface.h @@ -88,7 +88,10 @@ namespace AZ //! Sets the transform of the decal //! Equivalent to calling SetDecalPosition() + SetDecalOrientation() + SetDecalHalfSize() + //! @{ virtual void SetDecalTransform(DecalHandle handle, const AZ::Transform& world) = 0; + virtual void SetDecalTransform(DecalHandle handle, const AZ::Transform& world, const AZ::Vector3& nonUniformScale) = 0; + //! @} //! Sets the material information for this decal virtual void SetDecalMaterial(DecalHandle handle, const AZ::Data::AssetId) = 0; diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.cpp index 7abc6698fa..55fa633e5d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.cpp @@ -264,7 +264,12 @@ namespace AZ void DecalFeatureProcessor::SetDecalTransform(DecalHandle handle, const AZ::Transform& world) { - // https://jira.agscollab.com/browse/ATOM-4330 + SetDecalTransform(handle, world, AZ::Vector3::CreateOne()); + } + + void DecalFeatureProcessor::SetDecalTransform(DecalHandle handle, const AZ::Transform& world, const AZ::Vector3& nonUniformScale) + { + // ATOM-4330 // Original Open 3D Engine uploads a 4x4 matrix rather than quaternion, rotation, scale. // That is more memory but less calculation because it is doing a matrix inverse rather than a polar decomposition // I've done some experiments and uploading a 3x4 transform matrix with 3x3 matrix inverse should be possible @@ -274,7 +279,7 @@ namespace AZ if (handle.IsValid()) { Quaternion orientation = world.GetRotation(); - Vector3 scale = world.GetScale(); + Vector3 scale = world.GetScale() * nonUniformScale; SetDecalHalfSize(handle, scale); SetDecalPosition(handle, world.GetTranslation()); diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.h index 9c4acf6322..3b99715d5a 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalFeatureProcessor.h @@ -73,7 +73,10 @@ namespace AZ //! Sets the transform of the decal //! Equivalent to calling SetDecalPosition() + SetDecalOrientation() + SetDecalHalfSize() + //! @{ void SetDecalTransform(DecalHandle handle, const AZ::Transform& world) override; + void SetDecalTransform(DecalHandle handle, const AZ::Transform& world, const AZ::Vector3& nonUniformScale) override; + //! @} //! Sets the material information for this decal void SetDecalMaterial(DecalHandle handle, const AZ::Data::AssetId) override; diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp index 9d1ea4e680..4000df646d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.cpp @@ -270,10 +270,16 @@ namespace AZ } void DecalTextureArrayFeatureProcessor::SetDecalTransform(DecalHandle handle, const AZ::Transform& world) + { + SetDecalTransform(handle, world, AZ::Vector3::CreateOne()); + } + + void DecalTextureArrayFeatureProcessor::SetDecalTransform(DecalHandle handle, const AZ::Transform& world, + const AZ::Vector3& nonUniformScale) { if (handle.IsValid()) { - SetDecalHalfSize(handle, world.GetScale()); + SetDecalHalfSize(handle, nonUniformScale * world.GetScale()); SetDecalPosition(handle, world.GetTranslation()); SetDecalOrientation(handle, world.GetRotation()); diff --git a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h index 7ab073c7f9..825e461fc2 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Decals/DecalTextureArrayFeatureProcessor.h @@ -82,7 +82,10 @@ namespace AZ //! Sets the transform of the decal //! Equivalent to calling SetDecalPosition() + SetDecalOrientation() + SetDecalHalfSize() + //! @{ void SetDecalTransform(const DecalHandle handle, const AZ::Transform& world) override; + void SetDecalTransform(const DecalHandle handle, const AZ::Transform& world, const AZ::Vector3& nonUniformScale) override; + //! @} //! Sets the material information for this decal void SetDecalMaterial(const DecalHandle handle, const AZ::Data::AssetId id) override; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp index 22a7e1c6c0..3c748e352e 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.cpp @@ -75,6 +75,12 @@ namespace AZ incompatible.push_back(AZ_CRC_CE("DecalService")); } + void DecalComponentController::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) + { + dependent.push_back(AZ_CRC_CE("TransformService")); + dependent.push_back(AZ_CRC_CE("NonUniformScaleService")); + } + DecalComponentController::DecalComponentController(const DecalComponentConfig& config) : m_configuration(config) { @@ -90,6 +96,11 @@ namespace AZ m_handle = m_featureProcessor->AcquireDecal(); } + m_cachedNonUniformScale = AZ::Vector3::CreateOne(); + AZ::NonUniformScaleRequestBus::EventResult(m_cachedNonUniformScale, m_entityId, &AZ::NonUniformScaleRequests::GetScale); + AZ::NonUniformScaleRequestBus::Event(m_entityId, &AZ::NonUniformScaleRequests::RegisterScaleChangedEvent, + m_nonUniformScaleChangedHandler); + AZ::Transform local, world; AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::GetLocalAndWorld, local, world); OnTransformChanged(local, world); @@ -103,6 +114,7 @@ namespace AZ { DecalRequestBus::Handler::BusDisconnect(m_entityId); TransformNotificationBus::Handler::BusDisconnect(m_entityId); + m_nonUniformScaleChangedHandler.Disconnect(); if (m_featureProcessor) { m_featureProcessor->ReleaseDecal(m_handle); @@ -125,7 +137,18 @@ namespace AZ { if (m_featureProcessor) { - m_featureProcessor->SetDecalTransform(m_handle, world); + m_featureProcessor->SetDecalTransform(m_handle, world, m_cachedNonUniformScale); + } + } + + void DecalComponentController::HandleNonUniformScaleChange(const AZ::Vector3& nonUniformScale) + { + m_cachedNonUniformScale = nonUniformScale; + if (m_featureProcessor) + { + AZ::Transform world = AZ::Transform::CreateIdentity(); + AZ::TransformBus::EventResult(world, m_entityId, &AZ::TransformBus::Events::GetWorldTM); + m_featureProcessor->SetDecalTransform(m_handle, world, nonUniformScale); } } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.h index dc6b6e70ea..14204c43dc 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Decals/DecalComponentController.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,7 @@ namespace AZ static void Reflect(AZ::ReflectContext* context); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); DecalComponentController() = default; DecalComponentController(const DecalComponentConfig& config); @@ -64,11 +66,18 @@ namespace AZ void OpacityChanged(); void SortKeyChanged(); void MaterialChanged(); + void HandleNonUniformScaleChange(const AZ::Vector3& nonUniformScale); DecalComponentConfig m_configuration; DecalFeatureProcessorInterface* m_featureProcessor = nullptr; DecalFeatureProcessorInterface::DecalHandle m_handle; EntityId m_entityId; + AZ::Vector3 m_cachedNonUniformScale = AZ::Vector3::CreateOne(); + + AZ::NonUniformScaleChangedEvent::Handler m_nonUniformScaleChangedHandler + { + [&](const AZ::Vector3& nonUniformScale) { HandleNonUniformScaleChange(nonUniformScale); } + }; }; } // namespace Render } // AZ namespace diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp index deab9d2715..70627fd2f1 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp @@ -131,6 +131,7 @@ namespace AZ void MeshComponentController::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) { dependent.push_back(AZ_CRC("TransformService", 0x8ee22c50)); + dependent.push_back(AZ_CRC_CE("NonUniformScaleService")); } void MeshComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)