Merge pull request #5752 from aws-lumberyard-dev/puvvadar/gitflow_211118_o3de

Merge stabilization/2110
This commit is contained in:
puvvadar
2021-11-19 15:46:16 -08:00
committed by GitHub
387 changed files with 6580 additions and 3688 deletions
@@ -1198,14 +1198,25 @@ namespace AzToolsFramework
AZ::EntityId ToolsApplication::GetCurrentLevelEntityId()
{
AzFramework::EntityContextId editorEntityContextId = AzFramework::EntityContextId::CreateNull();
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &AzToolsFramework::EditorEntityContextRequestBus::Events::GetEditorEntityContextId);
AZ::SliceComponent* rootSliceComponent = nullptr;
AzFramework::SliceEntityOwnershipServiceRequestBus::EventResult(rootSliceComponent, editorEntityContextId,
&AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetRootSlice);
if (rootSliceComponent && rootSliceComponent->GetMetadataEntity())
if (IsPrefabSystemEnabled())
{
return rootSliceComponent->GetMetadataEntity()->GetId();
if (auto prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get())
{
return prefabPublicInterface->GetLevelInstanceContainerEntityId();
}
}
else
{
AzFramework::EntityContextId editorEntityContextId = AzFramework::EntityContextId::CreateNull();
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
editorEntityContextId, &AzToolsFramework::EditorEntityContextRequestBus::Events::GetEditorEntityContextId);
AZ::SliceComponent* rootSliceComponent = nullptr;
AzFramework::SliceEntityOwnershipServiceRequestBus::EventResult(
rootSliceComponent, editorEntityContextId, &AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetRootSlice);
if (rootSliceComponent && rootSliceComponent->GetMetadataEntity())
{
return rootSliceComponent->GetMetadataEntity()->GetId();
}
}
return AZ::EntityId();
@@ -448,7 +448,11 @@ namespace AzToolsFramework
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
componentMode.m_componentMode->GetComponentModeName().c_str());
componentMode.m_componentMode->GetComponentModeName().c_str(),
[]
{
ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequests::EndComponentMode);
});
}
RefreshActions();
@@ -55,8 +55,11 @@ namespace AzToolsFramework
GetEntityComponentIdPair(), elementIdsToDisplay);
// create the component mode border with the specific name for this component mode
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder,
GetComponentModeName());
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, GetComponentModeName(),
[]
{
ComponentModeSystemRequestBus::Broadcast(&ComponentModeSystemRequests::EndComponentMode);
});
// set the EntityComponentId for this ComponentMode to active in the ComponentModeViewportUi system
ComponentModeViewportUiRequestBus::Event(
GetComponentType(), &ComponentModeViewportUiRequestBus::Events::SetViewportUiActiveEntityComponentId,
@@ -98,7 +98,7 @@ namespace AzToolsFramework::Prefab
}
// Retrieve parent of currently focused prefab.
InstanceOptionalReference parentInstance = m_instanceFocusHierarchy[hierarchySize - 2];
InstanceOptionalReference parentInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[hierarchySize - 2]);
// Use container entity of parent Instance for focus operations.
AZ::EntityId entityId = parentInstance->get().GetContainerEntityId();
@@ -132,7 +132,7 @@ namespace AzToolsFramework::Prefab
return AZ::Failure(AZStd::string("Prefab Focus Handler: Invalid index on FocusOnPathIndex."));
}
InstanceOptionalReference focusedInstance = m_instanceFocusHierarchy[index];
InstanceOptionalReference focusedInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[index]);
return FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId());
}
@@ -172,7 +172,8 @@ namespace AzToolsFramework::Prefab
// Close all container entities in the old path.
CloseInstanceContainers(m_instanceFocusHierarchy);
m_focusedInstance = focusedInstance;
// Do not store the container for the root instance, use an invalid EntityId instead.
m_focusedInstanceContainerEntityId = focusedInstance->get().GetParentInstance().has_value() ? focusedInstance->get().GetContainerEntityId() : AZ::EntityId();
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
// Focus on the descendants of the container entity in the Editor, if the interface is initialized.
@@ -206,56 +207,55 @@ namespace AzToolsFramework::Prefab
InstanceOptionalReference PrefabFocusHandler::GetFocusedPrefabInstance(
[[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
return m_focusedInstance;
return GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
}
AZ::EntityId PrefabFocusHandler::GetFocusedPrefabContainerEntityId([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
if (!m_focusedInstance.has_value())
{
// PrefabFocusHandler has not been initialized yet.
return AZ::EntityId();
}
return m_focusedInstance->get().GetContainerEntityId();
return m_focusedInstanceContainerEntityId;
}
bool PrefabFocusHandler::IsOwningPrefabBeingFocused(AZ::EntityId entityId) const
{
if (!m_focusedInstance.has_value())
{
// PrefabFocusHandler has not been initialized yet.
return false;
}
if (!entityId.IsValid())
{
return false;
}
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
if (!instance.has_value())
{
return false;
}
return instance.has_value() && (&instance->get() == &m_focusedInstance->get());
// If this is owned by the root instance, that corresponds to an invalid m_focusedInstanceContainerEntityId.
if (!instance->get().GetParentInstance().has_value())
{
return !m_focusedInstanceContainerEntityId.IsValid();
}
return (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId);
}
bool PrefabFocusHandler::IsOwningPrefabInFocusHierarchy(AZ::EntityId entityId) const
{
if (!m_focusedInstance.has_value())
{
// PrefabFocusHandler has not been initialized yet.
return false;
}
if (!entityId.IsValid())
{
return false;
}
// If the focus is on the root, m_focusedInstanceContainerEntityId will be the invalid id.
// In those case all entities are in the focus hierarchy and should return true.
if (!m_focusedInstanceContainerEntityId.IsValid())
{
return true;
}
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
while (instance.has_value())
{
if (&instance->get() == &m_focusedInstance->get())
if (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId)
{
return true;
}
@@ -290,8 +290,9 @@ namespace AzToolsFramework::Prefab
// Determine if the entityId is the container for any of the instances in the vector.
auto result = AZStd::find_if(
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
[entityId](const InstanceOptionalReference& instance)
[&, entityId](const AZ::EntityId& containerEntityId)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
return (instance->get().GetContainerEntityId() == entityId);
}
);
@@ -316,8 +317,9 @@ namespace AzToolsFramework::Prefab
// Determine if the templateId matches any of the instances in the vector.
auto result = AZStd::find_if(
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
[templateId](const InstanceOptionalReference& instance)
[&, templateId](const AZ::EntityId& containerEntityId)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
return (instance->get().GetTemplateId() == templateId);
}
);
@@ -336,10 +338,17 @@ namespace AzToolsFramework::Prefab
AZStd::list<InstanceOptionalReference> instanceFocusList;
InstanceOptionalReference currentInstance = m_focusedInstance;
InstanceOptionalReference currentInstance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
while (currentInstance.has_value())
{
m_instanceFocusHierarchy.emplace_back(currentInstance);
if (currentInstance->get().GetParentInstance().has_value())
{
m_instanceFocusHierarchy.emplace_back(currentInstance->get().GetContainerEntityId());
}
else
{
m_instanceFocusHierarchy.emplace_back(AZ::EntityId());
}
currentInstance = currentInstance->get().GetParentInstance();
}
@@ -357,42 +366,48 @@ namespace AzToolsFramework::Prefab
size_t index = 0;
size_t maxIndex = m_instanceFocusHierarchy.size() - 1;
for (const InstanceOptionalReference& instance : m_instanceFocusHierarchy)
for (const AZ::EntityId containerEntityId : m_instanceFocusHierarchy)
{
AZStd::string prefabName;
if (index < maxIndex)
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
if (instance.has_value())
{
// Get the filename without the extension (stem).
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
}
else
{
// Get the full filename.
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
}
AZStd::string prefabName;
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
{
prefabName += "*";
}
if (index < maxIndex)
{
// Get the filename without the extension (stem).
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
}
else
{
// Get the full filename.
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
}
m_instanceFocusPath.Append(prefabName);
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
{
prefabName += "*";
}
m_instanceFocusPath.Append(prefabName);
}
++index;
}
}
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
{
// If this is called outside the Editor, this interface won't be initialized.
if (!m_containerEntityInterface)
{
return;
}
for (const InstanceOptionalReference& instance : instances)
for (const AZ::EntityId containerEntityId : instances)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
if (instance.has_value())
{
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), true);
@@ -400,7 +415,7 @@ namespace AzToolsFramework::Prefab
}
}
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
{
// If this is called outside the Editor, this interface won't be initialized.
if (!m_containerEntityInterface)
@@ -408,8 +423,10 @@ namespace AzToolsFramework::Prefab
return;
}
for (const InstanceOptionalReference& instance : instances)
for (const AZ::EntityId containerEntityId : instances)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
if (instance.has_value())
{
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), false);
@@ -417,4 +434,22 @@ namespace AzToolsFramework::Prefab
}
}
InstanceOptionalReference PrefabFocusHandler::GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const
{
if (!containerEntityId.IsValid())
{
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (!prefabEditorEntityOwnershipInterface)
{
return AZStd::nullopt;
}
return prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
}
return m_instanceEntityMapperInterface->FindOwningInstance(containerEntityId);
}
} // namespace AzToolsFramework::Prefab
@@ -73,16 +73,19 @@ namespace AzToolsFramework::Prefab
void RefreshInstanceFocusList();
void RefreshInstanceFocusPath();
void OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
void CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
void OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
void CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
//! The instance the editor is currently focusing on.
InstanceOptionalReference m_focusedInstance;
InstanceOptionalReference GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const;
//! The EntityId of the prefab container entity for the instance the editor is currently focusing on.
AZ::EntityId m_focusedInstanceContainerEntityId = AZ::EntityId();
//! The templateId of the focused instance.
TemplateId m_focusedTemplateId;
//! The list of instances going from the root (index 0) to the focused instance.
AZStd::vector<InstanceOptionalReference> m_instanceFocusHierarchy;
//! A path containing the names of the containers in the instance focus hierarchy, separated with a /.
//! The list of instances going from the root (index 0) to the focused instance,
//! referenced by their prefab container's EntityId.
AZStd::vector<AZ::EntityId> m_instanceFocusHierarchy;
//! A path containing the filenames of the instances in the focus hierarchy, separated with a /.
AZ::IO::Path m_instanceFocusPath;
ContainerEntityInterface* m_containerEntityInterface = nullptr;
@@ -527,8 +527,8 @@ namespace AzToolsFramework
m_errorButton = nullptr;
}
}
void PropertyAssetCtrl::UpdateErrorButton(const AZStd::string& errorLog)
void PropertyAssetCtrl::UpdateErrorButton()
{
if (m_errorButton)
{
@@ -543,12 +543,17 @@ namespace AzToolsFramework
m_errorButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_errorButton->setFixedSize(QSize(16, 16));
m_errorButton->setMouseTracking(true);
m_errorButton->setIcon(QIcon("Icons/PropertyEditor/error_icon.png"));
m_errorButton->setIcon(QIcon(":/PropertyEditor/Resources/error_icon.png"));
m_errorButton->setToolTip("Show Errors");
// Insert the error button after the asset label
qobject_cast<QHBoxLayout*>(layout())->insertWidget(1, m_errorButton);
}
}
void PropertyAssetCtrl::UpdateErrorButtonWithLog(const AZStd::string& errorLog)
{
UpdateErrorButton();
// Connect pressed to opening the error dialog
// Must capture this for call to QObject::connect
@@ -587,6 +592,21 @@ namespace AzToolsFramework
logDialog->show();
});
}
void PropertyAssetCtrl::UpdateErrorButtonWithMessage(const AZStd::string& message)
{
UpdateErrorButton();
connect(m_errorButton, &QPushButton::clicked, this, [this, message]() {
QMessageBox::critical(nullptr, "Error", message.c_str());
// Without this, the error button would maintain focus after clicking, which left the red error icon in a blue-highlighted state
if (parentWidget())
{
parentWidget()->setFocus();
}
});
}
void PropertyAssetCtrl::ClearAssetInternal()
{
@@ -960,7 +980,6 @@ namespace AzToolsFramework
else
{
const AZ::Data::AssetId assetID = GetCurrentAssetID();
m_currentAssetHint = "";
AZ::Outcome<AssetSystem::JobInfoContainer> jobOutcome = AZ::Failure();
AssetSystemJobRequestBus::BroadcastResult(jobOutcome, &AssetSystemJobRequestBus::Events::GetAssetJobsInfoByAssetID, assetID, false, false);
@@ -1018,7 +1037,7 @@ namespace AzToolsFramework
// In case of failure, render failure icon
case AssetSystem::JobStatus::Failed:
{
UpdateErrorButton(errorLog);
UpdateErrorButtonWithLog(errorLog);
}
break;
@@ -1043,6 +1062,10 @@ namespace AzToolsFramework
m_currentAssetHint = assetPath;
}
}
else
{
UpdateErrorButtonWithMessage(AZStd::string::format("Asset is missing.\n\nID: %s\nHint:%s", assetID.ToString<AZStd::string>().c_str(), GetCurrentAssetHint().c_str()));
}
}
// Get the asset file name
@@ -168,7 +168,9 @@ namespace AzToolsFramework
bool IsCorrectMimeData(const QMimeData* pData, AZ::Data::AssetId* pAssetId = nullptr, AZ::Data::AssetType* pAssetType = nullptr) const;
void ClearErrorButton();
void UpdateErrorButton(const AZStd::string& errorLog);
void UpdateErrorButton();
void UpdateErrorButtonWithLog(const AZStd::string& errorLog);
void UpdateErrorButtonWithMessage(const AZStd::string& message);
virtual const AZStd::string GetFolderSelection() const { return AZStd::string(); }
virtual void SetFolderSelection(const AZStd::string& /* folderPath */) {}
virtual void ClearAssetInternal();
@@ -158,7 +158,10 @@ namespace UnitTest
{
// Create & Start a new ToolsApplication if there's no existing one
m_app = CreateTestApplication();
m_app->Start(AzFramework::Application::Descriptor());
AZ::ComponentApplication::StartupParameters startupParameters;
startupParameters.m_loadAssetCatalog = false;
m_app->Start(AzFramework::Application::Descriptor(), startupParameters);
}
// without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
@@ -6,6 +6,7 @@
*
*/
#include <AzFramework/Render/IntersectorInterface.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
namespace AzToolsFramework
@@ -62,4 +63,33 @@ namespace AzToolsFramework
return circleBoundWidth;
}
AZ::Vector3 FindClosestPickIntersection(
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, const float rayLength, 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);
// attempt a ray intersection with any visible mesh and return the intersection position if successful
if (renderGeometryIntersectionResult)
{
return renderGeometryIntersectionResult.m_worldPosition;
}
else
{
return viewportRay.origin + viewportRay.direction * defaultDistance;
}
}
} // namespace AzToolsFramework
@@ -162,12 +162,11 @@ namespace AzToolsFramework
//! Multiply by DeviceScalingFactor to get the position in viewport pixel space.
virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
//! Transforms a point from Qt widget screen space to world space based on the given clip space depth.
//! Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
//! Returns the world space position if successful.
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0;
virtual AZ::Vector3 ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition) = 0;
//! Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
//! Returns a ray containing the ray's origin and a direction normal, if successful.
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
virtual ProjectedViewportRay ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
//! Gets the DPI scaling factor that translates Qt widget space into viewport pixel space.
virtual float DeviceScalingFactor() = 0;
@@ -229,9 +228,6 @@ namespace AzToolsFramework
class MainEditorViewportInteractionRequests
{
public:
//! Given a point in screen space, return the picked entity (if any).
//! Picked EntityId will be returned, InvalidEntityId will be returned on failure.
virtual AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) = 0;
//! 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).
@@ -266,7 +262,6 @@ namespace AzToolsFramework
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
//! Returns the current state of the keyboard modifier keys.
virtual KeyboardModifiers QueryKeyboardModifiers() = 0;
@@ -290,7 +285,6 @@ namespace AzToolsFramework
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
//! Returns the current time in seconds.
//! This interface can be overridden for the purposes of testing to simplify viewport input requests.
@@ -340,6 +334,12 @@ namespace AzToolsFramework
return entityContextId;
}
//! 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.
AZ::Vector3 FindClosestPickIntersection(
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, float rayLength, float defaultDistance);
//! 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(
@@ -148,7 +148,6 @@ namespace AzToolsFramework
return false;
}
EditorHelpers::EditorHelpers(const EditorVisibleEntityDataCache* entityDataCache)
: m_entityDataCache(entityDataCache)
{
@@ -190,7 +189,10 @@ namespace AzToolsFramework
if (helpersVisible)
{
// some components choose to hide their icons (e.g. meshes)
if (!m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex))
// we also do not want to test against icons that may not be showing as they're inside a 'closed' entity container
// (these icons only become visible when it is opened for editing)
if (!m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex) &&
m_entityDataCache->IsVisibleEntityIndividuallySelectableInViewport(entityCacheIndex))
{
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
@@ -235,7 +237,7 @@ namespace AzToolsFramework
viewportId, &ViewportInteraction::ViewportMouseCursorRequestBus::Events::SetOverrideCursor,
ViewportInteraction::CursorStyleOverride::Forbidden);
}
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() &&
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down ||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick)
@@ -18,9 +18,6 @@
namespace AzToolsFramework
{
// default ray length for picking in the viewport
static const float EditorPickRayLength = 1000.0f;
AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot)
{
if (Centered(pivot))
@@ -26,6 +26,9 @@ namespace AzFramework
namespace AzToolsFramework
{
//! Default ray length for picking in the viewport.
inline constexpr float EditorPickRayLength = 1000.0f;
//! Is the pivot at the center of the object (middle of extents) or at the
//! exported authored object root position.
inline bool Centered(const EditorTransformComponentSelectionRequests::Pivot pivot)
@@ -27,6 +27,7 @@
#include <AzToolsFramework/Manipulators/ScaleManipulators.h>
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
#include <AzToolsFramework/Maths/TransformUtils.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/ToolsComponents/EditorLockComponentBus.h>
@@ -409,7 +410,7 @@ namespace AzToolsFramework
const AzFramework::CameraState cameraState = GetCameraState(viewportId);
for (size_t entityCacheIndex = 0; entityCacheIndex < entityDataCache.VisibleEntityDataCount(); ++entityCacheIndex)
{
if (!entityDataCache.IsVisibleEntitySelectableInViewport(entityCacheIndex))
if (!entityDataCache.IsVisibleEntityIndividuallySelectableInViewport(entityCacheIndex))
{
continue;
}
@@ -983,7 +984,7 @@ namespace AzToolsFramework
{
if (auto entityIndex = entityDataCache.GetVisibleEntityIndexFromId(entityId))
{
if (entityDataCache.IsVisibleEntitySelectableInViewport(*entityIndex))
if (entityDataCache.IsVisibleEntityIndividuallySelectableInViewport(*entityIndex))
{
return *entityIndex;
}
@@ -1014,6 +1015,15 @@ namespace AzToolsFramework
ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values);
}
// leaves focus mode by focusing on the parent of the current perfab in the entity outliner
static void LeaveFocusMode()
{
if (auto prefabFocusPublicInterface = AZ::Interface<Prefab::PrefabFocusPublicInterface>::Get())
{
prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(GetEntityContextId());
}
}
EditorTransformComponentSelection::EditorTransformComponentSelection(const EditorVisibleEntityDataCache* entityDataCache)
: m_entityDataCache(entityDataCache)
{
@@ -3674,7 +3684,8 @@ namespace AzToolsFramework
case ViewportEditorMode::Focus:
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode",
LeaveFocusMode);
}
break;
case ViewportEditorMode::Default:
@@ -3703,12 +3714,14 @@ namespace AzToolsFramework
if (editorModeState.IsModeActive(ViewportEditorMode::Focus))
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode");
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::CreateViewportBorder, "Focus Mode",
LeaveFocusMode);
}
}
break;
case ViewportEditorMode::Focus:
{
ViewportUi::ViewportUiRequestBus::Event(
ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::RemoveViewportBorder);
}
@@ -293,12 +293,10 @@ namespace AzToolsFramework
return m_impl->m_visibleEntityDatas[index].m_iconHidden;
}
bool EditorVisibleEntityDataCache::IsVisibleEntitySelectableInViewport(size_t index) const
bool EditorVisibleEntityDataCache::IsVisibleEntityIndividuallySelectableInViewport(const size_t index) const
{
return m_impl->m_visibleEntityDatas[index].m_visible
&& !m_impl->m_visibleEntityDatas[index].m_locked
&& m_impl->m_visibleEntityDatas[index].m_inFocus
&& !m_impl->m_visibleEntityDatas[index].m_descendantOfClosedContainer;
return m_impl->m_visibleEntityDatas[index].m_visible && !m_impl->m_visibleEntityDatas[index].m_locked &&
m_impl->m_visibleEntityDatas[index].m_inFocus && !m_impl->m_visibleEntityDatas[index].m_descendantOfClosedContainer;
}
AZStd::optional<size_t> EditorVisibleEntityDataCache::GetVisibleEntityIndexFromId(const AZ::EntityId entityId) const
@@ -55,7 +55,10 @@ namespace AzToolsFramework
bool IsVisibleEntityVisible(size_t index) const;
bool IsVisibleEntitySelected(size_t index) const;
bool IsVisibleEntityIconHidden(size_t index) const;
bool IsVisibleEntitySelectableInViewport(size_t index) const;
//! Returns true if the entity is individually selectable (none of its ancestors are a closed container entity).
//! @note It may still be desirable to be able to 'click' an entity that is a descendant of a closed container
//! to select the container itself, not the individual entity.
bool IsVisibleEntityIndividuallySelectableInViewport(size_t index) const;
AZStd::optional<size_t> GetVisibleEntityIndexFromId(AZ::EntityId entityId) const;
@@ -62,9 +62,6 @@ namespace AzToolsFramework::ViewportUi::Internal
return;
}
// set hover to true by default
action->setProperty("IconHasHoverEffect", true);
// add the action
addAction(action);
@@ -20,7 +20,9 @@
namespace AzToolsFramework::ViewportUi::Internal
{
const static int HighlightBorderSize = 5;
const static char* HighlightBorderColor = "#4A90E2";
const static char* const HighlightBorderColor = "#4A90E2";
const static int HighlightBorderBackButtonIconSize = 20;
const static char* const HighlightBorderBackButtonIconFile = "X_axis.svg";
static void UnparentWidgets(ViewportUiElementIdInfoLookup& viewportUiElementIdInfoLookup)
{
@@ -62,6 +64,7 @@ namespace AzToolsFramework::ViewportUi::Internal
, m_fullScreenLayout(&m_uiOverlay)
, m_uiOverlayLayout()
, m_viewportBorderText(&m_uiOverlay)
, m_viewportBorderBackButton(&m_uiOverlay)
{
}
@@ -254,7 +257,7 @@ namespace AzToolsFramework::ViewportUi::Internal
auto viewportUiMapElement = m_viewportUiElements.find(elementId);
if (viewportUiMapElement != m_viewportUiElements.end())
{
viewportUiMapElement->second.m_widget->setVisible(false);
viewportUiMapElement->second.m_widget->hide();
viewportUiMapElement->second.m_widget->setParent(nullptr);
m_viewportUiElements.erase(viewportUiMapElement);
}
@@ -269,7 +272,7 @@ namespace AzToolsFramework::ViewportUi::Internal
{
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId); element.m_widget)
{
element.m_widget->setVisible(true);
element.m_widget->show();
}
}
@@ -277,7 +280,7 @@ namespace AzToolsFramework::ViewportUi::Internal
{
if (ViewportUiElementInfo element = GetViewportUiElementInfo(elementId); element.m_widget)
{
element.m_widget->setVisible(false);
element.m_widget->hide();
}
}
@@ -291,27 +294,34 @@ namespace AzToolsFramework::ViewportUi::Internal
return false;
}
void ViewportUiDisplay::CreateViewportBorder(const AZStd::string& borderTitle)
void ViewportUiDisplay::CreateViewportBorder(
const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback)
{
const AZStd::string styleSheet = AZStd::string::format(
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, ViewportUiTopBorderSize,
HighlightBorderColor);
m_uiOverlay.setStyleSheet(styleSheet.c_str());
m_uiOverlay.setStyleSheet(QString("border: %1px solid %2; border-top: %3px solid %4;")
.arg(
QString::number(HighlightBorderSize), HighlightBorderColor,
QString::number(ViewportUiTopBorderSize), HighlightBorderColor));
m_uiOverlayLayout.setContentsMargins(
HighlightBorderSize + ViewportUiOverlayMargin, ViewportUiTopBorderSize + ViewportUiOverlayMargin,
HighlightBorderSize + ViewportUiOverlayMargin, HighlightBorderSize + ViewportUiOverlayMargin);
m_viewportBorderText.setVisible(true);
m_viewportBorderText.show();
m_viewportBorderText.setText(borderTitle.c_str());
UpdateUiOverlayGeometry();
// only display the back button if a callback was provided
m_viewportBorderBackButtonCallback = backButtonCallback;
m_viewportBorderBackButton.setVisible(m_viewportBorderBackButtonCallback.has_value());
}
void ViewportUiDisplay::RemoveViewportBorder()
{
m_viewportBorderText.setVisible(false);
m_viewportBorderText.hide();
m_uiOverlay.setStyleSheet("border: none;");
m_uiOverlayLayout.setContentsMargins(
ViewportUiOverlayMargin, ViewportUiOverlayMargin + ViewportUiOverlayTopMarginPadding, ViewportUiOverlayMargin,
ViewportUiOverlayMargin);
m_viewportBorderBackButtonCallback.reset();
m_viewportBorderBackButton.hide();
}
void ViewportUiDisplay::PositionViewportUiElementFromWorldSpace(ViewportUiElementId elementId, const AZ::Vector3& pos)
@@ -350,23 +360,46 @@ namespace AzToolsFramework::ViewportUi::Internal
{
m_uiMainWindow.setObjectName(QString("ViewportUiWindow"));
ConfigureWindowForViewportUi(&m_uiMainWindow);
m_uiMainWindow.setVisible(false);
m_uiMainWindow.hide();
m_uiOverlay.setObjectName(QString("ViewportUiOverlay"));
m_uiMainWindow.setCentralWidget(&m_uiOverlay);
m_uiOverlay.setVisible(false);
m_uiOverlay.hide();
// remove any spacing and margins from the UI Overlay Layout
m_fullScreenLayout.setSpacing(0);
m_fullScreenLayout.setContentsMargins(0, 0, 0, 0);
m_fullScreenLayout.addLayout(&m_uiOverlayLayout, 0, 0, 1, 1);
// format the label which will appear on top of the highlight border
AZStd::string styleSheet = AZStd::string::format("background-color: %s; border: none;", HighlightBorderColor);
m_viewportBorderText.setStyleSheet(styleSheet.c_str());
// style the label which will appear on top of the highlight border
m_viewportBorderText.setStyleSheet(QString("background-color: %1; border: none").arg(HighlightBorderColor));
m_viewportBorderText.setFixedHeight(ViewportUiTopBorderSize);
m_viewportBorderText.setVisible(false);
m_viewportBorderText.hide();
m_fullScreenLayout.addWidget(&m_viewportBorderText, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
m_viewportBorderBackButton.setAutoRaise(true); // hover highlight
m_viewportBorderBackButton.hide();
QIcon backButtonIcon(QString(":/stylesheet/img/UI20/toolbar/%1").arg(HighlightBorderBackButtonIconFile));
m_viewportBorderBackButton.setIcon(backButtonIcon);
m_viewportBorderBackButton.setIconSize(QSize(HighlightBorderBackButtonIconSize, HighlightBorderBackButtonIconSize));
// setup the handler for the back button to call the user provided callback (if any)
QObject::connect(
&m_viewportBorderBackButton, &QToolButton::clicked,
[this]
{
if (m_viewportBorderBackButtonCallback.has_value())
{
// we need to swap out the existing back button callback because it will be reset in RemoveViewportBorder()
// so preserve the lifetime with this temporary callback until after the call to RemoveViewportBorder()
AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback;
m_viewportBorderBackButtonCallback.swap(backButtonCallback);
RemoveViewportBorder();
(*backButtonCallback)();
}
});
m_fullScreenLayout.addWidget(&m_viewportBorderBackButton, 0, 0, Qt::AlignTop | Qt::AlignRight);
}
void ViewportUiDisplay::PrepareWidgetForViewportUi(QPointer<QWidget> widget)
@@ -414,16 +447,9 @@ namespace AzToolsFramework::ViewportUi::Internal
region += m_uiOverlay.childrenRegion();
// set viewport ui visibility depending on if elements are present
if (region.isEmpty() || !UiDisplayEnabled())
{
m_uiMainWindow.setVisible(false);
m_uiOverlay.setVisible(false);
}
else
{
m_uiMainWindow.setVisible(true);
m_uiOverlay.setVisible(true);
}
const bool visible = !region.isEmpty() && UiDisplayEnabled();
m_uiMainWindow.setVisible(visible);
m_uiOverlay.setVisible(visible);
m_uiMainWindow.setMask(region);
}
@@ -17,6 +17,7 @@
#include <QLabel>
#include <QMainWindow>
#include <QPointer>
#include <QToolButton>
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
#include <QGridLayout>
@@ -89,7 +90,7 @@ namespace AzToolsFramework::ViewportUi::Internal
AZStd::shared_ptr<QWidget> GetViewportUiElement(ViewportUiElementId elementId);
bool IsViewportUiElementVisible(ViewportUiElementId elementId);
void CreateViewportBorder(const AZStd::string& borderTitle);
void CreateViewportBorder(const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback);
void RemoveViewportBorder();
private:
@@ -113,7 +114,10 @@ namespace AzToolsFramework::ViewportUi::Internal
QWidget m_uiOverlay; //!< The UI Overlay which displays Viewport UI Elements.
QGridLayout m_fullScreenLayout; //!< The layout which extends across the full screen.
ViewportUiDisplayLayout m_uiOverlayLayout; //!< The layout used for optionally anchoring Viewport UI Elements.
QLabel m_viewportBorderText; //!< The text used for the viewport border.
QLabel m_viewportBorderText; //!< The text used for the viewport highlight border.
QToolButton m_viewportBorderBackButton; //!< The button to return from the viewport highlight border (only displayed if callback provided).
//! The optional callback for when the viewport highlight border back button is pressed.
AZStd::optional<ViewportUiBackButtonCallback> m_viewportBorderBackButtonCallback;
QWidget* m_renderOverlay;
QPointer<QWidget> m_fullScreenWidget; //!< Reference to the widget attached to m_fullScreenLayout if any.
@@ -240,9 +240,10 @@ namespace AzToolsFramework::ViewportUi
}
}
void ViewportUiManager::CreateViewportBorder(const AZStd::string& borderTitle)
void ViewportUiManager::CreateViewportBorder(
const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback)
{
m_viewportUi->CreateViewportBorder(borderTitle);
m_viewportUi->CreateViewportBorder(borderTitle, backButtonCallback);
}
void ViewportUiManager::RemoveViewportBorder()
@@ -50,7 +50,8 @@ namespace AzToolsFramework::ViewportUi
void RegisterTextFieldCallback(TextFieldId textFieldId, AZ::Event<AZStd::string>::Handler& handler) override;
void RemoveTextField(TextFieldId textFieldId) override;
void SetTextFieldVisible(TextFieldId textFieldId, bool visible) override;
void CreateViewportBorder(const AZStd::string& borderTitle) override;
void CreateViewportBorder(
const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback) override;
void RemoveViewportBorder() override;
void PressButton(ClusterId clusterId, ButtonId buttonId) override;
void PressButton(SwitcherId switcherId, ButtonId buttonId) override;
@@ -22,6 +22,9 @@ namespace AzToolsFramework::ViewportUi
using SwitcherId = IdType<struct SwitcherIdType>;
using TextFieldId = IdType<struct TextFieldIdType>;
//! Callback function for viewport UI back button.
using ViewportUiBackButtonCallback = AZStd::function<void()>;
inline const ViewportUiElementId InvalidViewportUiElementId = ViewportUiElementId(0);
inline const ButtonId InvalidButtonId = ButtonId(0);
inline const ClusterId InvalidClusterId = ClusterId(0);
@@ -95,9 +98,9 @@ namespace AzToolsFramework::ViewportUi
virtual void RemoveTextField(TextFieldId textFieldId) = 0;
//! Sets the visibility of the text field.
virtual void SetTextFieldVisible(TextFieldId textFieldId, bool visible) = 0;
//! Create the highlight border for Component Mode.
virtual void CreateViewportBorder(const AZStd::string& borderTitle) = 0;
//! Remove the highlight border for Component Mode.
//! Create the highlight border with optional back button to exit the given editor mode.
virtual void CreateViewportBorder(const AZStd::string& borderTitle, AZStd::optional<ViewportUiBackButtonCallback> backButtonCallback) = 0;
//! Remove the highlight border.
virtual void RemoveViewportBorder() = 0;
//! Invoke a button press on a cluster.
virtual void PressButton(ClusterId clusterId, ButtonId buttonId) = 0;
@@ -22,8 +22,6 @@ namespace AzToolsFramework::ViewportUi::Internal
// Add am empty active button (is set in the call to SetActiveMode)
m_activeButton = new QToolButton();
// No hover effect for the main button as it's not clickable
m_activeButton->setProperty("IconHasHoverEffect", false);
m_activeButton->setCheckable(false);
m_activeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
addWidget(m_activeButton);
@@ -56,9 +54,6 @@ namespace AzToolsFramework::ViewportUi::Internal
return;
}
// set hover to true by default
action->setProperty("IconHasHoverEffect", true);
// add the action
addAction(action);
@@ -40,6 +40,9 @@ namespace UnitTest
{
AzFramework::BoundsRequestBus::Handler::BusConnect(GetEntityId());
AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusConnect(GetEntityId());
// default local bounds to unit cube
m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-0.5f), AZ::Vector3(0.5f));
}
void BoundsTestComponent::Deactivate()
@@ -57,7 +60,6 @@ namespace UnitTest
AZ::Aabb BoundsTestComponent::GetLocalBounds()
{
return AZ::Aabb::CreateFromMinMax(AZ::Vector3(-0.5f), AZ::Vector3(0.5f));
return m_localBounds;
}
} // namespace UnitTest
@@ -41,5 +41,7 @@ namespace UnitTest
// BoundsRequestBus overrides ...
AZ::Aabb GetWorldBounds() override;
AZ::Aabb GetLocalBounds() override;
AZ::Aabb m_localBounds; //!< Local bounds that can be modified for certain tests (defaults to unit cube).
};
} // namespace UnitTest
@@ -38,7 +38,7 @@
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
#include <AzToolsFramework/ViewportUi/ViewportUiManager.h>
#include<Tests/BoundsTestComponent.h>
#include <Tests/BoundsTestComponent.h>
namespace AZ
{
@@ -493,12 +493,8 @@ namespace UnitTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Then
AzToolsFramework::EntityIdList selectedEntities;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
selectedEntities, &AzToolsFramework::ToolsApplicationRequestBus::Events::GetSelectedEntities);
AzToolsFramework::EntityIdList expectedSelectedEntities = { entity4, entity5, entity6 };
const AzToolsFramework::EntityIdList selectedEntities = SelectedEntities();
const AzToolsFramework::EntityIdList expectedSelectedEntities = { entity4, entity5, entity6 };
EXPECT_THAT(selectedEntities, UnorderedElementsAreArray(expectedSelectedEntities));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
@@ -527,12 +523,8 @@ namespace UnitTest
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Then
AzToolsFramework::EntityIdList selectedEntities;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
selectedEntities, &AzToolsFramework::ToolsApplicationRequestBus::Events::GetSelectedEntities);
AzToolsFramework::EntityIdList expectedSelectedEntities = { m_entityId1, entity2, entity3, entity4 };
const AzToolsFramework::EntityIdList selectedEntities = SelectedEntities();
const AzToolsFramework::EntityIdList expectedSelectedEntities = { m_entityId1, entity2, entity3, entity4 };
EXPECT_THAT(selectedEntities, UnorderedElementsAreArray(expectedSelectedEntities));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
@@ -946,6 +938,42 @@ namespace UnitTest
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1));
}
TEST_F(
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, BoundsBetweenCameraAndNearClipPlaneDoesNotIntersectMouseRay)
{
// move camera to 10 units along the y-axis
AzFramework::SetCameraTransform(m_cameraState, AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(10.0f)));
// send a very narrow bounds for entity1
AZ::Entity* entity1 = AzToolsFramework::GetEntityById(m_entityId1);
auto* boundTestComponent = entity1->FindComponent<BoundsTestComponent>();
boundTestComponent->m_localBounds =
AZ::Aabb::CreateFromMinMax(AZ::Vector3(-0.5f, -0.0025f, -0.5f), AZ::Vector3(0.5f, 0.0025f, 0.5f));
// move entity1 in front of the camera between it and the near clip plane
AZ::TransformBus::Event(
m_entityId1, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(10.05f)));
// move entity2 behind entity1
AZ::TransformBus::Event(
m_entityId2, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(15.0f)));
const auto entity2ScreenPosition = AzFramework::WorldToScreen(AzToolsFramework::GetWorldTranslation(m_entityId2), m_cameraState);
// click the entity in the viewport
m_actionDispatcher->SetStickySelect(true)
->CameraState(m_cameraState)
->MousePosition(entity2ScreenPosition)
->CameraState(m_cameraState)
->MouseLButtonDown()
->MouseLButtonUp();
// ensure entity1 is not selected as it is before the near clip plane
using ::testing::UnorderedElementsAreArray;
const AzToolsFramework::EntityIdList selectedEntities = SelectedEntities();
const AzToolsFramework::EntityIdList expectedSelectedEntities = { m_entityId2 };
EXPECT_THAT(selectedEntities, UnorderedElementsAreArray(expectedSelectedEntities));
}
class EditorTransformComponentSelectionViewportPickingManipulatorTestFixtureParam
: public EditorTransformComponentSelectionViewportPickingManipulatorTestFixture
, public ::testing::WithParamInterface<bool>
@@ -23,6 +23,7 @@
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkTestHelpers.h>
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <Tests/Utils/Printers.h>
using namespace AzToolsFramework;
@@ -106,7 +106,9 @@ namespace UnitTest
inline static const char* Passenger2EntityName = "Passenger2";
};
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_RootContainer)
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
// which is not used by our test environment. This can be restored once Instance handles are implemented.
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootContainer)
{
// Verify FocusOnOwningPrefab works when passing the container entity of the root prefab.
{
@@ -121,7 +123,9 @@ namespace UnitTest
}
}
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_RootEntity)
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
// which is not used by our test environment. This can be restored once Instance handles are implemented.
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootEntity)
{
// Verify FocusOnOwningPrefab works when passing a nested entity of the root prefab.
{
@@ -17,6 +17,7 @@
#include <AzTest/AzTest.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
#include <Tests/Utils/Printers.h>
namespace UnitTest
{
@@ -35,6 +36,7 @@ namespace UnitTest
const auto worldResult = AzFramework::ScreenToWorld(screenPoint, cameraState);
return AzFramework::WorldToScreen(worldResult, cameraState);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// ScreenPoint tests
TEST(ViewportScreen, WorldToScreenAndScreenToWorldReturnsTheSameValueIdentityCameraOffsetFromOrigin)
@@ -102,8 +104,8 @@ namespace UnitTest
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// NDC tests
TEST(ViewportScreen, WorldToScreenNDCAndScreenNDCToWorldReturnsTheSameValueIdentityCameraOffsetFromOrigin)
// Ndc tests
TEST(ViewportScreen, WorldToScreenNdcAndScreenNdcToWorldReturnsTheSameValueIdentityCameraOffsetFromOrigin)
{
using NdcPoint = AZ::Vector2;
@@ -136,7 +138,7 @@ namespace UnitTest
}
}
TEST(ViewportScreen, WorldToScreenNDCAndScreenNDCToWorldReturnsTheSameValueOrientatedCamera)
TEST(ViewportScreen, WorldToScreenNdcAndScreenNdcToWorldReturnsTheSameValueOrientatedCamera)
{
using NdcPoint = AZ::Vector2;
@@ -153,7 +155,7 @@ namespace UnitTest
// note: nearClip is 0.1 - the world space value returned will be aligned to the near clip
// plane of the camera so use that to confirm the mapping to/from is correct
TEST(ViewportScreen, ScreenNDCToWorldReturnsPositionOnNearClipPlaneInWorldSpace)
TEST(ViewportScreen, ScreenNdcToWorldReturnsPositionOnNearClipPlaneInWorldSpace)
{
using NdcPoint = AZ::Vector2;