diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h index 465dae960d..c30116eea0 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h @@ -60,12 +60,14 @@ namespace AZ //! //! @param rayStart The starting point of the ray. //! @param rayDir The direction and length of the ray (magnitude is encoded in the direction). + //! @param allowBruteForce Allow for brute force queries while the mesh is baking (remove when ATOM-4343 is complete) //! @param[out] distanceNormalized If an intersection is found, will be set to the normalized distance of the intersection //! (in the range 0.0-1.0) - to calculate the actual distance, multiply distanceNormalized by the magnitude of rayDir. //! @param[out] normal If an intersection is found, will be set to the normal at the point of collision. //! @return True if the ray intersects the mesh. virtual bool LocalRayIntersectionAgainstModel( - const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, float& distanceNormalized, AZ::Vector3& normal) const; + const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, bool allowBruteForce, + float& distanceNormalized, AZ::Vector3& normal) const; private: void SetReady(); 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 a0743f97d3..7c869c7910 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Model/Model.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Model/Model.cpp @@ -146,7 +146,9 @@ namespace AZ AZ::Debug::Timer timer; timer.Stamp(); #endif - const bool hit = modelAssetPtr->LocalRayIntersectionAgainstModel(rayStart, rayDir, distanceNormalized, normal); + constexpr bool AllowBruteForce = false; + const bool hit = modelAssetPtr->LocalRayIntersectionAgainstModel( + rayStart, rayDir, AllowBruteForce, distanceNormalized, normal); #if defined(AZ_RPI_PROFILE_RAYCASTING_AGAINST_MODELS) if (hit) { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp index 99e97b0300..bf0e4eb584 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp @@ -72,7 +72,8 @@ namespace AZ } bool ModelAsset::LocalRayIntersectionAgainstModel( - const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, float& distanceNormalized, AZ::Vector3& normal) const + const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, bool allowBruteForce, + float& distanceNormalized, AZ::Vector3& normal) const { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender); @@ -90,7 +91,7 @@ namespace AZ BuildKdTree(); AZ_WarningOnce("Model", false, "ray intersection against a model that is still creating spatial information"); - return false; + return allowBruteForce ? BruteForceRayIntersect(rayStart, rayDir, distanceNormalized, normal) : false; } else { diff --git a/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp b/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp index 6329d11a55..7bc9ed5d11 100644 --- a/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp @@ -1214,11 +1214,12 @@ namespace UnitTest float distance = AZStd::numeric_limits::max(); AZ::Vector3 normal; + constexpr bool AllowBruteForce = false; EXPECT_THAT( mesh.GetModel()->LocalRayIntersectionAgainstModel( AZ::Vector3(GetParam().xpos, GetParam().ypos, GetParam().zpos), - AZ::Vector3(GetParam().xdir, GetParam().ydir, GetParam().zdir), distance, normal), + AZ::Vector3(GetParam().xdir, GetParam().ydir, GetParam().zdir), AllowBruteForce, distance, normal), testing::Eq(GetParam().expectedShouldIntersect)); EXPECT_THAT(distance, testing::FloatEq(GetParam().expectedDistance)); } @@ -1262,9 +1263,10 @@ namespace UnitTest // firing down the negative z axis, positioned 5 units from cube (cube is 2x2x2 so intersection // happens at 1 in z) + constexpr bool AllowBruteForce = false; EXPECT_THAT( m_mesh->GetModel()->LocalRayIntersectionAgainstModel( - AZ::Vector3::CreateAxisZ(5.0f), -AZ::Vector3::CreateAxisZ(10.0f), t, normal), + AZ::Vector3::CreateAxisZ(5.0f), -AZ::Vector3::CreateAxisZ(10.0f), AllowBruteForce, t, normal), testing::Eq(true)); EXPECT_THAT(t, testing::FloatEq(0.4f)); } @@ -1275,9 +1277,10 @@ namespace UnitTest AZ::Vector3 normal = AZ::Vector3::CreateOne(); // invalid starting normal // ensure the intersection happens right at the end of the ray + constexpr bool AllowBruteForce = false; EXPECT_THAT( m_mesh->GetModel()->LocalRayIntersectionAgainstModel( - AZ::Vector3::CreateAxisY(10.0f), -AZ::Vector3::CreateAxisY(9.0f), t, normal), + AZ::Vector3::CreateAxisY(10.0f), -AZ::Vector3::CreateAxisY(9.0f), AllowBruteForce, t, normal), testing::Eq(true)); EXPECT_THAT(t, testing::FloatEq(1.0f)); EXPECT_THAT(normal, IsClose(AZ::Vector3::CreateAxisY())); diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataUtility.cpp b/Gems/SurfaceData/Code/Source/SurfaceDataUtility.cpp index 72dee012c2..439bc35071 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataUtility.cpp +++ b/Gems/SurfaceData/Code/Source/SurfaceDataUtility.cpp @@ -28,7 +28,8 @@ namespace SurfaceData AZ::Vector3 normalLocal; - if (meshAsset.LocalRayIntersectionAgainstModel(rayStartLocal, rayDirectionLocal, distance, normalLocal)) + constexpr bool AllowBruteForce = true; + if (meshAsset.LocalRayIntersectionAgainstModel(rayStartLocal, rayDirectionLocal, AllowBruteForce, distance, normalLocal)) { // Transform everything back to world space outPosition = meshTransform.TransformPoint((rayStartLocal + (rayDirectionLocal * distance)) * clampedScale); diff --git a/Gems/Vegetation/Code/Tests/VegetationMocks.h b/Gems/Vegetation/Code/Tests/VegetationMocks.h index 1b95975e67..e2e135a3f3 100644 --- a/Gems/Vegetation/Code/Tests/VegetationMocks.h +++ b/Gems/Vegetation/Code/Tests/VegetationMocks.h @@ -475,7 +475,8 @@ namespace UnitTest ~MockMeshAsset() override = default; bool LocalRayIntersectionAgainstModel( - [[maybe_unused]] const AZ::Vector3& rayStart, [[maybe_unused]] const AZ::Vector3& dir, [[maybe_unused]] float& distance, [[maybe_unused]] AZ::Vector3& normal) const override + [[maybe_unused]] const AZ::Vector3& rayStart, [[maybe_unused]] const AZ::Vector3& dir, [[maybe_unused]] bool allowBruteForce, + [[maybe_unused]] float& distance, [[maybe_unused]] AZ::Vector3& normal) const override { distance = 0.1f; return true;