diff --git a/Code/Editor/Include/IDisplayViewport.h b/Code/Editor/Include/IDisplayViewport.h index 813c54355b..c7dff33e50 100644 --- a/Code/Editor/Include/IDisplayViewport.h +++ b/Code/Editor/Include/IDisplayViewport.h @@ -35,8 +35,6 @@ struct IDisplayViewport */ virtual float GetDistanceToLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& point) const = 0; - virtual CBaseObjectsCache* GetVisibleObjectsCache() = 0; - enum EAxis { AXIS_NONE, diff --git a/Code/Editor/Objects/ObjectManager.cpp b/Code/Editor/Objects/ObjectManager.cpp index 06aa8866b3..f67cf24553 100644 --- a/Code/Editor/Objects/ObjectManager.cpp +++ b/Code/Editor/Objects/ObjectManager.cpp @@ -33,10 +33,6 @@ AZ_CVAR_EXTERNED(bool, ed_visibility_logTiming); -AZ_CVAR( - bool, ed_visibility_use, true, nullptr, AZ::ConsoleFunctorFlags::Null, - "Enable/disable using the new IVisibilitySystem for Entity visibility determination"); - /*! * Class Description used for object templates. * This description filled from Xml template files. @@ -76,17 +72,6 @@ public: int GameCreationOrder() override { return superType->GameCreationOrder(); }; }; -void CBaseObjectsCache::AddObject(CBaseObject* object) -{ - m_objects.push_back(object); - if (object->GetType() == OBJTYPE_AZENTITY) - { - auto componentEntityObject = static_cast(object); - m_entityIds.push_back(componentEntityObject->GetAssociatedEntityId()); - } -} - - ////////////////////////////////////////////////////////////////////////// // CObjectManager implementation. ////////////////////////////////////////////////////////////////////////// @@ -1267,25 +1252,8 @@ void CObjectManager::Display(DisplayContext& dc) UpdateVisibilityList(); } - bool viewIsDirty = dc.settings->IsDisplayHelpers(); // displaying helpers require computing all the bound boxes and things anyway. - - if (!viewIsDirty) + if (dc.settings->IsDisplayHelpers()) { - if (CBaseObjectsCache* cache = dc.view->GetVisibleObjectsCache()) - { - // if the current rendering viewport has an out-of-date cache serial number, it needs to be refreshed too. - // views set their cache empty when they indicate they need to force a refresh. - if ((cache->GetObjectCount() == 0) || (cache->GetSerialNumber() != m_visibilitySerialNumber)) - { - viewIsDirty = true; - } - } - } - - if (viewIsDirty) - { - FindDisplayableObjects(dc, true); // this also actually draws the helpers. - // Also broadcast for anyone else that needs to draw global debug to do so now AzFramework::DebugDisplayEventBus::Broadcast(&AzFramework::DebugDisplayEvents::DrawGlobalDebugInfo); } @@ -1296,94 +1264,14 @@ void CObjectManager::Display(DisplayContext& dc) } } -void CObjectManager::ForceUpdateVisibleObjectCache(DisplayContext& dc) +void CObjectManager::ForceUpdateVisibleObjectCache([[maybe_unused]] DisplayContext& dc) { - FindDisplayableObjects(dc, false); + AZ_Assert(false, "CObjectManager::ForceUpdateVisibleObjectCache is legacy/deprecated and should not be used."); } -void CObjectManager::FindDisplayableObjects(DisplayContext& dc, [[maybe_unused]] bool bDisplay) +void CObjectManager::FindDisplayableObjects([[maybe_unused]] DisplayContext& dc, [[maybe_unused]] bool bDisplay) { - // if the new IVisibilitySystem is being used, do not run this logic - if (ed_visibility_use) - { - return; - } - - AZ_PROFILE_FUNCTION(Editor); - - auto start = std::chrono::steady_clock::now(); - CBaseObjectsCache* pDispayedViewObjects = dc.view->GetVisibleObjectsCache(); - if (!pDispayedViewObjects) - { - return; - } - - pDispayedViewObjects->SetSerialNumber(m_visibilitySerialNumber); // update viewport to be latest serial number - - AABB bbox; - bbox.min.zero(); - bbox.max.zero(); - - pDispayedViewObjects->ClearObjects(); - pDispayedViewObjects->Reserve(static_cast(m_visibleObjects.size())); - - if (dc.flags & DISPLAY_2D) - { - int numVis = static_cast(m_visibleObjects.size()); - for (int i = 0; i < numVis; i++) - { - CBaseObject* obj = m_visibleObjects[i]; - - obj->GetBoundBox(bbox); - if (dc.box.IsIntersectBox(bbox)) - { - pDispayedViewObjects->AddObject(obj); - } - } - } - else - { - CSelectionGroup* pSelection = GetSelection(); - if (pSelection && pSelection->GetCount() > 1) - { - AABB mergedAABB; - mergedAABB.Reset(); - for (int i = 0, iCount(pSelection->GetCount()); i < iCount; ++i) - { - CBaseObject* pObj(pSelection->GetObject(i)); - if (pObj == nullptr) - { - continue; - } - AABB aabb; - pObj->GetBoundBox(aabb); - mergedAABB.Add(aabb); - } - - pSelection->GetObject(0)->CBaseObject::DrawDimensions(dc, &mergedAABB); - } - - int numVis = static_cast(m_visibleObjects.size()); - for (int i = 0; i < numVis; i++) - { - CBaseObject* obj = m_visibleObjects[i]; - - if (obj) - { - if ((dc.flags & DISPLAY_SELECTION_HELPERS) || obj->IsSelected()) - { - pDispayedViewObjects->AddObject(obj); - } - } - } - } - - if (ed_visibility_logTiming && !ed_visibility_use) - { - auto stop = std::chrono::steady_clock::now(); - std::chrono::duration diff = stop - start; - AZ_Printf("Visibility", "FindDisplayableObjects (old) - Duration: %f", diff); - } + AZ_Assert(false, "CObjectManager::FindDisplayableObjects is legacy/deprecated and should not be used."); } void CObjectManager::BeginEditParams(CBaseObject* obj, int flags) @@ -1630,214 +1518,24 @@ bool CObjectManager::HitTestObject(CBaseObject* obj, HitContext& hc) return (bSelectionHelperHit || obj->HitTest(hc)); } - ////////////////////////////////////////////////////////////////////////// -bool CObjectManager::HitTest(HitContext& hitInfo) +bool CObjectManager::HitTest([[maybe_unused]] HitContext& hitInfo) { - AZ_PROFILE_FUNCTION(Editor); - - hitInfo.object = nullptr; - hitInfo.dist = FLT_MAX; - hitInfo.axis = 0; - hitInfo.manipulatorMode = 0; - - HitContext hcOrg = hitInfo; - if (hcOrg.view) - { - hcOrg.view->GetPerpendicularAxis(nullptr, &hcOrg.b2DViewport); - } - hcOrg.rayDir = hcOrg.rayDir.GetNormalized(); - - HitContext hc = hcOrg; - - float mindist = FLT_MAX; - - if (!hitInfo.bIgnoreAxis && !hc.bUseSelectionHelpers) - { - // Test gizmos. - if (m_gizmoManager->HitTest(hc)) - { - if (hc.axis != 0) - { - hitInfo.object = hc.object; - hitInfo.gizmo = hc.gizmo; - hitInfo.axis = hc.axis; - hitInfo.manipulatorMode = hc.manipulatorMode; - hitInfo.dist = hc.dist; - return true; - } - } - } - - if (hitInfo.bOnlyGizmo) - { - return false; - } - - // Only HitTest objects, that where previously Displayed. - CBaseObjectsCache* pDispayedViewObjects = hitInfo.view->GetVisibleObjectsCache(); - - const bool iconsPrioritized = true; // Force icons to always be prioritized over other things you hit. Can change to be a configurable option in the future. - - CBaseObject* selected = nullptr; - const char* name = nullptr; - bool iconHit = false; - int numVis = pDispayedViewObjects->GetObjectCount(); - for (int i = 0; i < numVis; i++) - { - CBaseObject* obj = pDispayedViewObjects->GetObject(i); - - if (obj == hitInfo.pExcludedObject) - { - continue; - } - - if (HitTestObject(obj, hc)) - { - if (m_selectCallback && !m_selectCallback->CanSelectObject(obj)) - { - continue; - } - - // Check if this object is nearest. - if (hc.axis != 0) - { - hitInfo.object = obj; - hitInfo.axis = hc.axis; - hitInfo.dist = hc.dist; - return true; - } - - // When prioritizing icons, we don't allow non-icon hits to beat icon hits - if (iconsPrioritized && iconHit && !hc.iconHit) - { - continue; - } - - if (hc.dist < mindist || (!iconHit && hc.iconHit)) - { - if (hc.iconHit) - { - iconHit = true; - } - - mindist = hc.dist; - name = hc.name; - selected = obj; - } - - // Clear the object pointer if an object was hit, not just if the collision - // was closer than any previous. Not all paths from HitTestObject set the object pointer and so you could get - // an object from a previous (rejected) result but with collision information about a closer hit. - hc.object = nullptr; - hc.iconHit = false; - - // If use deep selection - if (hitInfo.pDeepSelection) - { - hitInfo.pDeepSelection->AddObject(hc.dist, obj); - } - } - } - - if (selected) - { - hitInfo.object = selected; - hitInfo.dist = mindist; - hitInfo.name = name; - hitInfo.iconHit = iconHit; - return true; - } + AZ_Assert(false, "CObjectManager::HitTest is legacy/deprecated and should not be used."); return false; } -void CObjectManager::FindObjectsInRect(CViewport* view, const QRect& rect, std::vector& guids) + +void CObjectManager::FindObjectsInRect( + [[maybe_unused]] CViewport* view, [[maybe_unused]] const QRect& rect, [[maybe_unused]] std::vector& guids) { - AZ_PROFILE_FUNCTION(Editor); - - if (rect.width() < 1 || rect.height() < 1) - { - return; - } - - HitContext hc; - hc.view = view; - hc.b2DViewport = view->GetType() != ET_ViewportCamera; - hc.rect = rect; - hc.bUseSelectionHelpers = view->GetAdvancedSelectModeFlag(); - - guids.clear(); - - CBaseObjectsCache* pDispayedViewObjects = view->GetVisibleObjectsCache(); - - int numVis = pDispayedViewObjects->GetObjectCount(); - for (int i = 0; i < numVis; ++i) - { - CBaseObject* pObj = pDispayedViewObjects->GetObject(i); - - HitTestObjectAgainstRect(pObj, view, hc, guids); - } + AZ_Assert(false, "CObjectManager::FindObjectsInRect is legacy/deprecated and should not be used."); } ////////////////////////////////////////////////////////////////////////// -void CObjectManager::SelectObjectsInRect(CViewport* view, const QRect& rect, bool bSelect) +void CObjectManager::SelectObjectsInRect( + [[maybe_unused]] CViewport* view, [[maybe_unused]] const QRect& rect, [[maybe_unused]] bool bSelect) { - AZ_PROFILE_FUNCTION(Editor); - - // Ignore too small rectangles. - if (rect.width() < 1 || rect.height() < 1) - { - return; - } - - CUndo undo("Select Object(s)"); - - HitContext hc; - hc.view = view; - hc.b2DViewport = view->GetType() != ET_ViewportCamera; - hc.rect = rect; - hc.bUseSelectionHelpers = view->GetAdvancedSelectModeFlag(); - - bool isUndoRecording = GetIEditor()->IsUndoRecording(); - if (isUndoRecording) - { - m_processingBulkSelect = true; - } - - CBaseObjectsCache* displayedViewObjects = view->GetVisibleObjectsCache(); - int numVis = displayedViewObjects->GetObjectCount(); - - // Tracking the previous selection allows proper undo/redo functionality of additional - // selections (CTRL + drag select) - AZStd::unordered_set previousSelection; - - for (int i = 0; i < numVis; ++i) - { - CBaseObject* object = displayedViewObjects->GetObject(i); - - if (object->IsSelected()) - { - previousSelection.insert(object); - } - else - { - // This will update m_currSelection - SelectObjectInRect(object, view, hc, bSelect); - - // Legacy undo/redo does not go through the Ebus system and must be done individually - if (isUndoRecording && object->GetType() != OBJTYPE_AZENTITY) - { - GetIEditor()->RecordUndo(new CUndoBaseObjectSelect(object, true)); - } - } - } - - if (isUndoRecording && m_currSelection) - { - // Component Entities can handle undo/redo in bulk due to Ebuses - GetIEditor()->RecordUndo(new CUndoBaseObjectBulkSelect(previousSelection, *m_currSelection)); - } - - m_processingBulkSelect = false; + AZ_Assert(false, "CObjectManager::SelectObjectsInRect is legacy/deprecated and should not be used."); } ////////////////////////////////////////////////////////////////////////// @@ -3011,6 +2709,4 @@ namespace AzToolsFramework } } -} - - +} // namespace AzToolsFramework diff --git a/Code/Editor/Objects/ObjectManager.h b/Code/Editor/Objects/ObjectManager.h index 4ffa5e9a07..0ad5d8323e 100644 --- a/Code/Editor/Objects/ObjectManager.h +++ b/Code/Editor/Objects/ObjectManager.h @@ -52,40 +52,6 @@ public: } }; -////////////////////////////////////////////////////////////////////////// -// Array of editor objects. -////////////////////////////////////////////////////////////////////////// -class CBaseObjectsCache -{ -public: - int GetObjectCount() const { return static_cast(m_objects.size()); } - CBaseObject* GetObject(int nIndex) const { return m_objects[nIndex]; } - void AddObject(CBaseObject* object); - - void ClearObjects() - { - m_objects.clear(); - m_entityIds.clear(); - } - - void Reserve(int nCount) - { - m_objects.reserve(nCount); - m_entityIds.reserve(nCount); - } - - const AZStd::vector& GetEntityIdCache() const { return m_entityIds; } - - /// Checksum is used as a dirty flag. - unsigned int GetSerialNumber() { return m_serialNumber; } - void SetSerialNumber(unsigned int serialNumber) { m_serialNumber = serialNumber; } -private: - //! List of objects that was displayed at last frame. - std::vector<_smart_ptr > m_objects; - AZStd::vector m_entityIds; - unsigned int m_serialNumber = 0; -}; - /*! * CObjectManager is a singleton object that * manages global set of objects in level. diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp index 2d41538d92..5b4f4a4df3 100644 --- a/Code/Editor/Viewport.cpp +++ b/Code/Editor/Viewport.cpp @@ -173,8 +173,6 @@ QtViewport::QtViewport(QWidget* parent) m_bAdvancedSelectMode = false; - m_pVisibleObjectsCache = new CBaseObjectsCache; - m_constructionPlane.SetPlane(Vec3_OneZ, Vec3_Zero); m_constructionPlaneAxisX = Vec3_Zero; m_constructionPlaneAxisY = Vec3_Zero; @@ -204,8 +202,6 @@ QtViewport::QtViewport(QWidget* parent) ////////////////////////////////////////////////////////////////////////// QtViewport::~QtViewport() { - delete m_pVisibleObjectsCache; - GetIEditor()->GetViewManager()->UnregisterViewport(this); } @@ -376,11 +372,6 @@ void QtViewport::OnDeactivate() void QtViewport::ResetContent() { m_pMouseOverObject = nullptr; - - // Need to clear visual object cache. - // Right after loading new level, some code(e.g. OnMouseMove) access invalid - // previous level object before cache updated. - GetVisibleObjectsCache()->ClearObjects(); } ////////////////////////////////////////////////////////////////////////// @@ -398,11 +389,8 @@ void QtViewport::Update() m_viewportUi.Update(); m_bAdvancedSelectMode = false; - bool bSpaceClick = false; - { - bSpaceClick = CheckVirtualKey(Qt::Key_Space) & !CheckVirtualKey(Qt::Key_Shift) /*& !CheckVirtualKey(Qt::Key_Control)*/; - } - if (bSpaceClick && hasFocus()) + + if (CheckVirtualKey(Qt::Key_Space) && !CheckVirtualKey(Qt::Key_Shift) && hasFocus()) { m_bAdvancedSelectMode = true; } diff --git a/Code/Editor/Viewport.h b/Code/Editor/Viewport.h index 60c1306420..fdb8332479 100644 --- a/Code/Editor/Viewport.h +++ b/Code/Editor/Viewport.h @@ -491,10 +491,6 @@ public: void ResetCursor() override; void SetSupplementaryCursorStr(const QString& str) override; - ////////////////////////////////////////////////////////////////////////// - // Return visble objects cache. - CBaseObjectsCache* GetVisibleObjectsCache() override { return m_pVisibleObjectsCache; }; - void RegisterRenderListener(IRenderListener* piListener) override; bool UnregisterRenderListener(IRenderListener* piListener) override; bool IsRenderListenerRegistered(IRenderListener* piListener) override; @@ -612,8 +608,6 @@ protected: int m_nLastUpdateFrame; int m_nLastMouseMoveFrame; - CBaseObjectsCache* m_pVisibleObjectsCache; - QRect m_rcClient; AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerInterface.h index bcc8afbe6a..9da8d97990 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerInterface.h @@ -22,22 +22,22 @@ namespace AzToolsFramework virtual ~ViewportEditorModeTrackerInterface() = default; - //! Activates the specified editor mode for the specified viewport. + //! Activates the specified editor mode for the specified viewport editor mode tracker. virtual AZ::Outcome ActivateMode( - const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) = 0; + const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo, ViewportEditorMode mode) = 0; - //! Deactivates the specified editor mode for the specified viewport. + //! Deactivates the specified editor mode for the specified viewport editor mode tracker. virtual AZ::Outcome DeactivateMode( - const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) = 0; + const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo, ViewportEditorMode mode) = 0; - //! Attempts to retrieve the editor mode state for the specified viewport, otherwise returns nullptr. - virtual const ViewportEditorModesInterface* GetViewportEditorModes(const ViewportEditorModeInfo& viewportEditorModeInfo) const = 0; + //! Attempts to retrieve the editor mode state for the specified viewport editor mode tracker, otherwise returns nullptr. + virtual const ViewportEditorModesInterface* GetViewportEditorModes(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo) const = 0; - //! Returns the number of viewports currently being tracked. + //! Returns the number of viewport editor mode trackers. virtual size_t GetTrackedViewportCount() const = 0; - //! Returns true if the specified viewport is being tracked, otherwise false. - virtual bool IsViewportModeTracked(const ViewportEditorModeInfo& viewportEditorModeInfo) const = 0; + //! Returns true if viewport editor modes are being tracked for the specified od, otherwise false. + virtual bool IsViewportModeTracked(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo) const = 0; }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h index 42a1cb0113..4fcb891e61 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h @@ -9,7 +9,7 @@ #pragma once #include -#include +#include #include namespace AzToolsFramework @@ -23,11 +23,11 @@ namespace AzToolsFramework Pick }; - //! Viewport identifier and other relevant viewport data. - struct ViewportEditorModeInfo + //! Viewport editor mode tracker identifier and other relevant data. + struct ViewportEditorModeTrackerInfo { - using IdType = AzFramework::ViewportId; - IdType m_id = ViewportUi::DefaultViewportId; //!< The unique identifier for a given viewport. + using IdType = AzFramework::EntityContextId; + IdType m_id = AzFramework::EntityContextId::CreateNull(); //!< The unique identifier for a given viewport editor mode tracker. }; //! Interface for the editor modes of a given viewport. @@ -49,7 +49,7 @@ namespace AzToolsFramework // EBusTraits overrides static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - using BusIdType = ViewportEditorModeInfo::IdType; + using BusIdType = ViewportEditorModeTrackerInfo::IdType; ////////////////////////////////////////////////////////////////////////// //! Notifies subscribers of the a given viewport to the activation of the specified editor mode. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp index 4d849466ee..df93e924b8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ComponentMode/ComponentModeCollection.cpp @@ -218,7 +218,7 @@ namespace AzToolsFramework // this call to activate the component mode editor state should eventually replace the bus call in // ComponentModeCollection::BeginComponentMode() to EditorComponentModeNotifications::EnteredComponentMode // such that all of the notifications for activating/deactivating the different editor modes are in a central location - m_viewportEditorModeTracker->ActivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Component); + m_viewportEditorModeTracker->ActivateMode({ GetEntityContextId() }, ViewportEditorMode::Component); // enable actions for the first/primary ComponentMode // note: if multiple ComponentModes are activated at the same time, actions @@ -296,7 +296,7 @@ namespace AzToolsFramework // this call to deactivate the component mode editor state should eventually replace the bus call in // ComponentModeCollection::EndComponentMode() to EditorComponentModeNotifications::LeftComponentMode // such that all of the notifications for activating/deactivating the different editor modes are in a central location - m_viewportEditorModeTracker->DeactivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Component); + m_viewportEditorModeTracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Component); // clear stored modes and builders for this ComponentMode // TLDR: avoid 'use after free' error diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeSystemComponent.cpp index ceb516d86f..af518afd66 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeSystemComponent.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace AzToolsFramework { @@ -79,11 +79,11 @@ namespace AzToolsFramework { if (!m_focusRoot.IsValid() && entityId.IsValid()) { - tracker->ActivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Focus); + tracker->ActivateMode({ GetEntityContextId() }, ViewportEditorMode::Focus); } else if (m_focusRoot.IsValid() && !entityId.IsValid()) { - tracker->DeactivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Focus); + tracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Focus); } } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp index 30958cfbc1..1ad0ee8ff3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.cpp @@ -32,14 +32,14 @@ namespace AzToolsFramework m_manipulatorManager = AZStd::make_shared(AzToolsFramework::g_mainManipulatorManagerId); m_transformComponentSelection = AZStd::make_unique(entityDataCache); - m_viewportEditorModeTracker->ActivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Default); + m_viewportEditorModeTracker->ActivateMode({ GetEntityContextId() }, ViewportEditorMode::Default); } EditorDefaultSelection::~EditorDefaultSelection() { ComponentModeFramework::ComponentModeSystemRequestBus::Handler::BusDisconnect(); ActionOverrideRequestBus::Handler::BusDisconnect(); - m_viewportEditorModeTracker->DeactivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Default); + m_viewportEditorModeTracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Default); } void EditorDefaultSelection::SetOverridePhantomWidget(QWidget* phantomOverrideWidget) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp index 18eda140a0..6e7777b31c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorPickEntitySelection.cpp @@ -21,7 +21,7 @@ namespace AzToolsFramework : m_editorHelpers(AZStd::make_unique(entityDataCache)) , m_viewportEditorModeTracker(viewportEditorModeTracker) { - m_viewportEditorModeTracker->ActivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Pick); + m_viewportEditorModeTracker->ActivateMode({ GetEntityContextId() }, ViewportEditorMode::Pick); } EditorPickEntitySelection::~EditorPickEntitySelection() @@ -31,7 +31,7 @@ namespace AzToolsFramework ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetEntityHighlighted, m_hoveredEntityId, false); } - m_viewportEditorModeTracker->DeactivateMode({ /* DefaultViewportId */ }, ViewportEditorMode::Pick); + m_viewportEditorModeTracker->DeactivateMode({ GetEntityContextId() }, ViewportEditorMode::Pick); } // note: entityIdUnderCursor is the authoritative entityId we get each frame by querying diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.cpp index 105712c789..d3cfa47e51 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.cpp @@ -46,13 +46,14 @@ namespace AzToolsFramework } AZ::Outcome ViewportEditorModeTracker::ActivateMode( - const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) + const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo, ViewportEditorMode mode) { - auto& editorModes = m_viewportEditorModesMap[viewportEditorModeInfo.m_id]; + auto& editorModes = m_viewportEditorModesMap[ViewportEditorModeTrackerInfo.m_id]; if (editorModes.IsModeActive(mode)) { return AZ::Failure(AZStd::string::format( - "Duplicate call to ActivateMode for mode '%u' on id '%i'", static_cast(mode), viewportEditorModeInfo.m_id)); + "Duplicate call to ActivateMode for mode '%u' on id '%s'", static_cast(mode), + ViewportEditorModeTrackerInfo.m_id.ToString().c_str())); } if (const auto result = editorModes.ActivateMode(mode); @@ -62,29 +63,30 @@ namespace AzToolsFramework } ViewportEditorModeNotificationsBus::Event( - viewportEditorModeInfo.m_id, &ViewportEditorModeNotificationsBus::Events::OnEditorModeActivated, editorModes, mode); + ViewportEditorModeTrackerInfo.m_id, &ViewportEditorModeNotificationsBus::Events::OnEditorModeActivated, editorModes, mode); return AZ::Success(); } AZ::Outcome ViewportEditorModeTracker::DeactivateMode( - const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) + const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo, ViewportEditorMode mode) { ViewportEditorModes* editorModes = nullptr; bool modeWasActive = true; - if (m_viewportEditorModesMap.count(viewportEditorModeInfo.m_id)) + if (m_viewportEditorModesMap.count(ViewportEditorModeTrackerInfo.m_id)) { - editorModes = &m_viewportEditorModesMap.at(viewportEditorModeInfo.m_id); + editorModes = &m_viewportEditorModesMap.at(ViewportEditorModeTrackerInfo.m_id); if (!editorModes->IsModeActive(mode)) { return AZ::Failure(AZStd::string::format( - "Duplicate call to DeactivateMode for mode '%u' on id '%i'", static_cast(mode), viewportEditorModeInfo.m_id)); + "Duplicate call to DeactivateMode for mode '%u' on id '%s'", static_cast(mode), + ViewportEditorModeTrackerInfo.m_id.ToString().c_str())); } } else { modeWasActive = false; - editorModes = &m_viewportEditorModesMap[viewportEditorModeInfo.m_id]; + editorModes = &m_viewportEditorModesMap[ViewportEditorModeTrackerInfo.m_id]; } if(const auto result = editorModes->DeactivateMode(mode); @@ -94,7 +96,7 @@ namespace AzToolsFramework } ViewportEditorModeNotificationsBus::Event( - viewportEditorModeInfo.m_id, &ViewportEditorModeNotificationsBus::Events::OnEditorModeDeactivated, *editorModes, mode); + ViewportEditorModeTrackerInfo.m_id, &ViewportEditorModeNotificationsBus::Events::OnEditorModeDeactivated, *editorModes, mode); if (modeWasActive) { @@ -103,14 +105,14 @@ namespace AzToolsFramework else { return AZ::Failure(AZStd::string::format( - "Call to DeactivateMode for mode '%u' on id '%i' without precursor call to ActivateMode", static_cast(mode), - viewportEditorModeInfo.m_id)); + "Call to DeactivateMode for mode '%u' on id '%s' without precursor call to ActivateMode", static_cast(mode), + ViewportEditorModeTrackerInfo.m_id.ToString().c_str())); } } - const ViewportEditorModesInterface* ViewportEditorModeTracker::GetViewportEditorModes(const ViewportEditorModeInfo& viewportEditorModeInfo) const + const ViewportEditorModesInterface* ViewportEditorModeTracker::GetViewportEditorModes(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo) const { - if (auto editorModes = m_viewportEditorModesMap.find(viewportEditorModeInfo.m_id); + if (auto editorModes = m_viewportEditorModesMap.find(ViewportEditorModeTrackerInfo.m_id); editorModes != m_viewportEditorModesMap.end()) { return &editorModes->second; @@ -126,8 +128,8 @@ namespace AzToolsFramework return m_viewportEditorModesMap.size(); } - bool ViewportEditorModeTracker::IsViewportModeTracked(const ViewportEditorModeInfo& viewportEditorModeInfo) const + bool ViewportEditorModeTracker::IsViewportModeTracked(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo) const { - return m_viewportEditorModesMap.count(viewportEditorModeInfo.m_id) > 0; + return m_viewportEditorModesMap.count(ViewportEditorModeTrackerInfo.m_id) > 0; } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.h index 5b382c44e7..2efc0a66f7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.h @@ -42,14 +42,14 @@ namespace AzToolsFramework { public: // ViewportEditorModeTrackerInterface overrides ... - AZ::Outcome ActivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override; - AZ::Outcome DeactivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override; - const ViewportEditorModesInterface* GetViewportEditorModes(const ViewportEditorModeInfo& viewportEditorModeInfo) const override; + AZ::Outcome ActivateMode(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo, ViewportEditorMode mode) override; + AZ::Outcome DeactivateMode(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo, ViewportEditorMode mode) override; + const ViewportEditorModesInterface* GetViewportEditorModes(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo) const override; size_t GetTrackedViewportCount() const override; - bool IsViewportModeTracked(const ViewportEditorModeInfo& viewportEditorModeInfo) const override; + bool IsViewportModeTracked(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo) const override; private: - using ViewportEditorModesMap = AZStd::unordered_map; - ViewportEditorModesMap m_viewportEditorModesMap; //!< Editor mode state per viewport. + using ViewportEditorModesMap = AZStd::unordered_map; + ViewportEditorModesMap m_viewportEditorModesMap; //!< Editor mode states per tracker. }; } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportEditorModeTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportEditorModeTests.cpp index 866d88b7ba..db6a0b8571 100644 --- a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportEditorModeTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportEditorModeTests.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -17,8 +18,8 @@ namespace UnitTest using ViewportEditorMode = AzToolsFramework::ViewportEditorMode; using ViewportEditorModes = AzToolsFramework::ViewportEditorModes; using ViewportEditorModeTracker = AzToolsFramework::ViewportEditorModeTracker; - using ViewportEditorModeInfo = AzToolsFramework::ViewportEditorModeInfo; - using ViewportId = ViewportEditorModeInfo::IdType; + using ViewportEditorModeTrackerInfo = AzToolsFramework::ViewportEditorModeTrackerInfo; + using TrackerId = ViewportEditorModeTrackerInfo::IdType; using ViewportEditorModesInterface = AzToolsFramework::ViewportEditorModesInterface; using ViewportEditorModeTrackerInterface = AzToolsFramework::ViewportEditorModeTrackerInterface; @@ -113,10 +114,10 @@ namespace UnitTest using EditModeTracker = AZStd::unordered_map; - ViewportEditorModeNotificationsBusHandler(ViewportId viewportId) - : m_viewportSubscription(viewportId) + ViewportEditorModeNotificationsBusHandler(TrackerId id) + : m_trackerSubscription(id) { - AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusConnect(m_viewportSubscription); + AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusConnect(m_trackerSubscription); } ~ViewportEditorModeNotificationsBusHandler() @@ -124,11 +125,6 @@ namespace UnitTest AzToolsFramework::ViewportEditorModeNotificationsBus::Handler::BusDisconnect(); } - ViewportId GetViewportSubscription() const - { - return m_viewportSubscription; - } - const EditModeTracker& GetEditorModes() const { return m_editorModes; @@ -145,7 +141,7 @@ namespace UnitTest } private: - ViewportId m_viewportSubscription; + TrackerId m_trackerSubscription; EditModeTracker m_editorModes; }; @@ -158,10 +154,14 @@ namespace UnitTest void SetUpEditorFixtureImpl() override { + m_handlerIds.resize(ViewportEditorModes::NumEditorModes); for (auto mode = 0; mode < ViewportEditorModes::NumEditorModes; mode++) { - m_editorModeHandlers[mode] = AZStd::make_unique(mode); + // Create a random GUID for each handler and associate that GUID with an index derived from one of the possible editor modes + m_handlerIds[mode] = TrackerId::CreateRandom(); + m_editorModeHandlers[mode] = AZStd::make_unique(m_handlerIds[mode]); } + } void TearDownEditorFixtureImpl() override @@ -173,6 +173,7 @@ namespace UnitTest } AZStd::array, ViewportEditorModes::NumEditorModes> m_editorModeHandlers; + AZStd::vector m_handlerIds; }; // Fixture for testing the integration of viewport editor mode state tracker @@ -184,7 +185,8 @@ namespace UnitTest { m_viewportEditorModeTracker = AZ::Interface::Get(); ASSERT_NE(m_viewportEditorModeTracker, nullptr); - m_viewportEditorModes = m_viewportEditorModeTracker->GetViewportEditorModes({}); + m_viewportEditorModes = m_viewportEditorModeTracker->GetViewportEditorModes({AzToolsFramework::GetEntityContextId()}); + ASSERT_NE(m_viewportEditorModes, nullptr); } ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr; @@ -316,17 +318,17 @@ namespace UnitTest TEST_F(ViewportEditorModeTrackerTestFixture, ActivatingViewportEditorModeForNonExistentIdCreatesViewportEditorModesForThatId) { // Given a viewport not currently being tracked - const ViewportId viewportid = 0; - EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); - EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }), nullptr); + const TrackerId id = 0; + EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); + EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ id }), nullptr); // When a mode is activated for that viewport const auto editorMode = ViewportEditorMode::Default; - m_viewportEditorModeTracker.ActivateMode({ viewportid }, editorMode); - const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }); + m_viewportEditorModeTracker.ActivateMode({ id }, editorMode); + const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ id }); // Expect that viewport to now be tracked - EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); + EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); EXPECT_NE(viewportEditorModeState, nullptr); // Expect the mode for that viewport to be active @@ -336,23 +338,24 @@ namespace UnitTest TEST_F(ViewportEditorModeTrackerTestFixture, DeactivatingViewportEditorModeForNonExistentIdCreatesViewportEditorModesForThatIdButReturnsError) { // Given a viewport not currently being tracked - const ViewportId viewportid = 0; - EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); - EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }), nullptr); + const TrackerId id = 0; + EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); + EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ id }), nullptr); // When a mode is deactivated for that viewport const auto editorMode = ViewportEditorMode::Default; const auto expectedErrorMsg = AZStd::string::format( - "Call to DeactivateMode for mode '%u' on id '%i' without precursor call to ActivateMode", static_cast(editorMode), viewportid); - const auto result = m_viewportEditorModeTracker.DeactivateMode({ viewportid }, editorMode); + "Call to DeactivateMode for mode '%u' on id '%s' without precursor call to ActivateMode", static_cast(editorMode), + id.ToString().c_str()); + const auto result = m_viewportEditorModeTracker.DeactivateMode({ id }, editorMode); // Expect an error due to no precursor activation of that mode EXPECT_FALSE(result.IsSuccess()); EXPECT_EQ(result.GetError(), expectedErrorMsg); // Expect that viewport to now be tracked - const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }); - EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); + const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ id }); + EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); // Expect the mode for that viewport to be inactive EXPECT_NE(viewportEditorModeState, nullptr); @@ -361,45 +364,46 @@ namespace UnitTest TEST_F(ViewportEditorModeTrackerTestFixture, GettingNonExistentViewportEditorModesForIdReturnsNull) { - const ViewportId viewportid = 0; - EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); - EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }), nullptr); + const TrackerId id = 0; + EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); + EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ id }), nullptr); } TEST_F(ViewportEditorModeTrackerTestFixture, ActivatingViewportEditorModesForExistingIdInThatStateReturnsError) { // Given a viewport not currently tracked - const ViewportId viewportid = 0; - EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); - EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }), nullptr); + const TrackerId id = 0; + EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); + EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ id }), nullptr); const auto editorMode = ViewportEditorMode::Default; { // When the mode is activated for the viewport - const auto result = m_viewportEditorModeTracker.ActivateMode({ viewportid }, editorMode); + const auto result = m_viewportEditorModeTracker.ActivateMode({ id }, editorMode); // Expect no error as there is no duplicate activation EXPECT_TRUE(result.IsSuccess()); // Expect the mode to be active for the viewport - const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }); - EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); + const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ id }); + EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); EXPECT_NE(viewportEditorModeState, nullptr); EXPECT_TRUE(viewportEditorModeState->IsModeActive(editorMode)); } { // When the mode is activated again for the viewport - const auto result = m_viewportEditorModeTracker.ActivateMode({ viewportid }, editorMode); + const auto result = m_viewportEditorModeTracker.ActivateMode({ id }, editorMode); // Expect an error for the duplicate activation const auto expectedErrorMsg = AZStd::string::format( - "Duplicate call to ActivateMode for mode '%u' on id '%i'", static_cast(editorMode), viewportid); + "Duplicate call to ActivateMode for mode '%u' on id '%s'", static_cast(editorMode), + id.ToString().c_str()); EXPECT_FALSE(result.IsSuccess()); EXPECT_EQ(result.GetError(), expectedErrorMsg); // Expect the mode to still be active for the viewport - const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }); - EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); + const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ id }); + EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); EXPECT_NE(viewportEditorModeState, nullptr); EXPECT_TRUE(viewportEditorModeState->IsModeActive(editorMode)); } @@ -408,38 +412,39 @@ namespace UnitTest TEST_F(ViewportEditorModeTrackerTestFixture, DeactivatingViewportEditorModesForExistingIdNotInThatStateReturnssError) { // Given a viewport not currently tracked - const ViewportId viewportid = 0; - EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); - EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }), nullptr); + const TrackerId id = 0; + EXPECT_FALSE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); + EXPECT_EQ(m_viewportEditorModeTracker.GetViewportEditorModes({ id }), nullptr); const auto editorMode = ViewportEditorMode::Default; { // When the mode is activated and then deactivated for the viewport - m_viewportEditorModeTracker.ActivateMode({ viewportid }, editorMode); - const auto result = m_viewportEditorModeTracker.DeactivateMode({ viewportid }, editorMode); + m_viewportEditorModeTracker.ActivateMode({ id }, editorMode); + const auto result = m_viewportEditorModeTracker.DeactivateMode({ id }, editorMode); // Expect no error as there is no duplicate deactivation EXPECT_TRUE(result.IsSuccess()); // Expect the mode to be inctive for the viewport - const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }); - EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); + const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ id }); + EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); EXPECT_NE(viewportEditorModeState, nullptr); EXPECT_FALSE(viewportEditorModeState->IsModeActive(editorMode)); } { // When the mode is deactivated again for the viewport - const auto result = m_viewportEditorModeTracker.DeactivateMode({ viewportid }, editorMode); + const auto result = m_viewportEditorModeTracker.DeactivateMode({ id }, editorMode); // Expect an error for the duplicate deactivation const auto expectedErrorMsg = AZStd::string::format( - "Duplicate call to DeactivateMode for mode '%u' on id '%i'", static_cast(editorMode), viewportid); + "Duplicate call to DeactivateMode for mode '%u' on id '%s'", static_cast(editorMode), + id.ToString().c_str()); EXPECT_FALSE(result.IsSuccess()); EXPECT_EQ(result.GetError(), expectedErrorMsg); // Expect the mode to still be inactive for the viewport - const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ viewportid }); - EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ viewportid })); + const auto* viewportEditorModeState = m_viewportEditorModeTracker.GetViewportEditorModes({ id }); + EXPECT_TRUE(m_viewportEditorModeTracker.IsViewportModeTracked({ id })); EXPECT_NE(viewportEditorModeState, nullptr); EXPECT_FALSE(viewportEditorModeState->IsModeActive(editorMode)); } @@ -459,9 +464,9 @@ namespace UnitTest // When each editor mode is activated by the state tracker for a specific viewport for (auto mode = 0; mode < ViewportEditorModes::NumEditorModes; mode++) { - const ViewportId viewportId = mode; + const TrackerId id = m_handlerIds[mode]; const ViewportEditorMode editorMode = static_cast(mode); - m_viewportEditorModeTracker.ActivateMode({ viewportId }, editorMode); + m_viewportEditorModeTracker.ActivateMode({ id }, editorMode); } for (auto mode = 0; mode < ViewportEditorModes::NumEditorModes; mode++) @@ -491,10 +496,10 @@ namespace UnitTest // When each editor mode is activated deactivated by the state tracker for a specific viewport for (auto mode = 0; mode < ViewportEditorModes::NumEditorModes; mode++) { - const ViewportId viewportId = mode; + const TrackerId id = m_handlerIds[mode]; const ViewportEditorMode editorMode = static_cast(mode); - m_viewportEditorModeTracker.ActivateMode({ viewportId }, editorMode); - m_viewportEditorModeTracker.DeactivateMode({ viewportId }, editorMode); + m_viewportEditorModeTracker.ActivateMode({ id }, editorMode); + m_viewportEditorModeTracker.DeactivateMode({ id }, editorMode); } for (auto mode = 0; mode < ViewportEditorModes::NumEditorModes; mode++) diff --git a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp index 412e53d0da..0bb3639826 100644 --- a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp +++ b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp @@ -298,8 +298,10 @@ namespace PhysX assetMaterialData.m_nodesToPerFaceMaterialIndices.emplace(nodeName, AZStd::vector(faceCount)); - // Convex and primitive methods can only have 1 material + // Convex and primitive methods can only have 1 material per node. const bool limitToOneMaterial = meshGroup.GetExportAsConvex() || meshGroup.GetExportAsPrimitive(); + AZStd::string firstMaterial; + AZStd::set nodeMaterials; for (AZ::u32 faceIndex = 0; faceIndex < faceCount; ++faceIndex) { @@ -318,18 +320,28 @@ namespace PhysX materialName = localSourceSceneMaterialsList[materialId]; - // Keep using the first material when it has to be limited to one. - if (limitToOneMaterial && - assetMaterialData.m_sourceSceneMaterialNames.size() == 1 && - assetMaterialData.m_sourceSceneMaterialNames[0] != materialName) + // Use the first material found in the mesh when it has to be limited to one. + if (limitToOneMaterial) { - materialName = assetMaterialData.m_sourceSceneMaterialNames[0]; + nodeMaterials.insert(materialName); + if (firstMaterial.empty()) + { + firstMaterial = materialName; + } + materialName = firstMaterial; } } const AZ::u16 materialIndex = InsertMaterialIndexByName(materialName, assetMaterialData); assetMaterialData.m_nodesToPerFaceMaterialIndices[nodeName][faceIndex] = materialIndex; } + + if (limitToOneMaterial && nodeMaterials.size() > 1) + { + AZ_TracePrintf(AZ::SceneAPI::Utilities::WarningWindow, + "Node '%s' has %d materials, but cooking methods Convex and Primitive support one material per node. The first material '%s' will be used.", + sceneNodeSelectionList.GetSelectedNode(index).c_str(), nodeMaterials.size(), firstMaterial.c_str()); + } } return assetMaterialData; diff --git a/Gems/PhysX/Code/Source/Pipeline/MeshGroup.cpp b/Gems/PhysX/Code/Source/Pipeline/MeshGroup.cpp index f95804e805..d0ff4008b2 100644 --- a/Gems/PhysX/Code/Source/Pipeline/MeshGroup.cpp +++ b/Gems/PhysX/Code/Source/Pipeline/MeshGroup.cpp @@ -852,16 +852,7 @@ namespace PhysX { if (index < m_materialSlots.size()) { - // When limited to one material, clarify in the label the material - // will be used for the entire object. - if (index == 0 && (GetExportAsConvex() || GetExportAsPrimitive())) - { - return m_materialSlots[index] + " (entire object)"; - } - else - { - return m_materialSlots[index]; - } + return m_materialSlots[index]; } else {