Terrain ray cast benchmarks and optimization. (#7303)
* Terrain ray cast benchmarks and optimization: - Added some benchmarks that exercise terrain ray casting. - Optimized terrain ray casting by removing an unnecessary AABB intersection check (this was suggested by @invertednormal in the original review, but I forgot to actually remove it until now). - Fixed a bug where we were not normalizing the ray direction before performing the Moller-Trumbore ray<->triangle intersection calculations. Signed-off-by: bosnichd <bosnichd@amazon.com> * Update to make work with changes pulled down from mainline. Signed-off-by: bosnichd <bosnichd@amazon.com>
This commit is contained in:
@@ -35,7 +35,6 @@ namespace
|
||||
inline void FindNearestIntersection(const AZ::Aabb& aabb,
|
||||
const AZ::Vector3& rayStart,
|
||||
const AZ::Vector3& rayDirection,
|
||||
const AZ::Vector3& rayDirectionReciprocal,
|
||||
AzFramework::RenderGeometry::RayResult& result)
|
||||
{
|
||||
float intersectionT;
|
||||
@@ -43,7 +42,7 @@ namespace
|
||||
AZ::Vector3 intersectionNormal;
|
||||
const int intersectionResult = AZ::Intersect::IntersectRayAABB(rayStart,
|
||||
rayDirection,
|
||||
rayDirectionReciprocal,
|
||||
rayDirection.GetReciprocal(),
|
||||
aabb,
|
||||
intersectionT,
|
||||
intersectionEndT,
|
||||
@@ -117,7 +116,6 @@ namespace
|
||||
const AZ::Aabb& aabb,
|
||||
const AZ::Vector3& rayStart,
|
||||
const AZ::Vector3& rayDirection,
|
||||
const AZ::Vector3& rayDirectionReciprocal,
|
||||
AzFramework::RenderGeometry::RayResult& result)
|
||||
{
|
||||
// Obtain the height values at each corner of the AABB.
|
||||
@@ -132,26 +130,6 @@ namespace
|
||||
point2.SetZ(terrainSystem.GetHeight(point2, AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT));
|
||||
point3.SetZ(terrainSystem.GetHeight(point3, AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT));
|
||||
|
||||
// Construct a smaller AABB that tightly encloses the four terrain points.
|
||||
const float refinedMinZ = AZStd::GetMin(AZStd::GetMin(AZStd::GetMin(point0.GetZ(), point1.GetZ()), point2.GetZ()), point3.GetZ());
|
||||
const float refinedMaxZ = AZStd::GetMax(AZStd::GetMax(AZStd::GetMax(point0.GetZ(), point1.GetZ()), point2.GetZ()), point3.GetZ());
|
||||
const AZ::Vector3 refinedMin(aabbMin.GetX(), aabbMin.GetY(), refinedMinZ);
|
||||
const AZ::Vector3 refinedMax(aabbMax.GetX(), aabbMax.GetY(), refinedMaxZ);
|
||||
const AZ::Aabb refinedAABB = AZ::Aabb::CreateFromMinMax(refinedMin, refinedMax);
|
||||
|
||||
// Check for a hit against the refined AABB.
|
||||
float intersectionT;
|
||||
float intersectionEndT;
|
||||
const int intersectionResult = AZ::Intersect::IntersectRayAABB2(rayStart,
|
||||
rayDirectionReciprocal,
|
||||
refinedAABB,
|
||||
intersectionT,
|
||||
intersectionEndT);
|
||||
if (intersectionResult == AZ::Intersect::ISECT_RAY_AABB_NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, triangulate the four terrain points and check for a hit,
|
||||
// splitting using the top-left -> bottom-right diagonal so to match
|
||||
// the current behavior of the terrain physics and rendering systems.
|
||||
@@ -218,12 +196,10 @@ namespace
|
||||
{
|
||||
// Find the nearest intersection (if any) between the ray and terrain world bounds.
|
||||
// Note that the ray might (and often will) start inside the terrain world bounds.
|
||||
const AZ::Vector3 rayDirection = rayEnd - rayStart;
|
||||
const AZ::Vector3 rayDirectionReciprocal = rayDirection.GetReciprocal();
|
||||
const AZ::Vector3 rayDirection = (rayEnd - rayStart).GetNormalized();
|
||||
FindNearestIntersection(terrainWorldBounds,
|
||||
rayStart,
|
||||
rayDirection,
|
||||
rayDirectionReciprocal,
|
||||
result);
|
||||
if (!result)
|
||||
{
|
||||
@@ -327,7 +303,6 @@ namespace
|
||||
currentVoxel,
|
||||
rayStart,
|
||||
rayDirection,
|
||||
rayDirectionReciprocal,
|
||||
result);
|
||||
if (result)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user