Update intersect behavior for positioning entities in the viewport (#5906)
* update intersect behavior for positioning entities in the viewport and restore SurfaceManipulator Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * tests for surface manipulator from EditorTransformComponentSelection Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * update comments in tests and remove #pragma optimize('', off)@ Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add new file for FindClosestPickIntersection tests Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add remaining tests for surface manipulator and snap fixes Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * some small updates and polish before PR Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * small updates following PR feedback Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
75d6cb2527
commit
6908a3e945
@@ -64,23 +64,12 @@ namespace AzToolsFramework
|
||||
return circleBoundWidth;
|
||||
}
|
||||
|
||||
AZ::Vector3 FindClosestPickIntersection(
|
||||
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, const float rayLength, const float defaultDistance)
|
||||
AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, const float defaultDistance)
|
||||
{
|
||||
using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus;
|
||||
AzToolsFramework::ViewportInteraction::ProjectedViewportRay viewportRay{};
|
||||
ViewportInteractionRequestBus::EventResult(
|
||||
viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint);
|
||||
|
||||
AzFramework::RenderGeometry::RayRequest ray;
|
||||
ray.m_startWorldPosition = viewportRay.origin;
|
||||
ray.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength;
|
||||
ray.m_onlyVisible = true;
|
||||
|
||||
AzFramework::RenderGeometry::RayResult renderGeometryIntersectionResult;
|
||||
AzFramework::RenderGeometry::IntersectorBus::EventResult(
|
||||
renderGeometryIntersectionResult, AzToolsFramework::GetEntityContextId(),
|
||||
&AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, ray);
|
||||
&AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, rayRequest);
|
||||
|
||||
// attempt a ray intersection with any visible mesh and return the intersection position if successful
|
||||
if (renderGeometryIntersectionResult)
|
||||
@@ -89,7 +78,32 @@ namespace AzToolsFramework
|
||||
}
|
||||
else
|
||||
{
|
||||
return viewportRay.origin + viewportRay.direction * defaultDistance;
|
||||
const AZ::Vector3 rayDirection = (rayRequest.m_endWorldPosition - rayRequest.m_startWorldPosition).GetNormalized();
|
||||
return rayRequest.m_startWorldPosition + rayDirection * defaultDistance;
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshRayRequest(
|
||||
AzFramework::RenderGeometry::RayRequest& rayRequest,
|
||||
const ViewportInteraction::ProjectedViewportRay& viewportRay,
|
||||
const float rayLength)
|
||||
{
|
||||
AZ_Assert(rayLength > 0.0f, "Invalid ray length passed to RefreshRayRequest");
|
||||
rayRequest.m_startWorldPosition = viewportRay.origin;
|
||||
rayRequest.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength;
|
||||
}
|
||||
|
||||
AZ::Vector3 FindClosestPickIntersection(
|
||||
const AzFramework::ViewportId viewportId,
|
||||
const AzFramework::ScreenPoint& screenPoint,
|
||||
const float rayLength,
|
||||
const float defaultDistance)
|
||||
{
|
||||
AzFramework::RenderGeometry::RayRequest ray;
|
||||
ray.m_onlyVisible = true; // only consider visible objects
|
||||
|
||||
RefreshRayRequest(ray, ViewportInteraction::ViewportScreenToWorldRay(viewportId, screenPoint), rayLength);
|
||||
|
||||
return FindClosestPickIntersection(ray, defaultDistance);
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -15,13 +15,19 @@
|
||||
#include <AzFramework/Viewport/CameraState.h>
|
||||
#include <AzFramework/Viewport/ClickDetector.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct ScreenPoint;
|
||||
}
|
||||
|
||||
namespace RenderGeometry
|
||||
{
|
||||
struct RayRequest;
|
||||
}
|
||||
} // namespace AzFramework
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -177,6 +183,26 @@ namespace AzToolsFramework
|
||||
//! Type to inherit to implement ViewportInteractionRequests.
|
||||
using ViewportInteractionRequestBus = AZ::EBus<ViewportInteractionRequests, ViewportEBusTraits>;
|
||||
|
||||
//! Utility function to return a viewport ray.
|
||||
inline ProjectedViewportRay ViewportScreenToWorldRay(
|
||||
const AzFramework::CameraState& cameraState, const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPoint, cameraState);
|
||||
const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized();
|
||||
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection };
|
||||
}
|
||||
|
||||
//! Utility function to return a viewport ray using the ViewportInteractionRequestBus.
|
||||
inline ProjectedViewportRay ViewportScreenToWorldRay(
|
||||
const AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
ProjectedViewportRay viewportRay{};
|
||||
ViewportInteractionRequestBus::EventResult(
|
||||
viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint);
|
||||
|
||||
return viewportRay;
|
||||
}
|
||||
|
||||
//! Interface to return only viewport specific settings (e.g. snapping).
|
||||
class ViewportSettingsRequests
|
||||
{
|
||||
@@ -228,10 +254,6 @@ namespace AzToolsFramework
|
||||
class MainEditorViewportInteractionRequests
|
||||
{
|
||||
public:
|
||||
//! Given a point in screen space, return the terrain position in world space.
|
||||
virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0;
|
||||
//! Return the terrain height given a world position in 2d (xy plane).
|
||||
virtual float TerrainHeight(const AZ::Vector2& position) = 0;
|
||||
//! Is the user holding a modifier key to move the manipulator space from local to world.
|
||||
virtual bool ShowingWorldSpace() = 0;
|
||||
//! Return the widget to use as the parent for the viewport context menu.
|
||||
@@ -337,9 +359,18 @@ namespace AzToolsFramework
|
||||
//! Performs an intersection test against meshes in the scene, if there is a hit (the ray intersects
|
||||
//! a mesh), that position is returned, otherwise a point projected defaultDistance from the
|
||||
//! origin of the ray will be returned.
|
||||
//! @note The intersection will only consider visible objects.
|
||||
AZ::Vector3 FindClosestPickIntersection(
|
||||
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, float rayLength, float defaultDistance);
|
||||
|
||||
//! Overload of FindClosestPickIntersection taking a RenderGeometry::RayRequest directly.
|
||||
//! @note rayRequest must contain a valid ray/line segment (start/endWorldPosition must not be at the same position).
|
||||
AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, float defaultDistance);
|
||||
|
||||
//! Update the in/out parameter rayRequest based on the latest viewport ray.
|
||||
void RefreshRayRequest(
|
||||
AzFramework::RenderGeometry::RayRequest& rayRequest, const ViewportInteraction::ProjectedViewportRay& viewportRay, float rayLength);
|
||||
|
||||
//! Maps a mouse interaction event to a ClickDetector event.
|
||||
//! @note Function only cares about up or down events, all other events are mapped to Nil (ignored).
|
||||
AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction(
|
||||
|
||||
Reference in New Issue
Block a user