Added additional functions to edit prefabs during processing to PrefabDocument.
Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com>
This commit is contained in:
@@ -608,6 +608,31 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
AZ::EntityId Instance::GetEntityIdFromAliasPath(AliasPathView relativeAliasPath) const
|
||||
{
|
||||
return GetInstanceAndEntityIdFromAliasPath(relativeAliasPath).second;
|
||||
}
|
||||
|
||||
AZStd::pair<Instance*, AZ::EntityId> Instance::GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath)
|
||||
{
|
||||
Instance* instance = this;
|
||||
AliasPathView path = relativeAliasPath.ParentPath();
|
||||
for (auto it : path)
|
||||
{
|
||||
InstanceOptionalReference child = instance->FindNestedInstance(it.Native());
|
||||
if (child.has_value())
|
||||
{
|
||||
instance = &(child->get());
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZStd::pair<Instance*, AZ::EntityId>(nullptr, AZ::EntityId());
|
||||
}
|
||||
}
|
||||
|
||||
return AZStd::pair<Instance*, AZ::EntityId>(instance, instance->GetEntityId(relativeAliasPath.Filename().Native()));
|
||||
}
|
||||
|
||||
AZStd::pair<const Instance*, AZ::EntityId> Instance::GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) const
|
||||
{
|
||||
const Instance* instance = this;
|
||||
AliasPathView path = relativeAliasPath.ParentPath();
|
||||
@@ -620,11 +645,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::EntityId();
|
||||
return AZStd::pair<const Instance*, AZ::EntityId>(nullptr, AZ::EntityId());
|
||||
}
|
||||
}
|
||||
|
||||
return instance->GetEntityId(relativeAliasPath.Filename().Native());
|
||||
return AZStd::pair<const Instance*, AZ::EntityId>(instance, instance->GetEntityId(relativeAliasPath.Filename().Native()));
|
||||
}
|
||||
|
||||
AZStd::vector<InstanceAlias> Instance::GetNestedInstanceAliases(TemplateId templateId) const
|
||||
|
||||
@@ -169,6 +169,13 @@ namespace AzToolsFramework
|
||||
* @return entityId, invalid ID if not found
|
||||
*/
|
||||
AZ::EntityId GetEntityIdFromAliasPath(AliasPathView relativeAliasPath) const;
|
||||
/**
|
||||
* Retrieves the instance pointer and entity id from an alias path that's relative to this instance.
|
||||
*
|
||||
* @return A pair with the Instance and entity id. The Instance is set to null and entityId is set to invalid if not found.
|
||||
*/
|
||||
AZStd::pair<Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath);
|
||||
AZStd::pair<const Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) const;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
enum class EntityAliasType : uint8_t
|
||||
{
|
||||
Disable, //!< No alias is added.
|
||||
OptionalReplace, //!< At runtime the entity might be replaced. If the alias is disabled the original entity will be spawned.
|
||||
//!< The original entity will be left in the spawnable and a copy is returned.
|
||||
Replace, //!< At runtime the entity will be replaced. If the alias is disabled nothing will be spawned. The original
|
||||
//!< entity is returned and a blank entity is left.
|
||||
Additional, //!< At runtime the alias entity will be added as an additional but unrelated entity with a new entity id.
|
||||
//!< An empty entity will be returned.
|
||||
Merge //!< At runtime the components in both entities will be merged. An empty entity will be returned. The added
|
||||
//!< components may no conflict with the entities already in the root entity.
|
||||
};
|
||||
|
||||
enum class EntityAliasSpawnableLoadBehavior : uint8_t
|
||||
{
|
||||
NoLoad, //!< Don't load the spawnable referenced in the entity alias. Loading will be up to the caller.
|
||||
QueueLoad, //!< Queue the spawnable referenced in the entity alias for loading. This will be an async load because asset
|
||||
//!< handlers aren't allowed to start a blocking load as this can lead to deadlocks. This option will allow
|
||||
//!< to disable loading the referenced spawnable through the event fired from the spawnables asset handler.
|
||||
DependentLoad //!< The spawnable referenced in the entity alias is made a dependency of the spawnable that holds the entity
|
||||
//!< alias. This will cause the spawnable to be automatically loaded along with the owning spawnable.
|
||||
};
|
||||
|
||||
struct EntityAliasSpawnableLink
|
||||
{
|
||||
EntityAliasSpawnableLink(AzFramework::Spawnable& spawnable, AZ::EntityId index);
|
||||
|
||||
AzFramework::Spawnable& m_spawnable;
|
||||
AZ::EntityId m_index;
|
||||
};
|
||||
|
||||
struct EntityAliasPrefabLink
|
||||
{
|
||||
EntityAliasPrefabLink(AZStd::string prefabName, AzToolsFramework::Prefab::AliasPath alias);
|
||||
|
||||
AZStd::string m_prefabName;
|
||||
AzToolsFramework::Prefab::AliasPath m_alias;
|
||||
};
|
||||
|
||||
struct EntityAliasStore
|
||||
{
|
||||
using LinkStore = AZStd::variant<AZStd::monostate, EntityAliasSpawnableLink, EntityAliasPrefabLink>;
|
||||
|
||||
LinkStore m_source;
|
||||
LinkStore m_target;
|
||||
uint32_t m_tag;
|
||||
AzFramework::Spawnable::EntityAliasType m_aliasType;
|
||||
EntityAliasSpawnableLoadBehavior m_loadBehavior;
|
||||
};
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
+44
-8
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/PrefabDocument.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
@@ -68,6 +69,43 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
return AZStd::move(m_dom);
|
||||
}
|
||||
|
||||
void PrefabDocument::ListEntitiesWithComponentType(
|
||||
AZ::TypeId componentType, const AZStd::function<bool(AzToolsFramework::Prefab::AliasPath&&)>& callback) const
|
||||
{
|
||||
m_instance->GetAllEntitiesInHierarchyConst(
|
||||
[this, &componentType, &callback](const AZ::Entity& entity) -> bool
|
||||
{
|
||||
if (entity.FindComponent(componentType))
|
||||
{
|
||||
return callback(m_instance->GetAliasPathRelativeToInstance(entity.GetId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AZ::Entity* PrefabDocument::CreateEntityAlias(
|
||||
PrefabDocument& source,
|
||||
AzToolsFramework::Prefab::AliasPathView entity,
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType,
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior,
|
||||
uint32_t tag,
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context)
|
||||
{
|
||||
auto&& [sourceInstance, entityId] = source.m_instance->GetInstanceAndEntityIdFromAliasPath(entity);
|
||||
if (sourceInstance != nullptr && entityId.IsValid())
|
||||
{
|
||||
return SpawnableUtils::CreateEntityAlias(
|
||||
source.m_name, *sourceInstance, m_name, *m_instance, entityId, aliasType, loadBehavior, tag, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
AzToolsFramework::Prefab::Instance& PrefabDocument::GetInstance()
|
||||
{
|
||||
// Assume that changes will be made to the instance.
|
||||
@@ -91,18 +129,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
}
|
||||
else
|
||||
{
|
||||
AZStd::string errorMessage("Failed to construct Prefab instance from given PrefabDOM");
|
||||
|
||||
#ifdef AZ_ENABLE_TRACING
|
||||
AZStd::string_view sourceName = m_name;
|
||||
PrefabDomValueConstReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName);
|
||||
if (sourceReference.has_value() && sourceReference->get().IsString() && sourceReference->get().GetStringLength() != 0)
|
||||
{
|
||||
errorMessage += " (Source: ";
|
||||
errorMessage += AZStd::string_view(sourceReference->get().GetString(), sourceReference->get().GetStringLength());
|
||||
errorMessage += ')';
|
||||
sourceName = AZStd::string_view(sourceReference->get().GetString(), sourceReference->get().GetStringLength());
|
||||
}
|
||||
|
||||
errorMessage += '.';
|
||||
AZ_Error("PrefabDocument", false, errorMessage.c_str());
|
||||
AZ_Error(
|
||||
"PrefabDocument", false, "Failed to construct Prefab instance from given PrefabDOM '%.*s'.", AZ_STRING_ARG(sourceName));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomTypes.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/EntityAliasTypes.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
class PrefabProcessorContext;
|
||||
|
||||
class PrefabDocument final
|
||||
{
|
||||
public:
|
||||
@@ -32,6 +37,18 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
const PrefabDom& GetDom() const;
|
||||
PrefabDom&& TakeDom();
|
||||
|
||||
template<typename Component>
|
||||
void ListEntitiesWithComponentType(const AZStd::function<bool(AzToolsFramework::Prefab::AliasPath&&)>& callback) const;
|
||||
void ListEntitiesWithComponentType(
|
||||
AZ::TypeId componentType, const AZStd::function<bool(AzToolsFramework::Prefab::AliasPath&&)>& callback) const;
|
||||
AZ::Entity* CreateEntityAlias(
|
||||
PrefabDocument& source,
|
||||
AzToolsFramework::Prefab::AliasPathView entity,
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType,
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior,
|
||||
uint32_t tag,
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context);
|
||||
|
||||
// Where possible, prefer functions directly on the PrefabDocument Instead of using the Instance.
|
||||
AzToolsFramework::Prefab::Instance& GetInstance();
|
||||
const AzToolsFramework::Prefab::Instance& GetInstance() const;
|
||||
@@ -45,3 +62,5 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
mutable bool m_isDirty{ false };
|
||||
};
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
#include <AzToolsFramework/Prefab/Spawnable/PrefabDocument.inl>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
template<typename Component>
|
||||
void PrefabDocument::ListEntitiesWithComponentType(const AZStd::function<bool(AzToolsFramework::Prefab::AliasPath&&)>& callback) const
|
||||
{
|
||||
ListEntitiesWithComponentType(azrtti_typeid<Component>(), callback);
|
||||
}
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
+1
-50
@@ -21,61 +21,12 @@
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomTypes.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/EntityAliasTypes.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/PrefabDocument.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
enum class EntityAliasType : uint8_t
|
||||
{
|
||||
Disable, //!< No alias is added.
|
||||
OptionalReplace, //!< At runtime the entity might be replaced. If the alias is disabled the original entity will be spawned.
|
||||
//!< The original entity will be left in the spawnable and a copy is returned.
|
||||
Replace, //!< At runtime the entity will be replaced. If the alias is disabled nothing will be spawned. The original
|
||||
//!< entity is returned and a blank entity is left.
|
||||
Additional, //!< At runtime the alias entity will be added as an additional but unrelated entity with a new entity id.
|
||||
//!< An empty entity will be returned.
|
||||
Merge //!< At runtime the components in both entities will be merged. An empty entity will be returned. The added
|
||||
//!< components may no conflict with the entities already in the root entity.
|
||||
};
|
||||
|
||||
enum class EntityAliasSpawnableLoadBehavior : uint8_t
|
||||
{
|
||||
NoLoad, //!< Don't load the spawnable referenced in the entity alias. Loading will be up to the caller.
|
||||
QueueLoad, //!< Queue the spawnable referenced in the entity alias for loading. This will be an async load because asset
|
||||
//!< handlers aren't allowed to start a blocking load as this can lead to deadlocks. This option will allow
|
||||
//!< to disable loading the referenced spawnable through the event fired from the spawnables asset handler.
|
||||
DependentLoad //!< The spawnable referenced in the entity alias is made a dependency of the spawnable that holds the entity
|
||||
//!< alias. This will cause the spawnable to be automatically loaded along with the owning spawnable.
|
||||
};
|
||||
|
||||
struct EntityAliasSpawnableLink
|
||||
{
|
||||
EntityAliasSpawnableLink(AzFramework::Spawnable& spawnable, AZ::EntityId index);
|
||||
|
||||
AzFramework::Spawnable& m_spawnable;
|
||||
AZ::EntityId m_index;
|
||||
};
|
||||
|
||||
struct EntityAliasPrefabLink
|
||||
{
|
||||
EntityAliasPrefabLink(AZStd::string prefabName, AzToolsFramework::Prefab::AliasPath alias);
|
||||
|
||||
AZStd::string m_prefabName;
|
||||
AzToolsFramework::Prefab::AliasPath m_alias;
|
||||
};
|
||||
|
||||
struct EntityAliasStore
|
||||
{
|
||||
using LinkStore = AZStd::variant<AZStd::monostate, EntityAliasSpawnableLink, EntityAliasPrefabLink>;
|
||||
|
||||
LinkStore m_source;
|
||||
LinkStore m_target;
|
||||
uint32_t m_tag;
|
||||
AzFramework::Spawnable::EntityAliasType m_aliasType;
|
||||
EntityAliasSpawnableLoadBehavior m_loadBehavior;
|
||||
};
|
||||
|
||||
struct AssetDependencyInfo
|
||||
{
|
||||
AZ::Data::AssetId m_assetId;
|
||||
|
||||
+1
-26
@@ -21,6 +21,7 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
{
|
||||
@@ -222,32 +223,6 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
}
|
||||
}
|
||||
|
||||
void PatchParents(const AzToolsFramework::Prefab::Instance& source, AzToolsFramework::Prefab::Instance& target)
|
||||
{
|
||||
target.GetEntities(
|
||||
[&source, &target](AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
AzFramework::TransformComponent* transform = entity->FindComponent<AzFramework::TransformComponent>();
|
||||
if (transform)
|
||||
{
|
||||
if (transform->GetParentId().IsValid())
|
||||
{
|
||||
AliasPath originalParentAlias = source.GetAliasPathRelativeToInstance(transform->GetParentId());
|
||||
if (!originalParentAlias.empty())
|
||||
{
|
||||
AZ::EntityId targetParentId = target.GetEntityIdFromAliasPath(originalParentAlias);
|
||||
if (targetParentId.IsValid())
|
||||
{
|
||||
// If this is valid then the parent was moved to the target spawnable so adjust the entity id.
|
||||
transform->SetParent(targetParentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
uint32_t FindEntityIndex(AZ::EntityId entity, const AzFramework::Spawnable& spawnable)
|
||||
{
|
||||
auto begin = spawnable.GetEntities().begin();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <AzCore/std/limits.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomTypes.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/EntityAliasTypes.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -24,6 +24,11 @@ namespace AzToolsFramework::Prefab
|
||||
class Instance;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
class PrefabProcessorContext;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
{
|
||||
static constexpr uint32_t InvalidEntityIndex = AZStd::numeric_limits<uint32_t>::max();
|
||||
@@ -41,8 +46,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasSpawnableLoadBehavior loadBehavior,
|
||||
uint32_t tag,
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext& context);
|
||||
void PatchParents(const AzToolsFramework::Prefab::Instance& source, AzToolsFramework::Prefab::Instance& target);
|
||||
|
||||
|
||||
uint32_t FindEntityIndex(AZ::EntityId entity, const AzFramework::Spawnable& spawnable);
|
||||
|
||||
void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable);
|
||||
|
||||
@@ -723,6 +723,7 @@ set(FILES
|
||||
Prefab/Spawnable/EditorOnlyEntityHandler/UiEditorOnlyEntityHandler.cpp
|
||||
Prefab/Spawnable/EditorOnlyEntityHandler/WorldEditorOnlyEntityHandler.h
|
||||
Prefab/Spawnable/EditorOnlyEntityHandler/WorldEditorOnlyEntityHandler.cpp
|
||||
Prefab/Spawnable/EntityAliasTypes.h
|
||||
Prefab/Spawnable/InMemorySpawnableAssetContainer.h
|
||||
Prefab/Spawnable/InMemorySpawnableAssetContainer.cpp
|
||||
Prefab/Spawnable/PrefabCatchmentProcessor.h
|
||||
@@ -731,6 +732,7 @@ set(FILES
|
||||
Prefab/Spawnable/PrefabConversionPipeline.cpp
|
||||
Prefab/Spawnable/PrefabConverterStackProfileNames.h
|
||||
Prefab/Spawnable/PrefabDocument.h
|
||||
Prefab/Spawnable/PrefabDocument.inl
|
||||
Prefab/Spawnable/PrefabDocument.cpp
|
||||
Prefab/Spawnable/ProcesedObjectStore.h
|
||||
Prefab/Spawnable/ProcesedObjectStore.cpp
|
||||
|
||||
Reference in New Issue
Block a user