Integrating up through commit 90f050496
This commit is contained in:
+30
-14
@@ -40,18 +40,18 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
return;
|
||||
}
|
||||
|
||||
prefabProcessorContext.ListPrefabs([this, &serializeContext, &prefabProcessorContext](AZStd::string_view prefabName, PrefabDom& prefab)
|
||||
{
|
||||
auto result = RemoveEditorInfo(prefab, serializeContext, prefabProcessorContext);
|
||||
if (!result)
|
||||
prefabProcessorContext.ListPrefabs(
|
||||
[this, &serializeContext, &prefabProcessorContext](AZStd::string_view prefabName, PrefabDom& prefab)
|
||||
{
|
||||
AZ_Assert(false,
|
||||
"Converting to runtime Prefab '%.*s' failed, Error: %s .",
|
||||
AZ_STRING_ARG(prefabName),
|
||||
result.GetError().c_str());
|
||||
return;
|
||||
}
|
||||
});
|
||||
auto result = RemoveEditorInfo(prefab, serializeContext, prefabProcessorContext);
|
||||
if (!result)
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false, "Converting to runtime Prefab '%.*s' failed, Error: %s .", AZ_STRING_ARG(prefabName),
|
||||
result.GetError().c_str());
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EditorInfoRemover::Reflect(AZ::ReflectContext* context)
|
||||
@@ -74,6 +74,12 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
}
|
||||
);
|
||||
|
||||
if (instance->HasContainerEntity())
|
||||
{
|
||||
auto containerEntityReference = instance->GetContainerEntity();
|
||||
result.emplace_back(&containerEntityReference->get());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -519,7 +525,8 @@ exportComponent, prefabProcessorContext);
|
||||
|
||||
// convert Prefab DOM into Prefab Instance.
|
||||
AZStd::unique_ptr<Instance> instance(aznew Instance());
|
||||
if (!Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*instance, prefab, false))
|
||||
if (!Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*instance, prefab,
|
||||
Prefab::PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId))
|
||||
{
|
||||
PrefabDomValueReference sourceReference = PrefabDomUtils::FindPrefabDomValue(prefab, PrefabDomUtils::SourceName);
|
||||
|
||||
@@ -613,19 +620,28 @@ exportComponent, prefabProcessorContext);
|
||||
[&exportEntitiesMap](AZStd::unique_ptr<AZ::Entity>& entity)
|
||||
{
|
||||
auto entityId = entity->GetId();
|
||||
entity.release();
|
||||
entity.reset(exportEntitiesMap[entityId]);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
if (instance->HasContainerEntity())
|
||||
{
|
||||
if (auto found = exportEntitiesMap.find(instance->GetContainerEntityId()); found != exportEntitiesMap.end())
|
||||
{
|
||||
instance->SetContainerEntity(*found->second);
|
||||
}
|
||||
}
|
||||
|
||||
// save the final result in the target Prefab DOM.
|
||||
if (!PrefabDomUtils::StoreInstanceInPrefabDom(*instance, prefab))
|
||||
PrefabDom filteredPrefab;
|
||||
if (!PrefabDomUtils::StoreInstanceInPrefabDom(*instance, filteredPrefab))
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format(
|
||||
"Saving exported Prefab Instance within a Prefab Dom failed.")
|
||||
);
|
||||
}
|
||||
prefab.Swap(filteredPrefab);
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
+49
-16
@@ -16,6 +16,7 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/SpawnableUtils.h>
|
||||
|
||||
@@ -23,9 +24,11 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
void PrefabCatchmentProcessor::Process(PrefabProcessorContext& context)
|
||||
{
|
||||
context.ListPrefabs([&context](AZStd::string_view prefabName, PrefabDom& prefab)
|
||||
AZ::DataStream::StreamType serializationFormat = m_serializationFormat == SerializationFormats::Binary ?
|
||||
AZ::DataStream::StreamType::ST_BINARY : AZ::DataStream::StreamType::ST_XML;
|
||||
context.ListPrefabs([&context, serializationFormat](AZStd::string_view prefabName, PrefabDom& prefab)
|
||||
{
|
||||
ProcessPrefab(context, prefabName, prefab);
|
||||
ProcessPrefab(context, prefabName, prefab, serializationFormat);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,31 +36,61 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context); serializeContext != nullptr)
|
||||
{
|
||||
serializeContext->Class<PrefabCatchmentProcessor, PrefabProcessor>()->Version(1);
|
||||
serializeContext->Enum<SerializationFormats>()
|
||||
->Value("Binary", SerializationFormats::Binary)
|
||||
->Value("Text", SerializationFormats::Text);
|
||||
|
||||
serializeContext->Class<PrefabCatchmentProcessor, PrefabProcessor>()
|
||||
->Version(2)
|
||||
->Field("SerializationFormat", &PrefabCatchmentProcessor::m_serializationFormat);
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabCatchmentProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab)
|
||||
void PrefabCatchmentProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab,
|
||||
AZ::DataStream::StreamType serializationFormat)
|
||||
{
|
||||
|
||||
AZStd::string uniqueName = prefabName;
|
||||
uniqueName += '.';
|
||||
uniqueName += AzFramework::Spawnable::FileExtension;
|
||||
uniqueName += AzFramework::Spawnable::DotFileExtension;
|
||||
|
||||
auto serializer = [](AZStd::vector<uint8_t>& output, const ProcessedObjectStore& object) -> bool
|
||||
auto serializer = [serializationFormat](AZStd::vector<uint8_t>& output, const ProcessedObjectStore& object) -> bool
|
||||
{
|
||||
AZ::IO::ByteContainerStream stream(&output);
|
||||
return AZ::Utils::SaveObjectToStream(stream, AZ::DataStream::StreamType::ST_BINARY,
|
||||
AZStd::any_cast<void>(&object.GetObject()), object.GetObject().type());
|
||||
auto& asset = object.GetAsset();
|
||||
return AZ::Utils::SaveObjectToStream(stream, serializationFormat, &asset, asset.GetType());
|
||||
};
|
||||
|
||||
auto spawnable = SpawnableUtils::CreateSpawnable(prefab);
|
||||
SpawnableUtils::SortEntitiesByTransformHierarchy(spawnable);
|
||||
AZStd::any spawnableAny(AZStd::move(spawnable));
|
||||
auto&& [object, spawnable] = ProcessedObjectStore::Create<AzFramework::Spawnable>(
|
||||
AZStd::move(uniqueName), context.GetSourceUuid(), AZStd::move(serializer));
|
||||
AZ_Assert(spawnable, "Failed to create a new spawnable.");
|
||||
|
||||
context.GetProcessedObjects().emplace_back(AZStd::move(uniqueName), AZStd::move(spawnableAny),
|
||||
AZStd::move(serializer), AZ::AzTypeInfo<AzFramework::Spawnable>::Uuid());
|
||||
bool result = SpawnableUtils::CreateSpawnable(*spawnable, prefab);
|
||||
if (result)
|
||||
{
|
||||
AzFramework::Spawnable::EntityList& entities = spawnable->GetEntities();
|
||||
for (auto it = entities.begin(); it != entities.end(); )
|
||||
{
|
||||
(*it)->InvalidateDependencies();
|
||||
AZ::Entity::DependencySortOutcome evaluation = (*it)->EvaluateDependenciesGetDetails();
|
||||
if (evaluation.IsSuccess())
|
||||
{
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Prefabs", false, "Entity '%s' %s cannot be activated for the following reason: %s",
|
||||
(*it)->GetName().c_str(), (*it)->GetId().ToString().c_str(), evaluation.GetError().m_message.c_str());
|
||||
it = entities.erase(it);
|
||||
}
|
||||
}
|
||||
SpawnableUtils::SortEntitiesByTransformHierarchy(*spawnable);
|
||||
context.GetProcessedObjects().push_back(AZStd::move(object));
|
||||
|
||||
context.RemovePrefab(prefabName);
|
||||
context.RemovePrefab(prefabName);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Prefabs", false, "Failed to convert prefab '%.*s' to a spawnable.", AZ_STRING_ARG(prefabName));
|
||||
context.ErrorEncountered();
|
||||
}
|
||||
}
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
+17
-1
@@ -30,6 +30,13 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
AZ_RTTI(AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor,
|
||||
"{F71E2FBA-22ED-44C7-B4C8-D2CF4B2C7B97}", PrefabProcessor);
|
||||
|
||||
//! The format the remaining spawnables are going to be stored in.
|
||||
enum class SerializationFormats
|
||||
{
|
||||
Binary, //!< Binary is generally preferable for performance.
|
||||
Text //!< Store in text format which is usually slower but helps with debugging.
|
||||
};
|
||||
|
||||
~PrefabCatchmentProcessor() override = default;
|
||||
|
||||
void Process(PrefabProcessorContext& context) override;
|
||||
@@ -37,6 +44,15 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
protected:
|
||||
static void ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab);
|
||||
static void ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab,
|
||||
AZ::DataStream::StreamType serializationFormat);
|
||||
|
||||
SerializationFormats m_serializationFormat{ SerializationFormats::Binary };
|
||||
};
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor::SerializationFormats,
|
||||
"{0FBE2482-B514-4256-8716-EA3ECDF8CD49}");
|
||||
}
|
||||
|
||||
+49
-1
@@ -25,7 +25,30 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
auto registry = AZ::SettingsRegistry::Get();
|
||||
AZ_Assert(registry, "PrefabConversionPipeline is created before the Settings Registry is available.");
|
||||
return registry->GetObject(m_processors, registryKey);
|
||||
bool result = registry->GetObject(m_processors, registryKey);
|
||||
if (!result)
|
||||
{
|
||||
m_processors.clear();
|
||||
}
|
||||
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
|
||||
|
||||
if (serializeContext)
|
||||
{
|
||||
m_fingerprint = CalculateProcessorFingerprint(serializeContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("PrefabConversionPipeline", false, "Failed to get serialization context");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PrefabConversionPipeline::IsLoaded() const
|
||||
{
|
||||
return !m_processors.empty();
|
||||
}
|
||||
|
||||
void PrefabConversionPipeline::ProcessPrefab(PrefabProcessorContext& context)
|
||||
@@ -35,6 +58,26 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
processor->Process(context);
|
||||
}
|
||||
}
|
||||
size_t PrefabConversionPipeline::CalculateProcessorFingerprint(AZ::SerializeContext* context)
|
||||
{
|
||||
size_t fingerprint = 0;
|
||||
|
||||
for (const auto& processor : m_processors)
|
||||
{
|
||||
const AZ::SerializeContext::ClassData* classData = context->FindClassData(processor->RTTI_GetType());
|
||||
|
||||
if (!classData)
|
||||
{
|
||||
AZ_Warning("PrefabConversionPipeline", false, "Class data for processor type %s not found. Cannot get version for fingerprinting", processor->RTTI_GetType().ToString<AZStd::string>().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
AZStd::hash_combine(fingerprint, processor->RTTI_GetType());
|
||||
AZStd::hash_combine(fingerprint, classData->m_version);
|
||||
}
|
||||
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
void PrefabConversionPipeline::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
@@ -45,4 +88,9 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
serializeContext->RegisterGenericType<PrefabProcessorListEntry>();
|
||||
}
|
||||
}
|
||||
|
||||
size_t PrefabConversionPipeline::GetFingerprint() const
|
||||
{
|
||||
return m_fingerprint;
|
||||
}
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
+7
-1
@@ -31,12 +31,18 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
using PrefabProcessorList = AZStd::vector<PrefabProcessorListEntry>;
|
||||
|
||||
bool LoadStackProfile(AZStd::string_view stackProfile);
|
||||
bool IsLoaded() const;
|
||||
|
||||
void ProcessPrefab(PrefabProcessorContext& context);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
size_t GetFingerprint() const;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
private:
|
||||
size_t CalculateProcessorFingerprint(AZ::SerializeContext* context);
|
||||
|
||||
PrefabProcessorList m_processors;
|
||||
size_t m_fingerprint{};
|
||||
};
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
+23
@@ -14,6 +14,10 @@
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
PrefabProcessorContext::PrefabProcessorContext(const AZ::Uuid& sourceUuid)
|
||||
: m_sourceUuid(sourceUuid)
|
||||
{}
|
||||
|
||||
bool PrefabProcessorContext::AddPrefab(AZStd::string prefabName, PrefabDom prefab)
|
||||
{
|
||||
auto result = m_prefabs.emplace(AZStd::move(prefabName), AZStd::move(prefab));
|
||||
@@ -76,9 +80,28 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
return m_products;
|
||||
}
|
||||
|
||||
void PrefabProcessorContext::SetPlatformTags(AZ::PlatformTagSet tags)
|
||||
{
|
||||
m_platformTags = AZStd::move(tags);
|
||||
}
|
||||
|
||||
const AZ::PlatformTagSet& PrefabProcessorContext::GetPlatformTags() const
|
||||
{
|
||||
return m_platformTags;
|
||||
}
|
||||
|
||||
const AZ::Uuid& PrefabProcessorContext::GetSourceUuid() const
|
||||
{
|
||||
return m_sourceUuid;
|
||||
}
|
||||
|
||||
bool PrefabProcessorContext::HasCompletedSuccessfully() const
|
||||
{
|
||||
return m_completedSuccessfully;
|
||||
}
|
||||
|
||||
void PrefabProcessorContext::ErrorEncountered()
|
||||
{
|
||||
m_completedSuccessfully = false;
|
||||
}
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
+8
@@ -33,6 +33,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
AZ_CLASS_ALLOCATOR(PrefabProcessorContext, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(PrefabProcessorContext, "{C7D77E3A-C544-486B-B774-7C82C38FE22F}");
|
||||
|
||||
explicit PrefabProcessorContext(const AZ::Uuid& sourceUuid);
|
||||
virtual ~PrefabProcessorContext() = default;
|
||||
|
||||
virtual bool AddPrefab(AZStd::string prefabName, PrefabDom prefab);
|
||||
@@ -44,7 +45,12 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
virtual ProcessedObjectStoreContainer& GetProcessedObjects();
|
||||
virtual const ProcessedObjectStoreContainer& GetProcessedObjects() const;
|
||||
|
||||
virtual void SetPlatformTags(AZ::PlatformTagSet tags);
|
||||
virtual const AZ::PlatformTagSet& GetPlatformTags() const;
|
||||
virtual const AZ::Uuid& GetSourceUuid() const;
|
||||
|
||||
virtual bool HasCompletedSuccessfully() const;
|
||||
virtual void ErrorEncountered();
|
||||
|
||||
protected:
|
||||
using NamedPrefabContainer = AZStd::unordered_map<AZStd::string, PrefabDom>;
|
||||
@@ -53,6 +59,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
ProcessedObjectStoreContainer m_products;
|
||||
AZStd::vector<AZStd::string> m_delayedDelete;
|
||||
AZ::PlatformTagSet m_platformTags;
|
||||
AZ::Uuid m_sourceUuid;
|
||||
bool m_isIterating{ false };
|
||||
bool m_completedSuccessfully{ true };
|
||||
};
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
+33
-24
@@ -11,25 +11,21 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzToolsFramework/Prefab/Spawnable/ProcesedObjectStore.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
ProcessedObjectStore::ProcessedObjectStore(AZStd::string uniqueId, AZStd::any object, SerializerFunction objectSerializer,
|
||||
AZ::Data::AssetType assetType)
|
||||
ProcessedObjectStore::ProcessedObjectStore(AZStd::string uniqueId, AZStd::unique_ptr<AZ::Data::AssetData> asset, SerializerFunction assetSerializer)
|
||||
: m_uniqueId(AZStd::move(uniqueId))
|
||||
, m_object(AZStd::move(object))
|
||||
, m_objectSerializer(AZStd::move(objectSerializer))
|
||||
, m_assetType(AZStd::move(assetType))
|
||||
{
|
||||
}
|
||||
, m_assetSerializer(AZStd::move(assetSerializer))
|
||||
, m_asset(AZStd::move(asset))
|
||||
{}
|
||||
|
||||
bool ProcessedObjectStore::Serialize(AZStd::vector<uint8_t>& output) const
|
||||
{
|
||||
if (m_objectSerializer)
|
||||
if (m_assetSerializer)
|
||||
{
|
||||
return m_objectSerializer(output, *this);
|
||||
return m_assetSerializer(output, *this);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -37,25 +33,38 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
}
|
||||
}
|
||||
|
||||
const AZStd::any& ProcessedObjectStore::GetObject() const
|
||||
bool ProcessedObjectStore::HasAsset() const
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
AZStd::any ProcessedObjectStore::ReleaseObject()
|
||||
{
|
||||
return AZStd::move(m_object);
|
||||
}
|
||||
|
||||
uint32_t ProcessedObjectStore::BuildSubId() const
|
||||
{
|
||||
AZ::Uuid subIdHash = AZ::Uuid::CreateData(m_uniqueId.data(), m_uniqueId.size());
|
||||
return azlossy_caster(subIdHash.GetHash());
|
||||
return m_asset != nullptr;
|
||||
}
|
||||
|
||||
const AZ::Data::AssetType& ProcessedObjectStore::GetAssetType() const
|
||||
{
|
||||
return m_assetType;
|
||||
AZ_Assert(m_asset, "Called GetAssetType on ProcessedObjectStore when there was no valid asset.");
|
||||
return m_asset->GetType();
|
||||
}
|
||||
|
||||
AZ::Data::AssetData& ProcessedObjectStore::GetAsset()
|
||||
{
|
||||
AZ_Assert(m_asset, "Called GetAsset on ProcessedObjectStore when there was no valid asset.");
|
||||
return *m_asset;
|
||||
}
|
||||
|
||||
const AZ::Data::AssetData& ProcessedObjectStore::GetAsset() const
|
||||
{
|
||||
AZ_Assert(m_asset, "Called GetAsset on ProcessedObjectStore when there was no valid asset.");
|
||||
return *m_asset;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> ProcessedObjectStore::ReleaseAsset()
|
||||
{
|
||||
return AZStd::move(m_asset);
|
||||
}
|
||||
|
||||
uint32_t ProcessedObjectStore::BuildSubId(AZStd::string_view id)
|
||||
{
|
||||
AZ::Uuid subIdHash = AZ::Uuid::CreateData(id.data(), id.size());
|
||||
return azlossy_caster(subIdHash.GetHash());
|
||||
}
|
||||
|
||||
const AZStd::string& ProcessedObjectStore::GetId() const
|
||||
|
||||
+34
-17
@@ -13,10 +13,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/typetraits/typetraits.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
{
|
||||
@@ -31,26 +32,42 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
//! Constructs a new instance.
|
||||
//! @param uniqueId A name for the object that's unique within the scope of the Prefab. This name will be used to generate a sub id for the product
|
||||
//! which requires that the name is stable between runs.
|
||||
//! @param object The object that generated during processing of a Prefab.
|
||||
//! @param objectSerializer The callback used to convert the provided object into a binary stream.
|
||||
//! @param assetType The asset type of the asset.
|
||||
//! @param storagePath The relative path where the asset will be stored if/when committed to disk.
|
||||
ProcessedObjectStore(AZStd::string uniqueId, AZStd::any object, SerializerFunction objectSerializer, AZ::Data::AssetType assetType);
|
||||
|
||||
//! which requires that the name to be stable between runs.
|
||||
//! @param sourceId The uuid for the source file.
|
||||
//! @param assetSerializer The callback used to convert the provided asset into a binary version.
|
||||
template<typename T>
|
||||
static AZStd::pair<ProcessedObjectStore, T*> Create(AZStd::string uniqueId, const AZ::Uuid& sourceId,
|
||||
SerializerFunction assetSerializer);
|
||||
|
||||
bool Serialize(AZStd::vector<uint8_t>& output) const;
|
||||
uint32_t BuildSubId() const;
|
||||
|
||||
const AZStd::any& GetObject() const;
|
||||
AZStd::any ReleaseObject();
|
||||
static uint32_t BuildSubId(AZStd::string_view id);
|
||||
|
||||
bool HasAsset() const;
|
||||
const AZ::Data::AssetType& GetAssetType() const;
|
||||
const AZ::Data::AssetData& GetAsset() const;
|
||||
AZ::Data::AssetData& GetAsset();
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> ReleaseAsset();
|
||||
|
||||
const AZStd::string& GetId() const;
|
||||
|
||||
private:
|
||||
AZStd::any m_object;
|
||||
SerializerFunction m_objectSerializer;
|
||||
AZ::Data::AssetType m_assetType;
|
||||
ProcessedObjectStore(AZStd::string uniqueId, AZStd::unique_ptr<AZ::Data::AssetData> asset, SerializerFunction assetSerializer);
|
||||
|
||||
SerializerFunction m_assetSerializer;
|
||||
AZStd::unique_ptr<AZ::Data::AssetData> m_asset;
|
||||
AZStd::string m_uniqueId;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
AZStd::pair<ProcessedObjectStore, T*> ProcessedObjectStore::Create(AZStd::string uniqueId, const AZ::Uuid& sourceId,
|
||||
SerializerFunction assetSerializer)
|
||||
{
|
||||
static_assert(AZStd::is_base_of_v<AZ::Data::AssetData, T>,
|
||||
"ProcessedObjectStore can only be created from a class that derives from AZ::Data::AssetData.");
|
||||
AZ::Data::AssetId assetId(sourceId, BuildSubId(uniqueId));
|
||||
auto instance = AZStd::make_unique<T>(assetId, AZ::Data::AssetData::AssetStatus::Ready);
|
||||
ProcessedObjectStore resultLeft(AZStd::move(uniqueId), AZStd::move(instance), AZStd::move(assetSerializer));
|
||||
T* resultRight = static_cast<T*>(&resultLeft.GetAsset());
|
||||
return AZStd::make_pair<ProcessedObjectStore, T*>(AZStd::move(resultLeft), resultRight);
|
||||
}
|
||||
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
|
||||
+26
-12
@@ -17,9 +17,10 @@
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
|
||||
namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
{
|
||||
@@ -27,22 +28,35 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom)
|
||||
{
|
||||
AzFramework::Spawnable spawnable;
|
||||
AZStd::unique_ptr<Instance> instance(aznew Instance());
|
||||
if (!Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*instance, prefabDom, false))
|
||||
[[maybe_unused]] bool result = CreateSpawnable(spawnable, prefabDom);
|
||||
AZ_Assert(result,
|
||||
"Failed to Load Prefab Instance from given Prefab DOM while Spawnable creation.");
|
||||
return spawnable;
|
||||
}
|
||||
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom)
|
||||
{
|
||||
Instance instance;
|
||||
if (Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(instance, prefabDom,
|
||||
Prefab::PrefabDomUtils::LoadInstanceFlags::AssignRandomEntityId)) // Always assign random entity ids because the spawnable is
|
||||
// going to be used to create clones of the entities.
|
||||
{
|
||||
AZ_Assert(false,
|
||||
"Failed to Load Prefab Instance from given Prefab DOM while Spawnable creation.");
|
||||
AzFramework::Spawnable::EntityList& entities = spawnable.GetEntities();
|
||||
if (instance.HasContainerEntity())
|
||||
{
|
||||
entities.emplace_back(AZStd::move(instance.DetachContainerEntity()));
|
||||
}
|
||||
instance.DetachNestedEntities(
|
||||
[&entities](AZStd::unique_ptr<AZ::Entity> entity)
|
||||
{
|
||||
entities.emplace_back(AZStd::move(entity));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AzFramework::Spawnable::EntityList& entities = spawnable.GetEntities();
|
||||
instance->DetachNestedEntities([&entities](AZStd::unique_ptr<AZ::Entity> entity)
|
||||
{
|
||||
entities.emplace_back(AZStd::move(entity));
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return spawnable;
|
||||
}
|
||||
|
||||
void OrganizeEntitiesForSorting(
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
{
|
||||
AzFramework::Spawnable CreateSpawnable(const PrefabDom& prefabDom);
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom);
|
||||
|
||||
void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable);
|
||||
} // namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
Reference in New Issue
Block a user