Initial fix for geometry being intersected when not visible (#6473)

* initial fix for geometry being intersected when not visible

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* add tests for shape intersection with helpers enabled/disabled

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* update moved cmake file after merge

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* updates following PR feedback

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>
This commit is contained in:
Tom Hulton-Harrop
2022-01-25 16:56:58 +00:00
committed by GitHub
parent ad8b142230
commit ea55c6d5e5
8 changed files with 213 additions and 61 deletions
@@ -8,13 +8,11 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Component/EntityId.h>
#include <AzCore/EBus/EBus.h>
#include <AzFramework/Render/GeometryIntersectionStructures.h>
#include <AzToolsFramework/ToolsComponents/EditorSelectionAccentSystemComponent.h>
class CEntityObject;
namespace AzFramework
{
struct ViewportInfo;
@@ -22,56 +20,68 @@ namespace AzFramework
namespace AzToolsFramework
{
/// Bus for customizing Entity selection logic from within the EditorComponents.
/// Used to provide with custom implementation for Ray intersection tests, specifying AABB, etc.
class EditorComponentSelectionRequests
: public AZ::ComponentBus
//! Bus for customizing Entity selection logic from within the EditorComponents.
//! Used to provide with custom implementation for Ray intersection tests, specifying AABB, etc.
class EditorComponentSelectionRequests : public AZ::ComponentBus
{
public:
/// @brief Returns an AABB that encompasses the object.
/// @return AABB that encompasses the object.
/// @note ViewportInfo may be necessary if the all or part of the object
/// stays at a constant size regardless of camera position.
virtual AZ::Aabb GetEditorSelectionBoundsViewport(
const AzFramework::ViewportInfo& /*viewportInfo*/)
//! @brief Returns an AABB that encompasses the object.
//! @return AABB that encompasses the object.
//! @note ViewportInfo may be necessary if the all or part of the object
//! stays at a constant size regardless of camera position.
virtual AZ::Aabb GetEditorSelectionBoundsViewport([[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo)
{
AZ_Assert(!SupportsEditorRayIntersect(),
AZ_Assert(
!SupportsEditorRayIntersect(),
"Component claims to support ray intersection but GetEditorSelectionBoundsViewport "
"has not been implemented in the derived class");
return AZ::Aabb::CreateNull();
}
/// @brief Returns true if editor selection ray intersects with the handler.
/// @return True if the editor selection ray intersects the handler.
/// @note ViewportInfo may be necessary if the all or part of the object
/// stays at a constant size regardless of camera position.
//! @brief Returns true if editor selection ray intersects with the handler.
//! @return True if the editor selection ray intersects the handler.
//! @note ViewportInfo may be necessary if the all or part of the object
//! stays at a constant size regardless of camera position.
virtual bool EditorSelectionIntersectRayViewport(
const AzFramework::ViewportInfo& /*viewportInfo*/,
const AZ::Vector3& /*src*/, const AZ::Vector3& /*dir*/, float& /*distance*/)
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
[[maybe_unused]] const AZ::Vector3& src,
[[maybe_unused]] const AZ::Vector3& dir,
[[maybe_unused]] float& distance)
{
AZ_Assert(!SupportsEditorRayIntersect(),
AZ_Assert(
!SupportsEditorRayIntersect(),
"Component claims to support ray intersection but EditorSelectionIntersectRayViewport "
"has not been implemented in the derived class");
return false;
}
/// @brief Returns true if the component overrides EditorSelectionIntersectRay method,
/// otherwise selection will be based only on AABB test.
/// @return True if EditorSelectionIntersectRay method is implemented.
virtual bool SupportsEditorRayIntersect() { return false; }
//! @brief Returns if the component overrides EditorSelectionIntersectRay(Viewport) interface,
//! otherwise selection will be based only on an AABB test.
virtual bool SupportsEditorRayIntersect()
{
return false;
}
//! @brief Returns if the component overrides EditorSelectionIntersectRay(Viewport) interface,
//! otherwise selection will be based only on an AABB test.
//! @note Overload of SupportsEditorRayIntersect which accepts a ViewportInfo containing the ViewportId, this can be used to
//! lookup the intersection setting per viewport.
virtual bool SupportsEditorRayIntersectViewport([[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo)
{
return SupportsEditorRayIntersect();
}
protected:
~EditorComponentSelectionRequests() = default;
};
/// Type to inherit to implement EditorComponentSelectionRequests.
//! Type to inherit to implement EditorComponentSelectionRequests.
using EditorComponentSelectionRequestsBus = AZ::EBus<EditorComponentSelectionRequests>;
/// Bus that provides notifications about selection events of the parent Entity.
class EditorComponentSelectionNotifications
: public AZ::EBusTraits
//! Bus that provides notifications about selection events of the parent Entity.
class EditorComponentSelectionNotifications : public AZ::EBusTraits
{
public:
// EBusTraits overrides
@@ -79,20 +89,21 @@ namespace AzToolsFramework
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
typedef AZ::EntityId BusIdType;
/// @brief Notifies listeners about in-editor selection events (mouse hover, selected, etc.)
virtual void OnAccentTypeChanged(EntityAccentType /*accent*/) {}
//! @brief Notifies listeners about in-editor selection events (mouse hover, selected, etc.)
virtual void OnAccentTypeChanged([[maybe_unused]] EntityAccentType accent)
{
}
protected:
~EditorComponentSelectionNotifications() = default;
};
/// Type to inherit to implement EditorComponentSelectionNotifications.
//! Type to inherit to implement EditorComponentSelectionNotifications.
using EditorComponentSelectionNotificationsBus = AZ::EBus<EditorComponentSelectionNotifications>;
/// Returns the union of all editor selection bounds on a given Entity.
/// @note The returned Aabb is in world space.
inline AZ::Aabb CalculateEditorEntitySelectionBounds(
const AZ::EntityId entityId, const AzFramework::ViewportInfo& viewportInfo)
//! Returns the union of all editor selection bounds on a given Entity.
//! @note The returned Aabb is in world space.
inline AZ::Aabb CalculateEditorEntitySelectionBounds(const AZ::EntityId entityId, const AzFramework::ViewportInfo& viewportInfo)
{
AZ::EBusReduceResult<AZ::Aabb, AzFramework::AabbUnionAggregator> aabbResult(AZ::Aabb::CreateNull());
EditorComponentSelectionRequestsBus::EventResult(
@@ -95,11 +95,12 @@ namespace AzToolsFramework
entityId,
[mouseInteraction, &entityPicked, &closestDistance, viewportId](EditorComponentSelectionRequests* handler) -> bool
{
if (handler->SupportsEditorRayIntersect())
const auto viewportInfo = AzFramework::ViewportInfo{ viewportId };
if (handler->SupportsEditorRayIntersectViewport(viewportInfo))
{
float distance = std::numeric_limits<float>::max();
const bool intersection = handler->EditorSelectionIntersectRayViewport(
{ viewportId }, mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection, distance);
viewportInfo, mouseInteraction.m_mousePick.m_rayOrigin, mouseInteraction.m_mousePick.m_rayDirection, distance);
if (intersection && distance < closestDistance)
{