From 2fb2813b485f624cef957c68310e47e3597c51bc Mon Sep 17 00:00:00 2001 From: greerdv Date: Wed, 14 Apr 2021 14:05:59 +0100 Subject: [PATCH] updating atom mesh component to support non-uniform scale component --- Code/Framework/AzCore/AzCore/Math/Aabb.cpp | 31 ++++++++++++++- Code/Framework/AzCore/AzCore/Math/Aabb.h | 10 ++++- Code/Framework/AzCore/AzCore/Math/Aabb.inl | 8 ++++ .../Atom/Feature/Mesh/MeshFeatureProcessor.h | 4 +- .../Mesh/MeshFeatureProcessorInterface.h | 8 ++-- .../ReflectionProbeFeatureProcessor.h | 2 +- ...ReflectionProbeFeatureProcessorInterface.h | 2 +- .../TransformServiceFeatureProcessor.h | 4 +- ...ransformServiceFeatureProcessorInterface.h | 8 ++-- .../Code/Mocks/MockMeshFeatureProcessor.h | 4 +- .../Code/Source/AuxGeom/AuxGeomDrawQueue.cpp | 2 +- .../DiffuseProbeGridRayTracingPass.cpp | 8 ++-- .../Code/Source/Mesh/MeshFeatureProcessor.cpp | 18 ++++----- .../RayTracingAccelerationStructurePass.cpp | 2 +- .../RayTracing/RayTracingFeatureProcessor.cpp | 6 +-- .../RayTracing/RayTracingFeatureProcessor.h | 4 +- .../ReflectionProbe/ReflectionProbe.cpp | 8 ++-- .../Source/ReflectionProbe/ReflectionProbe.h | 2 +- .../ReflectionProbeFeatureProcessor.cpp | 8 ++-- .../TransformServiceFeatureProcessor.cpp | 8 ++-- .../RHI/RayTracingAccelerationStructure.h | 6 +-- .../RHI/RayTracingAccelerationStructure.cpp | 6 +-- .../DX12/Code/Source/RHI/RayTracingTlas.cpp | 3 +- .../Vulkan/Code/Source/RHI/RayTracingTlas.cpp | 4 +- .../Include/Atom/RPI.Public/Model/Model.h | 4 +- .../Code/Source/RPI.Public/Model/Model.cpp | 6 +-- .../Code/Source/Mesh/EditorMeshComponent.cpp | 5 ++- .../Source/Mesh/MeshComponentController.cpp | 38 ++++++++++++++++--- .../Source/Mesh/MeshComponentController.h | 10 +++++ .../ReflectionProbeComponentController.cpp | 2 +- .../Code/Source/AtomActorInstance.cpp | 5 ++- .../Editor/EditorBlastMeshDataComponent.cpp | 4 +- .../Code/Source/Family/ActorRenderManager.cpp | 6 +-- .../Code/Tests/ActorRenderManagerTest.cpp | 2 +- .../Rendering/Atom/WhiteBoxAtomRenderMesh.cpp | 2 +- 35 files changed, 166 insertions(+), 84 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Math/Aabb.cpp b/Code/Framework/AzCore/AzCore/Math/Aabb.cpp index 94e138d88d..48e51cce48 100644 --- a/Code/Framework/AzCore/AzCore/Math/Aabb.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Aabb.cpp @@ -146,8 +146,8 @@ namespace AZ ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) ->Method("GetTranslated", &Aabb::GetTranslated) ->Method("GetSurfaceArea", &Aabb::GetSurfaceArea) - ->Method("GetTransformedObb", &Aabb::GetTransformedObb) - ->Method("GetTransformedAabb", &Aabb::GetTransformedAabb) + ->Method("GetTransformedObb", static_cast(&Aabb::GetTransformedObb)) + ->Method("GetTransformedAabb", static_cast(&Aabb::GetTransformedAabb)) ->Method("ApplyTransform", &Aabb::ApplyTransform) ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) ->Method("Clone", [](const Aabb& rhs) -> Aabb { return rhs; }) @@ -195,6 +195,20 @@ namespace AZ } + Obb Aabb::GetTransformedObb(const Matrix3x4& matrix3x4) const + { + Matrix3x4 matrixNoScale = matrix3x4; + const AZ::Vector3 scale = matrixNoScale.ExtractScale(); + const AZ::Quaternion rotation = AZ::Quaternion::CreateFromMatrix3x4(matrixNoScale); + + return Obb::CreateFromPositionRotationAndHalfLengths( + matrix3x4 * GetCenter(), + rotation, + 0.5f * scale * GetExtents() + ); + } + + void Aabb::ApplyTransform(const Transform& transform) { Vector3 a, b, axisCoeffs; @@ -224,4 +238,17 @@ namespace AZ m_min = newMin; m_max = newMax; } + + + void Aabb::ApplyMatrix3x4(const Matrix3x4& matrix3x4) + { + const AZ::Vector3 extents = GetExtents(); + const AZ::Vector3 center = GetCenter(); + AZ::Vector3 newHalfExtents( + 0.5f * matrix3x4.GetRowAsVector3(0).GetAbs().Dot(extents), + 0.5f * matrix3x4.GetRowAsVector3(1).GetAbs().Dot(extents), + 0.5f * matrix3x4.GetRowAsVector3(2).GetAbs().Dot(extents)); + m_min = center - newHalfExtents; + m_max = center + newHalfExtents; + } } diff --git a/Code/Framework/AzCore/AzCore/Math/Aabb.h b/Code/Framework/AzCore/AzCore/Math/Aabb.h index 0aebd099f4..474ac2e2ee 100644 --- a/Code/Framework/AzCore/AzCore/Math/Aabb.h +++ b/Code/Framework/AzCore/AzCore/Math/Aabb.h @@ -129,12 +129,20 @@ namespace AZ void ApplyTransform(const Transform& transform); + void ApplyMatrix3x4(const Matrix3x4& matrix3x4); + //! Transforms an Aabb and returns the resulting Obb. - class Obb GetTransformedObb(const Transform& transform) const; + Obb GetTransformedObb(const Transform& transform) const; + + //! Transforms an Aabb and returns the resulting Obb. + Obb GetTransformedObb(const Matrix3x4& matrix3x4) const; //! Returns a new AABB containing the transformed AABB. Aabb GetTransformedAabb(const Transform& transform) const; + //! Returns a new AABB containing the transformed AABB. + Aabb GetTransformedAabb(const Matrix3x4& matrix3x4) const; + //! Checks if this aabb is equal to another within a floating point tolerance. bool IsClose(const Aabb& rhs, float tolerance = Constants::Tolerance) const; diff --git a/Code/Framework/AzCore/AzCore/Math/Aabb.inl b/Code/Framework/AzCore/AzCore/Math/Aabb.inl index 5e6a5ae188..94ad3e3e7d 100644 --- a/Code/Framework/AzCore/AzCore/Math/Aabb.inl +++ b/Code/Framework/AzCore/AzCore/Math/Aabb.inl @@ -300,6 +300,14 @@ namespace AZ } + AZ_MATH_INLINE Aabb Aabb::GetTransformedAabb(const Matrix3x4& matrix3x4) const + { + Aabb aabb = Aabb::CreateFromMinMax(m_min, m_max); + aabb.ApplyMatrix3x4(matrix3x4); + return aabb; + } + + AZ_MATH_INLINE bool Aabb::IsClose(const Aabb& rhs, float tolerance) const { return m_min.IsClose(rhs.m_min, tolerance) && m_max.IsClose(rhs.m_max, tolerance); diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h index a595471813..cc26ff862a 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h @@ -144,8 +144,8 @@ namespace AZ const MaterialAssignmentMap& GetMaterialAssignmentMap(const MeshHandle& meshHandle) const override; void ConnectModelChangeEventHandler(const MeshHandle& meshHandle, ModelChangedEvent::Handler& handler) override; - void SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform) override; - Transform GetTransform(const MeshHandle& meshHandle) override; + void SetMatrix3x4(const MeshHandle& meshHandle, const AZ::Matrix3x4& matrix3x4) override; + Matrix3x4 GetMatrix3x4(const MeshHandle& meshHandle) override; void SetSortKey(const MeshHandle& meshHandle, RHI::DrawItemSortKey sortKey) override; RHI::DrawItemSortKey GetSortKey(const MeshHandle& meshHandle) override; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h index 77e3467fb9..ef8084d534 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h @@ -61,10 +61,10 @@ namespace AZ virtual const MaterialAssignmentMap& GetMaterialAssignmentMap(const MeshHandle& meshHandle) const = 0; //! Connects a handler to any changes to an RPI::Model. Changes include loading and reloading. virtual void ConnectModelChangeEventHandler(const MeshHandle& meshHandle, ModelChangedEvent::Handler& handler) = 0; - //! Sets the transform for a given mesh handle. - virtual void SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform) = 0; - //! Gets the transform for a given mesh handle. - virtual Transform GetTransform(const MeshHandle& meshHandle) = 0; + //! Sets the Matrix3x4 for a given mesh handle. + virtual void SetMatrix3x4(const MeshHandle& meshHandle, const AZ::Matrix3x4& matrix3x4) = 0; + //! Gets the Matrix3x4 for a given mesh handle. + virtual Matrix3x4 GetMatrix3x4(const MeshHandle& meshHandle) = 0; //! Sets the sort key for a given mesh handle. virtual void SetSortKey(const MeshHandle& meshHandle, RHI::DrawItemSortKey sortKey) = 0; //! Gets the sort key for a given mesh handle. diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h index a89875aaa6..610bb40369 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h @@ -37,7 +37,7 @@ namespace AZ void SetProbeOuterExtents(const ReflectionProbeHandle& probe, const AZ::Vector3& outerExtents) override; void SetProbeInnerExtents(const ReflectionProbeHandle& probe, const AZ::Vector3& innerExtents) override; void SetProbeCubeMap(const ReflectionProbeHandle& probe, Data::Instance& cubeMapImage) override; - void SetProbeTransform(const ReflectionProbeHandle& probe, const AZ::Transform& transform) override; + void SetProbeMatrix3x4(const ReflectionProbeHandle& probe, const AZ::Matrix3x4& matrix3x4) override; void BakeProbe(const ReflectionProbeHandle& probe, BuildCubeMapCallback callback) override; void NotifyCubeMapAssetReady(const AZStd::string relativePath, NotifyCubeMapAssetReadyCallback callback) override; bool IsValidProbeHandle(const ReflectionProbeHandle& probe) const override { return (probe.get() != nullptr); } diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessorInterface.h index 8b277e97c8..3053d9d44f 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessorInterface.h @@ -48,7 +48,7 @@ namespace AZ virtual void SetProbeOuterExtents(const ReflectionProbeHandle& handle, const AZ::Vector3& outerExtents) = 0; virtual void SetProbeInnerExtents(const ReflectionProbeHandle& handle, const AZ::Vector3& innerExtents) = 0; virtual void SetProbeCubeMap(const ReflectionProbeHandle& handle, Data::Instance& cubeMapImage) = 0; - virtual void SetProbeTransform(const ReflectionProbeHandle& handle, const AZ::Transform& transform) = 0; + virtual void SetProbeMatrix3x4(const ReflectionProbeHandle& handle, const AZ::Matrix3x4& matrix3x4) = 0; virtual void BakeProbe(const ReflectionProbeHandle& handle, BuildCubeMapCallback callback) = 0; virtual void NotifyCubeMapAssetReady(const AZStd::string relativePath, NotifyCubeMapAssetReadyCallback callback) = 0; virtual bool IsValidProbeHandle(const ReflectionProbeHandle& probe) const = 0; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessor.h index 2344f745f8..d6338d6b0c 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessor.h @@ -50,8 +50,8 @@ namespace AZ // TransformServiceFeatureProcessorInterface overrides ... ObjectId ReserveObjectId() override; void ReleaseObjectId(ObjectId& id) override; - void SetTransformForId(ObjectId id, const AZ::Transform& transform) override; - AZ::Transform GetTransformForId(ObjectId id) const override; + void SetMatrix3x4ForId(ObjectId id, const AZ::Matrix3x4& matrix3x4) override; + AZ::Matrix3x4 GetMatrix3x4ForId(ObjectId id) const override; private: diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessorInterface.h index 0b17a9a5a0..b75257c485 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/TransformService/TransformServiceFeatureProcessorInterface.h @@ -34,10 +34,10 @@ namespace AZ //! Releases an object ID to be used by others. The passed in handle is invalidated. virtual void ReleaseObjectId(ObjectId& id) = 0; - //! Sets the transform for a given id. Id must be one reserved earlier. - virtual void SetTransformForId(ObjectId id, const AZ::Transform& transform) = 0; - //! Gets the transform for a given id. Id must be one reserved earlier. - virtual AZ::Transform GetTransformForId(ObjectId) const = 0; + //! Sets the Matrix3x4 for a given id. Id must be one reserved earlier. + virtual void SetMatrix3x4ForId(ObjectId id, const AZ::Matrix3x4& transform) = 0; + //! Gets the Matrix3x4 for a given id. Id must be one reserved earlier. + virtual AZ::Matrix3x4 GetMatrix3x4ForId(ObjectId) const = 0; }; } diff --git a/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h index 6fc1ac0e30..b6428754b5 100644 --- a/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h @@ -31,11 +31,11 @@ namespace UnitTest MOCK_CONST_METHOD1(GetModel, AZStd::intrusive_ptr(const MeshHandle&)); MOCK_CONST_METHOD1(GetMaterialAssignmentMap, const AZ::Render::MaterialAssignmentMap&(const MeshHandle&)); MOCK_METHOD2(ConnectModelChangeEventHandler, void(const MeshHandle&, ModelChangedEvent::Handler&)); - MOCK_METHOD2(SetTransform, void(const MeshHandle&, const AZ::Transform&)); + MOCK_METHOD2(SetMatrix3x4, void(const MeshHandle&, const AZ::Matrix3x4&)); MOCK_METHOD2(SetExcludeFromReflectionCubeMaps, void(const MeshHandle&, bool)); MOCK_METHOD2(SetMaterialAssignmentMap, void(const MeshHandle&, const AZ::Data::Instance&)); MOCK_METHOD2(SetMaterialAssignmentMap, void(const MeshHandle&, const AZ::Render::MaterialAssignmentMap&)); - MOCK_METHOD1(GetTransform, AZ::Transform (const MeshHandle&)); + MOCK_METHOD1(GetMatrix3x4, AZ::Matrix3x4 (const MeshHandle&)); MOCK_METHOD2(SetSortKey, void (const MeshHandle&, AZ::RHI::DrawItemSortKey)); MOCK_METHOD1(GetSortKey, AZ::RHI::DrawItemSortKey(const MeshHandle&)); MOCK_METHOD2(SetLodOverride, void(const MeshHandle&, AZ::RPI::Cullable::LodOverride)); diff --git a/Gems/Atom/Feature/Common/Code/Source/AuxGeom/AuxGeomDrawQueue.cpp b/Gems/Atom/Feature/Common/Code/Source/AuxGeom/AuxGeomDrawQueue.cpp index fd4b5b28d1..c412746676 100644 --- a/Gems/Atom/Feature/Common/Code/Source/AuxGeom/AuxGeomDrawQueue.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/AuxGeom/AuxGeomDrawQueue.cpp @@ -504,7 +504,7 @@ namespace AZ box.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull); box.m_color = color; box.m_scale = localMatrix3x4.ExtractScale() * extents; - box.m_position = localMatrix3x4.GetTranslation() + center; + box.m_position = matrix3x4 * center; box.m_rotationMatrix = Matrix3x3::CreateFromMatrix3x4(localMatrix3x4); box.m_pointSize = m_pointSize; box.m_viewProjOverrideIndex = viewProjOverrideIndex; diff --git a/Gems/Atom/Feature/Common/Code/Source/DiffuseProbeGrid/DiffuseProbeGridRayTracingPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DiffuseProbeGrid/DiffuseProbeGridRayTracingPass.cpp index f6eeaf2971..f5e4f29cea 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DiffuseProbeGrid/DiffuseProbeGridRayTracingPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DiffuseProbeGrid/DiffuseProbeGridRayTracingPass.cpp @@ -186,10 +186,10 @@ namespace AZ // set irradiance color and worldInverseTranspose constants Vector4 color(subMesh.m_irradianceColor.GetR(), subMesh.m_irradianceColor.GetG(), subMesh.m_irradianceColor.GetB(), 1.0f); - AZ::Transform meshTransform = transformFeatureProcessor->GetTransformForId(TransformServiceFeatureProcessorInterface::ObjectId(mesh.first)); - AZ::Transform noScaleTransform = meshTransform; - noScaleTransform.ExtractScale(); - AZ::Matrix3x3 rotationMatrix = Matrix3x3::CreateFromTransform(noScaleTransform); + AZ::Matrix3x4 meshMatrix3x4 = transformFeatureProcessor->GetMatrix3x4ForId(TransformServiceFeatureProcessorInterface::ObjectId(mesh.first)); + AZ::Matrix3x4 noScaleMatrix3x4 = meshMatrix3x4; + noScaleMatrix3x4.ExtractScale(); + AZ::Matrix3x3 rotationMatrix = Matrix3x3::CreateFromMatrix3x4(noScaleMatrix3x4); rotationMatrix = rotationMatrix.GetInverseFull().GetTranspose(); m_closestHitData[m_meshCount].m_materialColor = color; diff --git a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp index 1f5b8ecc65..40873ccea0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp @@ -256,7 +256,7 @@ namespace AZ } } - void MeshFeatureProcessor::SetTransform(const MeshHandle& meshHandle, const AZ::Transform& transform) + void MeshFeatureProcessor::SetMatrix3x4(const MeshHandle& meshHandle, const AZ::Matrix3x4& matrix3x4) { if (meshHandle.IsValid()) { @@ -264,26 +264,26 @@ namespace AZ meshData.m_cullBoundsNeedsUpdate = true; meshData.m_objectSrgNeedsUpdate = true; - m_transformService->SetTransformForId(meshHandle->m_objectId, transform); + m_transformService->SetMatrix3x4ForId(meshHandle->m_objectId, matrix3x4); // ray tracing data needs to be updated with the new transform if (m_rayTracingFeatureProcessor) { - m_rayTracingFeatureProcessor->SetMeshTransform(meshHandle->m_objectId, transform); + m_rayTracingFeatureProcessor->SetMeshMatrix3x4(meshHandle->m_objectId, matrix3x4); } } } - Transform MeshFeatureProcessor::GetTransform(const MeshHandle& meshHandle) + Matrix3x4 MeshFeatureProcessor::GetMatrix3x4(const MeshHandle& meshHandle) { if (meshHandle.IsValid()) { - return m_transformService->GetTransformForId(meshHandle->m_objectId); + return m_transformService->GetMatrix3x4ForId(meshHandle->m_objectId); } else { AZ_Assert(false, "Invalid mesh handle"); - return Transform::CreateIdentity(); + return Matrix3x4::CreateIdentity(); } } @@ -841,7 +841,7 @@ namespace AZ AZ_Assert(m_cullBoundsNeedsUpdate, "This function only needs to be called if the culling bounds need to be rebuilt"); AZ_Assert(m_model, "The model has not finished loading yet"); - Transform localToWorld = transformService->GetTransformForId(m_objectId); + Matrix3x4 localToWorld = transformService->GetMatrix3x4ForId(m_objectId); Vector3 center; float radius; @@ -919,11 +919,11 @@ namespace AZ // retrieve the list of probes that contain the centerpoint of the mesh TransformServiceFeatureProcessor* transformServiceFeatureProcessor = m_scene->GetFeatureProcessor(); - Transform transform = transformServiceFeatureProcessor->GetTransformForId(m_objectId); + Matrix3x4 matrix3x4 = transformServiceFeatureProcessor->GetMatrix3x4ForId(m_objectId); ReflectionProbeFeatureProcessor* reflectionProbeFeatureProcessor = m_scene->GetFeatureProcessor(); ReflectionProbeFeatureProcessor::ReflectionProbeVector reflectionProbes; - reflectionProbeFeatureProcessor->FindReflectionProbes(transform.GetTranslation(), reflectionProbes); + reflectionProbeFeatureProcessor->FindReflectionProbes(matrix3x4.GetTranslation(), reflectionProbes); if (!reflectionProbes.empty() && reflectionProbes[0]) { diff --git a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp index f874f87b4a..7e39f968fd 100644 --- a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingAccelerationStructurePass.cpp @@ -83,7 +83,7 @@ namespace AZ ->InstanceID(blasIndex) ->HitGroupIndex(blasIndex) ->Blas(rayTracingSubMesh.m_blas) - ->Transform(rayTracingMesh.second.m_transform) + ->Matrix3x4(rayTracingMesh.second.m_matrix3x4) ; } diff --git a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.cpp index abced377a0..1e7fc464df 100644 --- a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.cpp @@ -97,7 +97,7 @@ namespace AZ } // set initial transform - mesh.m_transform = m_transformServiceFeatureProcessor->GetTransformForId(objectId); + mesh.m_matrix3x4 = m_transformServiceFeatureProcessor->GetMatrix3x4ForId(objectId); m_revision++; m_subMeshCount += aznumeric_cast(subMeshes.size()); @@ -119,7 +119,7 @@ namespace AZ } } - void RayTracingFeatureProcessor::SetMeshTransform(const ObjectId objectId, AZ::Transform transform) + void RayTracingFeatureProcessor::SetMeshMatrix3x4(const ObjectId objectId, const AZ::Matrix3x4 matrix3x4) { if (!m_rayTracingEnabled) { @@ -129,7 +129,7 @@ namespace AZ MeshMap::iterator itMesh = m_meshes.find(objectId.GetIndex()); if (itMesh != m_meshes.end()) { - itMesh->second.m_transform = transform; + itMesh->second.m_matrix3x4 = matrix3x4; m_revision++; } } diff --git a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.h index 09a4a6f63c..af5bfd0d51 100644 --- a/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/RayTracing/RayTracingFeatureProcessor.h @@ -66,7 +66,7 @@ namespace AZ SubMeshVector m_subMeshes; // mesh transform - AZ::Transform m_transform = AZ::Transform::CreateIdentity(); + AZ::Matrix3x4 m_matrix3x4 = AZ::Matrix3x4::CreateIdentity(); // flag indicating if the Blas objects in the sub-meshes are built bool m_blasBuilt = false; @@ -85,7 +85,7 @@ namespace AZ //! Sets the ray tracing mesh transform //! This will cause an update to the RayTracing acceleration structure on the next frame - void SetMeshTransform(const ObjectId objectId, const AZ::Transform transform); + void SetMeshMatrix3x4(const ObjectId objectId, const AZ::Matrix3x4 matrix3x4); //! Retrieves ray tracing data for all meshes in the scene const MeshMap& GetMeshes() const { return m_meshes; } diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp index 51303436ee..f56902ebde 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp @@ -70,7 +70,7 @@ namespace AZ m_visualizationMeshHandle = m_meshFeatureProcessor->AcquireMesh(m_visualizationModelAsset); m_meshFeatureProcessor->SetExcludeFromReflectionCubeMaps(m_visualizationMeshHandle, true); m_meshFeatureProcessor->SetRayTracingEnabled(m_visualizationMeshHandle, false); - m_meshFeatureProcessor->SetTransform(m_visualizationMeshHandle, AZ::Transform::CreateIdentity()); + m_meshFeatureProcessor->SetMatrix3x4(m_visualizationMeshHandle, AZ::Matrix3x4::CreateIdentity()); // We have to pre-load this asset before creating a Material instance because the InstanceDatabase will attempt a blocking load which could deadlock, // particularly when slices are involved. @@ -206,10 +206,10 @@ namespace AZ } - void ReflectionProbe::SetTransform(const AZ::Transform& transform) + void ReflectionProbe::SetMatrix3x4(const AZ::Matrix3x4& matrix3x4) { - m_position = transform.GetTranslation(); - m_meshFeatureProcessor->SetTransform(m_visualizationMeshHandle, transform); + m_position = matrix3x4.GetTranslation(); + m_meshFeatureProcessor->SetMatrix3x4(m_visualizationMeshHandle, matrix3x4); m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_position, m_outerExtents / 2.0f); m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_position, m_innerExtents / 2.0f); m_updateSrg = true; diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h index 22645a4ed3..6b23afb1fc 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h @@ -76,7 +76,7 @@ namespace AZ void Simulate(uint32_t probeIndex); const Vector3& GetPosition() const { return m_position; } - void SetTransform(const AZ::Transform& transform); + void SetMatrix3x4(const AZ::Matrix3x4& matrix3x4); const AZ::Vector3& GetOuterExtents() const { return m_outerExtents; } void SetOuterExtents(const AZ::Vector3& outerExtents); diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp index 80719564b1..8631e334b4 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp @@ -223,7 +223,7 @@ namespace AZ { AZStd::shared_ptr reflectionProbe = AZStd::make_shared(); reflectionProbe->Init(GetParentScene(), &m_reflectionRenderData); - reflectionProbe->SetTransform(transform); + reflectionProbe->SetMatrix3x4(AZ::Matrix3x4::CreateFromTransform(transform)); reflectionProbe->SetUseParallaxCorrection(useParallaxCorrection); m_reflectionProbes.push_back(reflectionProbe); m_probeSortRequired = true; @@ -264,10 +264,10 @@ namespace AZ probe->SetCubeMapImage(cubeMapImage); } - void ReflectionProbeFeatureProcessor::SetProbeTransform(const ReflectionProbeHandle& probe, const AZ::Transform& transform) + void ReflectionProbeFeatureProcessor::SetProbeMatrix3x4(const ReflectionProbeHandle& probe, const AZ::Matrix3x4& matrix3x4) { - AZ_Assert(probe.get(), "SetProbeTransform called with an invalid handle"); - probe->SetTransform(transform); + AZ_Assert(probe.get(), "SetProbeMatrix3x4 called with an invalid handle"); + probe->SetMatrix3x4(matrix3x4); m_probeSortRequired = true; } diff --git a/Gems/Atom/Feature/Common/Code/Source/TransformService/TransformServiceFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/TransformService/TransformServiceFeatureProcessor.cpp index a4f255185a..a3a91ca620 100644 --- a/Gems/Atom/Feature/Common/Code/Source/TransformService/TransformServiceFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/TransformService/TransformServiceFeatureProcessor.cpp @@ -210,14 +210,12 @@ namespace AZ } } - void TransformServiceFeatureProcessor::SetTransformForId(ObjectId id, const AZ::Transform& transform) + void TransformServiceFeatureProcessor::SetMatrix3x4ForId(ObjectId id, const AZ::Matrix3x4& matrix3x4) { AZ_Error("TransformServiceFeatureProcessor", m_isWriteable, "Transform data cannot be written to during this phase"); AZ_Error("TransformServiceFeatureProcessor", id.IsValid(), "Attempting to set the transform for an invalid handle."); if (id.IsValid()) { - AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromTransform(transform); - matrix3x4.StoreToRowMajorFloat12(m_objectToWorldTransforms.at(id.GetIndex()).m_transform); // Inverse transpose to take the non-uniform scale out of the transform for usage with normals. @@ -226,10 +224,10 @@ namespace AZ } } - AZ::Transform TransformServiceFeatureProcessor::GetTransformForId(ObjectId id) const + AZ::Matrix3x4 TransformServiceFeatureProcessor::GetMatrix3x4ForId(ObjectId id) const { AZ_Error("TransformServiceFeatureProcessor", id.IsValid(), "Attempting to set the transform for an invalid handle."); - return AZ::Transform::CreateFromMatrix3x4( Matrix3x4::CreateFromRowMajorFloat12(m_objectToWorldTransforms.at(id.GetIndex()).m_transform) ); + return AZ::Matrix3x4::CreateFromRowMajorFloat12(m_objectToWorldTransforms.at(id.GetIndex()).m_transform); } } } diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/RayTracingAccelerationStructure.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/RayTracingAccelerationStructure.h index 09ba2b1d59..0225673efd 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/RayTracingAccelerationStructure.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/RayTracingAccelerationStructure.h @@ -12,7 +12,7 @@ #pragma once #include -#include +#include #include #include #include @@ -110,7 +110,7 @@ namespace AZ { uint32_t m_instanceID = 0; uint32_t m_hitGroupIndex = 0; - AZ::Transform m_transform = AZ::Transform::CreateIdentity(); + AZ::Matrix3x4 m_matrix3x4 = AZ::Matrix3x4::CreateIdentity(); RHI::Ptr m_blas; }; using RayTracingTlasInstanceVector = AZStd::vector; @@ -153,7 +153,7 @@ namespace AZ RayTracingTlasDescriptor* Instance(); RayTracingTlasDescriptor* InstanceID(uint32_t instanceID); RayTracingTlasDescriptor* HitGroupIndex(uint32_t hitGroupIndex); - RayTracingTlasDescriptor* Transform(const AZ::Transform& transform); + RayTracingTlasDescriptor* Matrix3x4(const AZ::Matrix3x4& matrix3x4); RayTracingTlasDescriptor* Blas(RHI::Ptr& blas); RayTracingTlasDescriptor* InstancesBuffer(RHI::Ptr& tlasInstances); RayTracingTlasDescriptor* NumInstances(uint32_t numInstancesInBuffer); diff --git a/Gems/Atom/RHI/Code/Source/RHI/RayTracingAccelerationStructure.cpp b/Gems/Atom/RHI/Code/Source/RHI/RayTracingAccelerationStructure.cpp index 37e5b316d6..dadaeee5d4 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/RayTracingAccelerationStructure.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/RayTracingAccelerationStructure.cpp @@ -78,10 +78,10 @@ namespace AZ return this; } - RayTracingTlasDescriptor* RayTracingTlasDescriptor::Transform(const AZ::Transform& transform) + RayTracingTlasDescriptor* RayTracingTlasDescriptor::Matrix3x4(const AZ::Matrix3x4& matrix3x4) { - AZ_Assert(m_buildContext, "Transform property can only be added to an Instance entry"); - m_buildContext->m_transform = transform; + AZ_Assert(m_buildContext, "Matrix3x4 property can only be added to an Instance entry"); + m_buildContext->m_matrix3x4 = matrix3x4; return this; } diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingTlas.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingTlas.cpp index 77d8d38e42..8c01b798a6 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingTlas.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/RayTracingTlas.cpp @@ -89,8 +89,7 @@ namespace AZ mappedData[i].InstanceID = instance.m_instanceID; mappedData[i].InstanceContributionToHitGroupIndex = instance.m_hitGroupIndex; // convert transform to row-major 3x4 - AZ::Matrix3x4 matrix34 = AZ::Matrix3x4::CreateFromTransform(instance.m_transform); - matrix34.StoreToRowMajorFloat12(&mappedData[i].Transform[0][0]); + instance.m_matrix3x4.StoreToRowMajorFloat12(&mappedData[i].Transform[0][0]); mappedData[i].AccelerationStructure = static_cast(blas->GetBuffers().m_blasBuffer.get())->GetMemoryView().GetGpuAddress(); // [GFX TODO][ATOM-5270] Add ray tracing TLAS instance mask support mappedData[i].InstanceMask = 0x1; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingTlas.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingTlas.cpp index 9720fecb6d..161104060e 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingTlas.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingTlas.cpp @@ -92,9 +92,7 @@ namespace AZ mappedData[i].instanceCustomIndex = instance.m_instanceID; mappedData[i].instanceShaderBindingTableRecordOffset = instance.m_hitGroupIndex; - // convert transform to row-major 3x4 - AZ::Matrix3x4 matrix34 = AZ::Matrix3x4::CreateFromTransform(instance.m_transform); - matrix34.StoreToRowMajorFloat12(&mappedData[i].transform.matrix[0][0]); + instance.m_matrix3x4.StoreToRowMajorFloat12(&mappedData[i].transform.matrix[0][0]); RayTracingBlas* blas = static_cast(instance.m_blas.get()); VkAccelerationStructureDeviceAddressInfoKHR addressInfo = {}; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Model/Model.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Model/Model.h index 5cd464962b..ada429ee05 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Model/Model.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Model/Model.h @@ -72,11 +72,13 @@ namespace AZ //! [GFX TODO][ATOM-4343 Bake mesh spatial during AP processing] //! //! @param modelTransform a transform that puts the model into the ray's coordinate space + //! @param nonUniformScale Non-uniform scale applied in the model's local frame. //! @param rayStart position where the ray starts //! @param dir direction where the ray ends (does not have to be unit length) //! @param distanceFactor if an intersection is detected, this will be set such that distanceFactor * dir.length == distance to intersection //! @return true if the ray intersects the mesh - bool RayIntersection(const AZ::Transform& modelTransform, const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distanceFactor) const; + bool RayIntersection(const AZ::Transform& modelTransform, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayStart, + const AZ::Vector3& dir, float& distanceFactor) const; //! Get available UV names from the model and its lods. const AZStd::unordered_set& GetUvNames() const; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Model/Model.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Model/Model.cpp index 84c10cb272..ad56b6e33a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Model/Model.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Model/Model.cpp @@ -164,15 +164,15 @@ namespace AZ return false; } - bool Model::RayIntersection(const AZ::Transform& modelTransform, const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distanceFactor) const + bool Model::RayIntersection(const AZ::Transform& modelTransform, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distanceFactor) const { AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender); const AZ::Transform inverseTM = modelTransform.GetInverse(); - const AZ::Vector3 raySrcLocal = inverseTM.TransformPoint(rayStart); + const AZ::Vector3 raySrcLocal = inverseTM.TransformPoint(rayStart) / nonUniformScale; // Instead of just rotating 'dir' we need it to be scaled too, so that 'distanceFactor' will be in the target units rather than object local units. const AZ::Vector3 rayDest = rayStart + dir; - const AZ::Vector3 rayDestLocal = inverseTM.TransformPoint(rayDest); + const AZ::Vector3 rayDestLocal = inverseTM.TransformPoint(rayDest) / nonUniformScale; const AZ::Vector3 rayDirLocal = rayDestLocal - raySrcLocal; return LocalRayIntersection(raySrcLocal, rayDirLocal, distanceFactor); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp index 0afe96588f..86a3c12557 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp @@ -137,7 +137,10 @@ namespace AZ AZ::Transform transform = AZ::Transform::CreateIdentity(); AZ::TransformBus::EventResult(transform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); - return m_controller.GetModel()->RayIntersection(transform, src, dir, distance); + AZ::Vector3 nonUniformScale = AZ::Vector3::CreateOne(); + AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, GetEntityId(), &AZ::NonUniformScaleRequests::GetScale); + + return m_controller.GetModel()->RayIntersection(transform, nonUniformScale, src, dir, distance); } bool EditorMeshComponent::SupportsEditorRayIntersect() diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp index db64d26a54..1404db717f 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp @@ -180,6 +180,11 @@ namespace AZ m_meshFeatureProcessor = RPI::Scene::GetFeatureProcessorForEntity(m_entityId); AZ_Error("MeshComponentController", m_meshFeatureProcessor, "Unable to find a MeshFeatureProcessorInterface on the entityId."); + 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); + MeshComponentRequestBus::Handler::BusConnect(m_entityId); TransformNotificationBus::Handler::BusConnect(m_entityId); MaterialReceiverRequestBus::Handler::BusConnect(m_entityId); @@ -216,11 +221,24 @@ namespace AZ return m_configuration; } - void MeshComponentController::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) + void MeshComponentController::OnTransformChanged([[maybe_unused]] const AZ::Transform& local, [[maybe_unused]] const AZ::Transform& world) + { + UpdateOverallMatrix(); + } + + void MeshComponentController::HandleNonUniformScaleChange(const AZ::Vector3 & nonUniformScale) + { + m_cachedNonUniformScale = nonUniformScale; + UpdateOverallMatrix(); + } + + void MeshComponentController::UpdateOverallMatrix() { if (m_meshFeatureProcessor) { - m_meshFeatureProcessor->SetTransform(m_meshHandle, world); + Matrix3x4 world = Matrix3x4::CreateFromTransform(m_transformInterface->GetWorldTM()); + world.MultiplyByScale(m_cachedNonUniformScale); + m_meshFeatureProcessor->SetMatrix3x4(m_meshHandle, world); } } @@ -266,8 +284,8 @@ namespace AZ m_meshHandle = m_meshFeatureProcessor->AcquireMesh(m_configuration.m_modelAsset, materials); m_meshFeatureProcessor->ConnectModelChangeEventHandler(m_meshHandle, m_changeEventHandler); - const AZ::Transform& transform = m_transformInterface ? m_transformInterface->GetWorldTM() : Transform::Identity(); - m_meshFeatureProcessor->SetTransform(m_meshHandle, transform); + const AZ::Matrix3x4& matrix3x4 = m_transformInterface ? Matrix3x4::CreateFromTransform(m_transformInterface->GetWorldTM()) : Matrix3x4::Identity(); + m_meshFeatureProcessor->SetMatrix3x4(m_meshHandle, matrix3x4); m_meshFeatureProcessor->SetSortKey(m_meshHandle, m_configuration.m_sortKey); m_meshFeatureProcessor->SetLodOverride(m_meshHandle, m_configuration.m_lodOverride); m_meshFeatureProcessor->SetExcludeFromReflectionCubeMaps(m_meshHandle, m_configuration.m_excludeFromReflectionCubeMaps); @@ -403,7 +421,17 @@ namespace AZ Aabb MeshComponentController::GetLocalBounds() { const Data::Instance model = GetModel(); - return model ? model->GetAabb() : Aabb::CreateNull(); + if (model) + { + Aabb aabb = model->GetAabb(); + aabb.SetMin(aabb.GetMin() * m_cachedNonUniformScale); + aabb.SetMax(aabb.GetMax() * m_cachedNonUniformScale); + return aabb; + } + else + { + return Aabb::CreateNull(); + } } } // namespace Render } // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h index 184756d931..68c7ed8063 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.h @@ -14,6 +14,7 @@ #include #include +#include #include @@ -120,17 +121,26 @@ namespace AZ void UnregisterModel(); void RefreshModelRegistration(); + void HandleNonUniformScaleChange(const AZ::Vector3& nonUniformScale); + void UpdateOverallMatrix(); + Render::MeshFeatureProcessorInterface* m_meshFeatureProcessor = nullptr; Render::MeshFeatureProcessorInterface::MeshHandle m_meshHandle; TransformInterface* m_transformInterface = nullptr; AZ::EntityId m_entityId; bool m_isVisible = true; MeshComponentConfig m_configuration; + AZ::Vector3 m_cachedNonUniformScale = AZ::Vector3::CreateOne(); MeshFeatureProcessorInterface::ModelChangedEvent::Handler m_changeEventHandler { [&](Data::Instance model) { HandleModelChange(model); } }; + + AZ::NonUniformScaleChangedEvent::Handler m_nonUniformScaleChangedHandler + { + [&](const AZ::Vector3& nonUniformScale) { HandleNonUniformScaleChange(nonUniformScale); } + }; }; } // namespace Render diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp index 005e9a6ff5..57aaa6a83f 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp @@ -199,7 +199,7 @@ namespace AZ return; } - m_featureProcessor->SetProbeTransform(m_handle, world); + m_featureProcessor->SetProbeMatrix3x4(m_handle, Matrix3x4::CreateFromTransform(world)); } void ReflectionProbeComponentController::OnShapeChanged(ShapeChangeReasons changeReason) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp index b0d52e0776..fd98dfe666 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp @@ -187,8 +187,9 @@ namespace AZ void AtomActorInstance::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) { - // The mesh transform is used to determine where the actor instance is actually rendered - m_meshFeatureProcessor->SetTransform(*m_meshHandle, world); // handle validity is checked internally. + // The mesh Matrix3x4 is used to determine where the actor instance is actually rendered + AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromTransform(world); + m_meshFeatureProcessor->SetMatrix3x4(*m_meshHandle, matrix3x4); // handle validity is checked internally. if (m_skinnedMeshRenderProxy.IsValid()) { diff --git a/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp b/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp index d2aa81900b..5fd9c678dc 100644 --- a/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp +++ b/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp @@ -193,7 +193,7 @@ namespace Blast AZ::Transform transform = AZ::Transform::Identity(); AZ::TransformBus::EventResult(transform, GetEntityId(), &AZ::TransformInterface::GetWorldTM); - m_meshFeatureProcessor->SetTransform(m_meshHandle, transform); + m_meshFeatureProcessor->SetMatrix3x4(m_meshHandle, AZ::Matrix3x4::CreateFromTransform(transform)); } } @@ -232,7 +232,7 @@ namespace Blast { if (m_meshFeatureProcessor) { - m_meshFeatureProcessor->SetTransform(m_meshHandle, world); + m_meshFeatureProcessor->SetMatrix3x4(m_meshHandle, AZ::Matrix3x4::CreateFromTransform(world)); } } } // namespace Blast diff --git a/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp b/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp index deb6362ee3..d057e5a619 100644 --- a/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp +++ b/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp @@ -74,10 +74,10 @@ namespace Blast { if (m_chunkActors[chunkId]) { - auto transform = m_chunkActors[chunkId]->GetWorldBody()->GetTransform(); + auto matrix3x4 = AZ::Matrix3x4::CreateFromTransform(m_chunkActors[chunkId]->GetWorldBody()->GetTransform()); // Multiply by scale because the transform on the world body does not store scale - transform.MultiplyByScale(m_scale); - m_meshFeatureProcessor->SetTransform(m_chunkMeshHandles[chunkId], transform); + matrix3x4.MultiplyByScale(m_scale); + m_meshFeatureProcessor->SetMatrix3x4(m_chunkMeshHandles[chunkId], matrix3x4); } } } diff --git a/Gems/Blast/Code/Tests/ActorRenderManagerTest.cpp b/Gems/Blast/Code/Tests/ActorRenderManagerTest.cpp index 4036023397..0a7cd229a3 100644 --- a/Gems/Blast/Code/Tests/ActorRenderManagerTest.cpp +++ b/Gems/Blast/Code/Tests/ActorRenderManagerTest.cpp @@ -114,7 +114,7 @@ namespace Blast // ActorRenderManager::SyncMeshes { - EXPECT_CALL(*m_mockMeshFeatureProcessor, SetTransform(_, _)) + EXPECT_CALL(*m_mockMeshFeatureProcessor, SetMatrix3x4(_, _)) .Times(aznumeric_cast(m_actorFactory->m_mockActors[0]->GetChunkIndices().size())); actorRenderManager->SyncMeshes(); } diff --git a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp index 9aa29cb288..9c3428ad63 100644 --- a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp +++ b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxAtomRenderMesh.cpp @@ -248,7 +248,7 @@ namespace WhiteBox void AtomRenderMesh::UpdateTransform(const AZ::Transform& worldFromLocal) { - m_meshFeatureProcessor->SetTransform(m_meshHandle, worldFromLocal); + m_meshFeatureProcessor->SetMatrix3x4(m_meshHandle, AZ::Matrix3x4::CreateFromTransform(worldFromLocal)); } void AtomRenderMesh::UpdateMaterial([[maybe_unused]] const WhiteBoxMaterial& material)