[LYN-2255] Refactored some EditorEntityHelpers so they can be re-used.

This commit is contained in:
Chris Galvan
2021-04-14 16:01:26 -05:00
parent 7b3b1cd73e
commit 0f13a71bd2
7 changed files with 174 additions and 22 deletions
@@ -136,6 +136,48 @@ namespace AzToolsFramework
return entity->GetName();
}
EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds)
{
EntityList entities;
entities.reserve(inputEntityIds.size());
for (AZ::EntityId entityId : inputEntityIds)
{
if (!entityId.IsValid())
{
continue;
}
if (auto entity = GetEntityById(entityId))
{
entities.emplace_back(entity);
}
}
return entities;
}
EntityList EntityIdSetToEntityList(const EntityIdSet& inputEntityIds)
{
EntityList entities;
entities.reserve(inputEntityIds.size());
for (AZ::EntityId entityId : inputEntityIds)
{
if (!entityId.IsValid())
{
continue;
}
if (auto entity = GetEntityById(entityId))
{
entities.emplace_back(entity);
}
}
return entities;
}
void GetAllComponentsForEntity(const AZ::Entity* entity, AZ::Entity::ComponentArrayType& componentsOnEntity)
{
if (entity)
@@ -1068,6 +1110,45 @@ namespace AzToolsFramework
return !allEntityClonesContainer.m_entities.empty();
}
EntityIdSet GetCulledEntityHierarchy(const EntityIdList& entities)
{
EntityIdSet culledEntities;
for (const AZ::EntityId& entityId : entities)
{
bool selectionIncludesTransformHeritage = false;
AZ::EntityId parentEntityId = entityId;
do
{
AZ::EntityId nextParentId;
AZ::TransformBus::EventResult(
/*result*/ nextParentId,
/*address*/ parentEntityId,
&AZ::TransformBus::Events::GetParentId);
parentEntityId = nextParentId;
if (!parentEntityId.IsValid())
{
break;
}
for (const AZ::EntityId& parentCheck : entities)
{
if (parentCheck == parentEntityId)
{
selectionIncludesTransformHeritage = true;
break;
}
}
} while (parentEntityId.IsValid() && !selectionIncludesTransformHeritage);
if (!selectionIncludesTransformHeritage)
{
culledEntities.insert(entityId);
}
}
return culledEntities;
}
namespace Internal
{
void CloneSliceEntitiesAndChildren(
@@ -47,6 +47,9 @@ namespace AzToolsFramework
AZStd::string GetEntityName(const AZ::EntityId& entityId, const AZStd::string_view& nameOverride = {});
EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds);
EntityList EntityIdSetToEntityList(const EntityIdSet & inputEntityIds);
template <typename... ComponentTypes>
struct AddComponents
{
@@ -202,4 +205,7 @@ namespace AzToolsFramework
/// Wrap EBus SetSelectedEntities call.
void SelectEntities(const AzToolsFramework::EntityIdList& entities);
/// Return a set of entities, culling any that have an ancestor in the list.
EntityIdSet GetCulledEntityHierarchy(const EntityIdList & entities);
}; // namespace AzToolsFramework
@@ -61,8 +61,7 @@ namespace AzToolsFramework
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZStd::string_view filePath)
{
// Retrieve entityList from entityIds
EntityList inputEntityList;
EntityIdListToEntityList(entityIds, inputEntityList);
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
// Find common root and top level entities
bool entitiesHaveCommonRoot = false;
@@ -419,8 +418,7 @@ namespace AzToolsFramework
InstanceOptionalReference instance = GetOwnerInstanceByEntityId(entityIds[0]);
// Retrieve entityList from entityIds
EntityList inputEntityList;
EntityIdListToEntityList(entityIds, inputEntityList);
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
@@ -767,18 +765,5 @@ namespace AzToolsFramework
return true;
}
void PrefabPublicHandler::EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities)
{
outEntities.reserve(inputEntityIds.size());
for (AZ::EntityId entityId : inputEntityIds)
{
if (entityId.IsValid())
{
outEntities.emplace_back(GetEntityById(entityId));
}
}
}
}
}
@@ -70,7 +70,6 @@ namespace AzToolsFramework
static Instance* GetParentInstance(Instance* instance);
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation);
static void EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities);
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
@@ -0,0 +1,71 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
namespace UnitTest
{
using namespace AZ;
using namespace AzToolsFramework;
class EditorEntityHelpersTest
: public ToolsApplicationFixture
{
void SetUpEditorFixtureImpl() override
{
m_parent1 = CreateDefaultEditorEntity("Parent1");
m_child1 = CreateDefaultEditorEntity("Child1");
m_child2 = CreateDefaultEditorEntity("Child2");
m_grandChild1 = CreateDefaultEditorEntity("GrandChild1");
m_parent2 = CreateDefaultEditorEntity("Parent2");
AZ::TransformBus::Event(m_child1, &AZ::TransformBus::Events::SetParent, m_parent1);
AZ::TransformBus::Event(m_child2, &AZ::TransformBus::Events::SetParent, m_parent1);
AZ::TransformBus::Event(m_grandChild1, &AZ::TransformBus::Events::SetParent, m_child1);
}
public:
AZ::EntityId m_parent1;
AZ::EntityId m_child1;
AZ::EntityId m_child2;
AZ::EntityId m_grandChild1;
AZ::EntityId m_parent2;
};
TEST_F(EditorEntityHelpersTest, EditorEntityHelpersTests_GetCulledEntityHierarchy)
{
EntityIdList testEntityIds{ m_parent1, m_child1, m_child2, m_grandChild1, m_parent2 };
EntityIdSet culledSet = GetCulledEntityHierarchy(testEntityIds);
// There should only be two EntityIds returned (m_parent1, and m_parent2),
// since all the others should be culled out since they have a common ancestor
// in the list already
EXPECT_EQ(culledSet.size(), 2);
EntityIdList foundEntityIds{ m_parent1, m_parent2 };
for (auto& entityId : foundEntityIds)
{
EXPECT_TRUE(AZStd::find(culledSet.begin(), culledSet.end(), entityId) != culledSet.end());
}
EntityIdList culledEntityIds{ m_child1, m_child2, m_grandChild1 };
for (auto& entityId : culledEntityIds)
{
EXPECT_FALSE(AZStd::find(culledSet.begin(), culledSet.end(), entityId) != culledSet.end());
}
}
}
@@ -85,7 +85,9 @@ set(FILES
Prefab/SpawnableSortEntitiesTestFixture.cpp
Prefab/SpawnableSortEntitiesTestFixture.h
Entity/EditorEntityContextComponentTests.cpp
Entity/EditorEntityHelpersTests.cpp
Entity/EditorEntitySearchComponentTests.cpp
Entity/EditorEntitySelectionTests.cpp
SliceStabilityTests/SliceStabilityTestFramework.h
SliceStabilityTests/SliceStabilityTestFramework.cpp
SliceStabilityTests/SliceStabilityCreateTests.cpp
@@ -670,9 +670,13 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
action = menu->addAction(QObject::tr("Create layer"));
QObject::connect(action, &QAction::triggered, [this] { ContextMenu_NewLayer(); });
AzToolsFramework::EntityIdList entities;
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
entities,
&AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
SetupLayerContextMenu(menu);
AzToolsFramework::EntityIdSet flattenedSelection;
GetSelectedEntitiesSetWithFlattenedHierarchy(flattenedSelection);
AzToolsFramework::EntityIdSet flattenedSelection = AzToolsFramework::GetCulledEntityHierarchy(entities);
AzToolsFramework::SetupAddToLayerMenu(menu, flattenedSelection, [this] { return ContextMenu_NewLayer(); });
SetupSliceContextMenu(menu);
@@ -1220,8 +1224,12 @@ void SandboxIntegrationManager::CloneSelection(bool& handled)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AzToolsFramework::EntityIdSet duplicationSet;
GetSelectedEntitiesSetWithFlattenedHierarchy(duplicationSet);
AzToolsFramework::EntityIdList entities;
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
entities,
&AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
AzToolsFramework::EntityIdSet duplicationSet = AzToolsFramework::GetCulledEntityHierarchy(entities);
if (duplicationSet.size() > 0)
{