Add a ray cast API to the terrain system, implement it, and use it so entities can be placed on top of terrain. (#6895)
* Add a ray cast API to the terrain system, implement it, and use it so entities can be placed on top of terrain. Still to do: - Unit tests - Profiling/benchmarks - Optimization (if needed, may not be now after updating to use the iterative approach, but one option could be to use SIMD to ray cast against both triangles at once) Signed-off-by: bosnichd <bosnichd@amazon.com> * Fix typos. Signed-off-by: bosnichd <bosnichd@amazon.com> * Added a FindNearestIntersectionIterative to use in place of the first-pass FindnearestIntersectionRecursive attempt. Signed-off-by: bosnichd <bosnichd@amazon.com> * Remove some functions that are no longer being used. Signed-off-by: bosnichd <bosnichd@amazon.com> * Remove a unicode character from a comment to fix the validation build. Signed-off-by: bosnichd <bosnichd@amazon.com> * Remove another unicode character from a comment to fix the validation build. Signed-off-by: bosnichd <bosnichd@amazon.com> * Update to bail out as soon as t > 1.0f Signed-off-by: bosnichd <bosnichd@amazon.com>
This commit is contained in:
@@ -24,7 +24,7 @@ namespace AzFramework
|
||||
//! IntersectorBus::EventResult(result, editorContextId, &IntersectorInterface::RayIntersect, ray);
|
||||
//!
|
||||
//! Raycast against all entities
|
||||
//! RayResultAggregator rayResult;
|
||||
//! AZ::EBusReduceResult<RayResult, RayResultClosestAggregator> rayResult;
|
||||
//! IntersectorBus::BroadCastResult(rayResult, &IntersectorInterface::RayIntersect, ray);
|
||||
//
|
||||
class IntersectorInterface
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
#include <AzCore/std/containers/span.h>
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
#include <AzFramework/Render/GeometryIntersectionStructures.h>
|
||||
#include <AzFramework/SurfaceData/SurfaceData.h>
|
||||
|
||||
namespace AzFramework
|
||||
@@ -185,6 +187,11 @@ namespace AzFramework
|
||||
SurfacePointRegionFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
|
||||
//! Get the terrain raycast entity context id.
|
||||
virtual EntityContextId GetTerrainRaycastEntityContextId() const = 0;
|
||||
|
||||
//! Given a ray, return the closest intersection with terrain.
|
||||
virtual RenderGeometry::RayResult GetClosestIntersection(const RenderGeometry::RayRequest& ray) const = 0;
|
||||
|
||||
private:
|
||||
// Private variations of the GetSurfacePoint API exposed to BehaviorContext that returns a value instead of
|
||||
|
||||
@@ -102,5 +102,9 @@ namespace UnitTest
|
||||
ProcessSurfaceWeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessSurfacePointsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD0(
|
||||
GetTerrainRaycastEntityContextId, AzFramework::EntityContextId());
|
||||
MOCK_CONST_METHOD1(
|
||||
GetClosestIntersection, AzFramework::RenderGeometry::RayResult(const AzFramework::RenderGeometry::RayRequest&));
|
||||
};
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Render/IntersectorInterface.h>
|
||||
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -66,15 +67,19 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, const float defaultDistance)
|
||||
{
|
||||
AzFramework::RenderGeometry::RayResult renderGeometryIntersectionResult;
|
||||
// attempt a ray intersection with any visible mesh or terrain and return the intersection position if successful
|
||||
AZ::EBusReduceResult<AzFramework::RenderGeometry::RayResult, AzFramework::RenderGeometry::RayResultClosestAggregator> renderGeometryIntersectionResult;
|
||||
AzFramework::RenderGeometry::IntersectorBus::EventResult(
|
||||
renderGeometryIntersectionResult, AzToolsFramework::GetEntityContextId(),
|
||||
&AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, rayRequest);
|
||||
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
||||
renderGeometryIntersectionResult,
|
||||
&AzFramework::Terrain::TerrainDataRequests::GetClosestIntersection,
|
||||
rayRequest);
|
||||
|
||||
// attempt a ray intersection with any visible mesh and return the intersection position if successful
|
||||
if (renderGeometryIntersectionResult)
|
||||
if (renderGeometryIntersectionResult.value)
|
||||
{
|
||||
return renderGeometryIntersectionResult.m_worldPosition;
|
||||
return renderGeometryIntersectionResult.value.m_worldPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user