Merge branch 'development' of https://github.com/o3de/o3de into NetHierarchyInput
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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<CComponentEntityObject*>(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<int>(m_visibleObjects.size()));
|
||||
|
||||
if (dc.flags & DISPLAY_2D)
|
||||
{
|
||||
int numVis = static_cast<int>(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<int>(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<double> 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<GUID>& guids)
|
||||
|
||||
void CObjectManager::FindObjectsInRect(
|
||||
[[maybe_unused]] CViewport* view, [[maybe_unused]] const QRect& rect, [[maybe_unused]] std::vector<GUID>& 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<const CBaseObject*> 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
|
||||
|
||||
@@ -52,40 +52,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Array of editor objects.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CBaseObjectsCache
|
||||
{
|
||||
public:
|
||||
int GetObjectCount() const { return static_cast<int>(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<AZ::EntityId>& 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<CBaseObject> > m_objects;
|
||||
AZStd::vector<AZ::EntityId> m_entityIds;
|
||||
unsigned int m_serialNumber = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
* CObjectManager is a singleton object that
|
||||
* manages global set of objects in level.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+9
-9
@@ -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<void, AZStd::string> 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<void, AZStd::string> 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
|
||||
|
||||
|
||||
+6
-6
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
|
||||
|
||||
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.
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@
|
||||
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeNotificationBus.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeSystemComponent.h>
|
||||
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -32,14 +32,14 @@ namespace AzToolsFramework
|
||||
|
||||
m_manipulatorManager = AZStd::make_shared<AzToolsFramework::ManipulatorManager>(AzToolsFramework::g_mainManipulatorManagerId);
|
||||
m_transformComponentSelection = AZStd::make_unique<EditorTransformComponentSelection>(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)
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ namespace AzToolsFramework
|
||||
: m_editorHelpers(AZStd::make_unique<EditorHelpers>(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
|
||||
|
||||
+18
-16
@@ -46,13 +46,14 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> 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<AZ::u32>(mode), viewportEditorModeInfo.m_id));
|
||||
"Duplicate call to ActivateMode for mode '%u' on id '%s'", static_cast<AZ::u32>(mode),
|
||||
ViewportEditorModeTrackerInfo.m_id.ToString<AZStd::string>().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<void, AZStd::string> 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<AZ::u32>(mode), viewportEditorModeInfo.m_id));
|
||||
"Duplicate call to DeactivateMode for mode '%u' on id '%s'", static_cast<AZ::u32>(mode),
|
||||
ViewportEditorModeTrackerInfo.m_id.ToString<AZStd::string>().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<AZ::u32>(mode),
|
||||
viewportEditorModeInfo.m_id));
|
||||
"Call to DeactivateMode for mode '%u' on id '%s' without precursor call to ActivateMode", static_cast<AZ::u32>(mode),
|
||||
ViewportEditorModeTrackerInfo.m_id.ToString<AZStd::string>().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
|
||||
|
||||
+6
-6
@@ -42,14 +42,14 @@ namespace AzToolsFramework
|
||||
{
|
||||
public:
|
||||
// ViewportEditorModeTrackerInterface overrides ...
|
||||
AZ::Outcome<void, AZStd::string> ActivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override;
|
||||
AZ::Outcome<void, AZStd::string> DeactivateMode(const ViewportEditorModeInfo& viewportEditorModeInfo, ViewportEditorMode mode) override;
|
||||
const ViewportEditorModesInterface* GetViewportEditorModes(const ViewportEditorModeInfo& viewportEditorModeInfo) const override;
|
||||
AZ::Outcome<void, AZStd::string> ActivateMode(const ViewportEditorModeTrackerInfo& ViewportEditorModeTrackerInfo, ViewportEditorMode mode) override;
|
||||
AZ::Outcome<void, AZStd::string> 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<typename ViewportEditorModeInfo::IdType, ViewportEditorModes>;
|
||||
ViewportEditorModesMap m_viewportEditorModesMap; //!< Editor mode state per viewport.
|
||||
using ViewportEditorModesMap = AZStd::unordered_map<typename ViewportEditorModeTrackerInfo::IdType, ViewportEditorModes>;
|
||||
ViewportEditorModesMap m_viewportEditorModesMap; //!< Editor mode states per tracker.
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
|
||||
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorPickEntitySelection.h>
|
||||
#include <AzToolsFramework/ViewportSelection/ViewportEditorModeTracker.h>
|
||||
|
||||
@@ -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<ViewportEditorMode, ReceivedEvents>;
|
||||
|
||||
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<ViewportEditorModeNotificationsBusHandler>(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<ViewportEditorModeNotificationsBusHandler>(m_handlerIds[mode]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TearDownEditorFixtureImpl() override
|
||||
@@ -173,6 +173,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::array<AZStd::unique_ptr<ViewportEditorModeNotificationsBusHandler>, ViewportEditorModes::NumEditorModes> m_editorModeHandlers;
|
||||
AZStd::vector<TrackerId> m_handlerIds;
|
||||
};
|
||||
|
||||
// Fixture for testing the integration of viewport editor mode state tracker
|
||||
@@ -184,7 +185,8 @@ namespace UnitTest
|
||||
{
|
||||
m_viewportEditorModeTracker = AZ::Interface<ViewportEditorModeTrackerInterface>::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<AZ::u32>(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<AZ::u32>(editorMode),
|
||||
id.ToString<AZStd::string>().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<AZ::u32>(editorMode), viewportid);
|
||||
"Duplicate call to ActivateMode for mode '%u' on id '%s'", static_cast<AZ::u32>(editorMode),
|
||||
id.ToString<AZStd::string>().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<AZ::u32>(editorMode), viewportid);
|
||||
"Duplicate call to DeactivateMode for mode '%u' on id '%s'", static_cast<AZ::u32>(editorMode),
|
||||
id.ToString<AZStd::string>().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<ViewportEditorMode>(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<ViewportEditorMode>(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++)
|
||||
|
||||
@@ -298,8 +298,10 @@ namespace PhysX
|
||||
|
||||
assetMaterialData.m_nodesToPerFaceMaterialIndices.emplace(nodeName, AZStd::vector<AZ::u16>(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<AZStd::string> 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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user