Merge branch 'main' into non-uniform-scale-trackview

This commit is contained in:
greerdv
2021-04-23 12:11:21 +01:00
613 changed files with 3851 additions and 4639 deletions
@@ -63,13 +63,13 @@ namespace AZ
static AssetTrackingImpl* GetSharedInstance();
static ThreadData& GetSharedThreadData();
using MasterAssets = AZStd::unordered_map<AssetTrackingId, AssetMasterInfo, AZStd::hash<AssetTrackingId>, AZStd::equal_to<AssetTrackingId>, AZStdAssetTrackingAllocator>;
using PrimaryAssets = AZStd::unordered_map<AssetTrackingId, AssetPrimaryInfo, AZStd::hash<AssetTrackingId>, AZStd::equal_to<AssetTrackingId>, AZStdAssetTrackingAllocator>;
using ThreadData = ThreadData;
using mutex_type = AZStd::mutex;
using lock_type = AZStd::lock_guard<mutex_type>;
mutex_type m_mutex;
MasterAssets m_masterAssets;
PrimaryAssets m_primaryAssets;
AssetTreeNodeBase* m_assetRoot = nullptr;
AssetAllocationTableBase* m_allocationTable = nullptr;
bool m_performingAnalysis = false;
@@ -118,7 +118,7 @@ namespace AZ
auto& threadData = GetSharedThreadData();
AssetTreeNodeBase* parentAsset = threadData.m_currentAssetStack.empty() ? nullptr : threadData.m_currentAssetStack.back();
AssetTreeNodeBase* childAsset;
AssetMasterInfo* assetMasterInfo;
AssetPrimaryInfo* assetPrimaryInfo;
if (!parentAsset)
{
@@ -128,22 +128,22 @@ namespace AZ
{
lock_type lock(m_mutex);
// Locate or create the master record for this asset
auto masterItr = m_masterAssets.find(assetId);
// Locate or create the primary record for this asset
auto primaryItr = m_primaryAssets.find(assetId);
if (masterItr != m_masterAssets.end())
if (primaryItr != m_primaryAssets.end())
{
assetMasterInfo = &masterItr->second;
assetPrimaryInfo = &primaryItr->second;
}
else
{
auto insertResult = m_masterAssets.emplace(assetId, AssetMasterInfo());
assetMasterInfo = &insertResult.first->second;
assetMasterInfo->m_id = &insertResult.first->first;
auto insertResult = m_primaryAssets.emplace(assetId, AssetPrimaryInfo());
assetPrimaryInfo = &insertResult.first->second;
assetPrimaryInfo->m_id = &insertResult.first->first;
}
// Add this asset to the stack for this thread's context
childAsset = parentAsset->FindOrAddChild(assetId, assetMasterInfo);
childAsset = parentAsset->FindOrAddChild(assetId, assetPrimaryInfo);
}
threadData.m_currentAssetStack.push_back(childAsset);
@@ -304,7 +304,7 @@ namespace AZ
char* pos = buffer;
for (auto itr = assetStack.rbegin(); itr != assetStack.rend(); ++itr)
{
pos += azsnprintf(pos, BUFFER_SIZE - (pos - buffer), "%s\n", (*itr)->GetAssetMasterInfo()->m_id->m_id.c_str());
pos += azsnprintf(pos, BUFFER_SIZE - (pos - buffer), "%s\n", (*itr)->GetAssetPrimaryInfo()->m_id->m_id.c_str());
if (pos >= buffer + BUFFER_SIZE)
{
@@ -79,9 +79,9 @@ namespace AZ
AssetTrackingString m_id;
};
// Master information about an asset.
// Primary information about an asset.
// Currently just contains the ID of the asset, but in the future may carry additional information about that asset (such as where in code it was initialized).
struct AssetMasterInfo
struct AssetPrimaryInfo
{
const AssetTrackingId* m_id;
};
@@ -90,8 +90,8 @@ namespace AZ
class AssetTreeNodeBase
{
public:
virtual const AssetMasterInfo* GetAssetMasterInfo() const = 0;
virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetMasterInfo* info) = 0;
virtual const AssetPrimaryInfo* GetAssetPrimaryInfo() const = 0;
virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) = 0;
};
// Base class for an asset tree. Implemented by the template AssetTree<>.
@@ -29,18 +29,18 @@ namespace AZ
class AssetTreeNode : public AssetTreeNodeBase
{
public:
AssetTreeNode(const AssetMasterInfo* masterInfo = nullptr, AssetTreeNode* parent = nullptr) :
m_masterInfo(masterInfo),
AssetTreeNode(const AssetPrimaryInfo* primaryInfo = nullptr, AssetTreeNode* parent = nullptr) :
m_primaryinfo(primaryInfo),
m_parent(parent)
{
}
const AssetMasterInfo* GetAssetMasterInfo() const override
const AssetPrimaryInfo* GetAssetPrimaryInfo() const override
{
return m_masterInfo;
return m_primaryinfo;
}
AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetMasterInfo* info) override
AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) override
{
AssetTreeNodeBase* result = nullptr;
auto childItr = m_children.find(id);
@@ -61,7 +61,7 @@ namespace AZ
using AssetMap = AssetTrackingMap<AssetTrackingId, AssetTreeNode>;
const AssetMasterInfo* m_masterInfo;
const AssetPrimaryInfo* m_primaryinfo;
AssetTreeNode* m_parent;
AssetMap m_children;
AssetDataT m_data;
+9 -2
View File
@@ -70,6 +70,7 @@ namespace AZ
static const char* logVerbosityUID = "sys_LogLevel";
static const int assertLevel_log = 1;
static const int assertLevel_nativeUI = 2;
static const int assertLevel_crash = 3;
static const int logLevel_errorWarning = 1;
static const int logLevel_full = 2;
static AZ::EnvironmentVariable<AZStd::unordered_set<size_t>> g_ignoredAsserts;
@@ -289,8 +290,8 @@ namespace AZ
}
#if AZ_ENABLE_TRACE_ASSERTS
//display native UI dialogs at verbosity level 2 or higher
if (currentLevel >= assertLevel_nativeUI)
//display native UI dialogs at verbosity level 2
if (currentLevel == assertLevel_nativeUI)
{
AZ::NativeUI::AssertAction buttonResult;
EBUS_EVENT_RESULT(buttonResult, AZ::NativeUI::NativeUIRequestBus, DisplayAssertDialog, dialogBoxText);
@@ -314,7 +315,13 @@ namespace AZ
break;
}
}
else
#endif //AZ_ENABLE_TRACE_ASSERTS
// Crash the application directly at assert level 3
if (currentLevel >= assertLevel_crash)
{
AZ_Crash();
}
}
g_alreadyHandlingAssertOrFatal = false;
}
+29 -2
View File
@@ -146,8 +146,8 @@ namespace AZ
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("GetTranslated", &Aabb::GetTranslated)
->Method("GetSurfaceArea", &Aabb::GetSurfaceArea)
->Method("GetTransformedObb", &Aabb::GetTransformedObb)
->Method("GetTransformedAabb", &Aabb::GetTransformedAabb)
->Method("GetTransformedObb", static_cast<Obb(Aabb::*)(const Transform&) const>(&Aabb::GetTransformedObb))
->Method("GetTransformedAabb", static_cast<Aabb(Aabb::*)(const Transform&) const>(&Aabb::GetTransformedAabb))
->Method("ApplyTransform", &Aabb::ApplyTransform)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("Clone", [](const Aabb& rhs) -> Aabb { return rhs; })
@@ -195,6 +195,20 @@ namespace AZ
}
Obb Aabb::GetTransformedObb(const Matrix3x4& matrix3x4) const
{
Matrix3x4 matrixNoScale = matrix3x4;
const AZ::Vector3 scale = matrixNoScale.ExtractScale();
const AZ::Quaternion rotation = AZ::Quaternion::CreateFromMatrix3x4(matrixNoScale);
return Obb::CreateFromPositionRotationAndHalfLengths(
matrix3x4 * GetCenter(),
rotation,
0.5f * scale * GetExtents()
);
}
void Aabb::ApplyTransform(const Transform& transform)
{
Vector3 a, b, axisCoeffs;
@@ -224,4 +238,17 @@ namespace AZ
m_min = newMin;
m_max = newMax;
}
void Aabb::ApplyMatrix3x4(const Matrix3x4& matrix3x4)
{
const AZ::Vector3 extents = GetExtents();
const AZ::Vector3 center = matrix3x4 * GetCenter();
AZ::Vector3 newHalfExtents(
0.5f * matrix3x4.GetRowAsVector3(0).GetAbs().Dot(extents),
0.5f * matrix3x4.GetRowAsVector3(1).GetAbs().Dot(extents),
0.5f * matrix3x4.GetRowAsVector3(2).GetAbs().Dot(extents));
m_min = center - newHalfExtents;
m_max = center + newHalfExtents;
}
}
+12 -2
View File
@@ -129,11 +129,21 @@ namespace AZ
void ApplyTransform(const Transform& transform);
void ApplyMatrix3x4(const Matrix3x4& matrix3x4);
void MultiplyByScale(const Vector3& scale);
//! Transforms an Aabb and returns the resulting Obb.
class Obb GetTransformedObb(const Transform& transform) const;
[[nodiscard]] Obb GetTransformedObb(const Transform& transform) const;
//! Transforms an Aabb and returns the resulting Obb.
[[nodiscard]] Obb GetTransformedObb(const Matrix3x4& matrix3x4) const;
//! Returns a new AABB containing the transformed AABB.
Aabb GetTransformedAabb(const Transform& transform) const;
[[nodiscard]] Aabb GetTransformedAabb(const Transform& transform) const;
//! Returns a new AABB containing the transformed AABB.
[[nodiscard]] Aabb GetTransformedAabb(const Matrix3x4& matrix3x4) const;
//! Checks if this aabb is equal to another within a floating point tolerance.
bool IsClose(const Aabb& rhs, float tolerance = Constants::Tolerance) const;
@@ -292,6 +292,14 @@ namespace AZ
}
AZ_MATH_INLINE void Aabb::MultiplyByScale(const Vector3& scale)
{
m_min *= scale;
m_max *= scale;
AZ_MATH_ASSERT(IsValid(), "Min must be less than Max");
}
AZ_MATH_INLINE Aabb Aabb::GetTransformedAabb(const Transform& transform) const
{
Aabb aabb = Aabb::CreateFromMinMax(m_min, m_max);
@@ -300,6 +308,14 @@ namespace AZ
}
AZ_MATH_INLINE Aabb Aabb::GetTransformedAabb(const Matrix3x4& matrix3x4) const
{
Aabb aabb = Aabb::CreateFromMinMax(m_min, m_max);
aabb.ApplyMatrix3x4(matrix3x4);
return aabb;
}
AZ_MATH_INLINE bool Aabb::IsClose(const Aabb& rhs, float tolerance) const
{
return m_min.IsClose(rhs.m_min, tolerance) && m_max.IsClose(rhs.m_max, tolerance);
@@ -105,7 +105,7 @@ namespace UnitTest
EXPECT_EQ(&rootAsset, &m_env->m_tree.GetRoot());
ASSERT_NE(itr, rootAsset.m_children.end());
EXPECT_EQ(itr->second.m_masterInfo->m_id->m_id, "TestScopedAllocation.1");
EXPECT_EQ(itr->second.m_primaryinfo->m_id->m_id, "TestScopedAllocation.1");
EXPECT_EQ(&itr->second, m_env->m_table.FindAllocation(TEST_POINTER));
@@ -15,6 +15,7 @@
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Math/MathTestHelpers.h>
using namespace AZ;
@@ -385,4 +386,77 @@ namespace UnitTest
EXPECT_TRUE(aabb.GetMin().IsClose(transAabb.GetMin()));
EXPECT_TRUE(aabb.GetMax().IsClose(transAabb.GetMax()));
}
TEST(MATH_AabbTransform, GetTransformedObbMatrix3x4)
{
Vector3 min(-1.0f, -2.0f, -3.0f);
Vector3 max(4.0f, 3.0f, 2.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Quaternion rotation(0.46f, 0.26f, 0.58f, 0.62f);
Vector3 translation(5.0f, 7.0f, 9.0f);
Matrix3x4 matrix3x4 = Matrix3x4::CreateFromQuaternionAndTranslation(rotation, translation);
matrix3x4.MultiplyByScale(Vector3(0.5f, 1.5f, 2.0f));
Obb obb = aabb.GetTransformedObb(matrix3x4);
EXPECT_THAT(obb.GetRotation(), IsClose(rotation));
EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(1.25f, 3.75f, 5.0f)));
EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(3.928f, 7.9156f, 9.3708f)));
}
TEST(MATH_AabbTransform, GetTransformedAabbMatrix3x4)
{
Vector3 min(2.0f, 3.0f, 5.0f);
Vector3 max(6.0f, 5.0f, 11.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Quaternion rotation(0.34f, 0.46f, 0.58f, 0.58f);
Vector3 translation(-3.0f, -4.0f, -5.0f);
Matrix3x4 matrix3x4 = Matrix3x4::CreateFromQuaternionAndTranslation(rotation, translation);
matrix3x4.MultiplyByScale(Vector3(1.2f, 0.8f, 2.0f));
Aabb transformedAabb = aabb.GetTransformedAabb(matrix3x4);
EXPECT_THAT(transformedAabb.GetMin(), IsClose(Vector3(4.1488f, -0.01216f, -0.31904f)));
EXPECT_THAT(transformedAabb.GetMax(), IsClose(Vector3(16.3216f, 6.54272f, 5.98112f)));
}
TEST(MATH_AabbTransform, GetTransformedObbFitsInsideTransformedAabb)
{
Vector3 min(4.0f, 3.0f, 1.0f);
Vector3 max(7.0f, 6.0f, 8.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Quaternion rotation(0.40f, 0.40f, 0.64f, 0.52f);
Vector3 translation(-2.0f, 4.0f, -3.0f);
Matrix3x4 matrix3x4 = Matrix3x4::CreateFromQuaternionAndTranslation(rotation, translation);
matrix3x4.MultiplyByScale(Vector3(2.2f, 0.6f, 1.4f));
Aabb transformedAabb = aabb.GetTransformedAabb(matrix3x4);
Obb transformedObb = aabb.GetTransformedObb(matrix3x4);
Aabb aabbContainingTransformedObb = Aabb::CreateFromObb(transformedObb);
EXPECT_THAT(transformedAabb.GetMin(), IsClose(aabbContainingTransformedObb.GetMin()));
EXPECT_THAT(transformedAabb.GetMax(), IsClose(aabbContainingTransformedObb.GetMax()));
}
TEST(MATH_AabbTransform, MultiplyByScale)
{
Vector3 min(2.0f, 6.0f, 8.0f);
Vector3 max(6.0f, 9.0f, 10.0f);
Aabb aabb = Aabb::CreateFromMinMax(min, max);
Vector3 scale(0.5f, 2.0f, 1.5f);
aabb.MultiplyByScale(scale);
EXPECT_THAT(aabb.GetMin(), IsClose(Vector3(1.0f, 12.0f, 12.0f)));
EXPECT_THAT(aabb.GetMax(), IsClose(Vector3(3.0f, 18.0f, 15.0f)));
}
}
@@ -29,6 +29,20 @@ namespace AzFramework::AssetSystem::Platform
bool LaunchAssetProcessor(AZStd::string_view executableDirectory, AZStd::string_view engineRoot,
AZStd::string_view projectPath)
{
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
pid_t firstChildPid = fork();
if (firstChildPid == 0)
{
@@ -47,9 +61,6 @@ namespace AzFramework::AssetSystem::Platform
pid_t secondChildPid = fork();
if (secondChildPid == 0)
{
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor";
AZStd::array args {
assetProcessorPath.c_str(), assetProcessorPath.c_str(), "--start-hidden",
static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), static_cast<const char*>(nullptr)
@@ -11,6 +11,7 @@
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <sys/types.h>
@@ -20,6 +21,7 @@ namespace AzFramework::AssetSystem::Platform
{
void AllowAssetProcessorToForeground()
{}
bool LaunchAssetProcessor(AZStd::string_view executableDirectory, AZStd::string_view engineRoot,
AZStd::string_view projectPath)
{
@@ -29,6 +31,17 @@ namespace AzFramework::AssetSystem::Platform
assetProcessorPath /= "../../../AssetProcessor.app";
assetProcessorPath = assetProcessorPath.LexicallyNormal();
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.app";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"(open -g "%s" --args --start-hidden)", assetProcessorPath.c_str());
// Add the engine path to the launch command if not empty
if (!engineRoot.empty())
@@ -12,6 +12,7 @@
#include <AzCore/PlatformIncl.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <Psapi.h>
@@ -67,6 +68,17 @@ namespace AzFramework::AssetSystem::Platform
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor.exe";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.exe";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"("%s" --start-hidden)", assetProcessorPath.c_str());
// Add the engine path to the launch command if not empty
@@ -279,7 +279,7 @@ namespace AzToolsFramework
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder)
{
AZStd::unique_ptr<Prefab::Instance> createdPrefabInstance =
m_prefabSystemComponent->CreatePrefab(entities, AZStd::move(nestedPrefabInstances), filePath);
m_prefabSystemComponent->CreatePrefab(entities, AZStd::move(nestedPrefabInstances), filePath, nullptr, false);
if (createdPrefabInstance)
{
@@ -321,7 +321,6 @@ namespace AzToolsFramework
removedNestedInstance = AZStd::move(nestedInstanceIterator->second);
removedNestedInstance->m_parent = nullptr;
removedNestedInstance->m_alias = InstanceAlias();
m_nestedInstances.erase(instanceAlias);
}
@@ -396,6 +395,14 @@ namespace AzToolsFramework
}
}
void Instance::GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback)
{
for (auto& [instanceAlias, instance] : m_nestedInstances)
{
callback(instance);
}
}
void Instance::GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback)
{
for (auto& [entityAlias, entity] : m_entities)
@@ -114,6 +114,7 @@ namespace AzToolsFramework
void GetConstEntities(const AZStd::function<bool(const AZ::Entity&)>& callback);
void GetNestedEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
void GetEntities(const AZStd::function<bool(AZStd::unique_ptr<AZ::Entity>&)>& callback);
void GetNestedInstances(const AZStd::function<void(AZStd::unique_ptr<Instance>&)>& callback);
/**
* Gets the alias for a given EnitityId in the Instance DOM.
@@ -101,6 +101,10 @@ namespace AzToolsFramework
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
}
PrefabUndoHelpers::UpdatePrefabInstance(
commonRootEntityOwningInstance->get(), "Update prefab instance", commonRootInstanceDomBeforeCreate,
undoBatch.GetUndoBatch());
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (!prefabEditorEntityOwnershipInterface)
{
@@ -118,13 +122,21 @@ namespace AzToolsFramework
"(A null instance is returned)."));
}
PrefabUndoHelpers::UpdatePrefabInstance(
commonRootEntityOwningInstance->get(), "Update prefab instance", commonRootInstanceDomBeforeCreate, undoBatch.GetUndoBatch());
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
instanceToCreate->get().GetNestedInstances([&](AZStd::unique_ptr<Instance>& nestedInstance) {
AZ_Assert(nestedInstance, "Invalid nested instance found in the new prefab created.");
EntityOptionalReference nestedInstanceContainerEntity = nestedInstance->GetContainerEntity();
AZ_Assert(
nestedInstanceContainerEntity, "Invalid container entity found for the nested instance used in prefab creation.");
CreateLink(
{&nestedInstanceContainerEntity->get()}, *nestedInstance, instanceToCreate->get().GetTemplateId(),
undoBatch.GetUndoBatch(), containerEntityId);
});
CreateLink(
topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(),
commonRootEntityId);
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
// Change top level entities to be parented to the container entity
// Mark them as dirty so this change is correctly applied to the template
@@ -225,19 +237,7 @@ namespace AzToolsFramework
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
{
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
if (!prefabSystemComponentInterface)
{
AZ_Assert(
false,
"Prefab - PrefabPublicHandler - "
"Prefab System Component Interface could not be found. "
"Check that it is being correctly initialized.");
return AZ::Failure(
AZStd::string("SavePrefab - Internal error (Prefab System Component Interface could not be found)."));
}
auto templateId = prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
if (templateId == InvalidTemplateId)
{
@@ -438,26 +438,14 @@ namespace AzToolsFramework
PrefabRequestResult PrefabPublicHandler::HasUnsavedChanges(AZ::IO::Path prefabFilePath) const
{
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
if (!prefabSystemComponentInterface)
{
AZ_Assert(
false,
"Prefab - PrefabPublicHandler - "
"Prefab System Component Interface could not be found. "
"Check that it is being correctly initialized.");
return AZ::Failure(
AZStd::string("HasUnsavedChanges - Internal error (Prefab System Component Interface could not be found)."));
}
auto templateId = prefabSystemComponentInterface->GetTemplateIdFromFilePath(prefabFilePath.c_str());
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(prefabFilePath.c_str());
if (templateId == InvalidTemplateId)
{
return AZ::Failure(AZStd::string("HasUnsavedChanges - Path error. Path could be invalid, or the prefab may not be loaded in this level."));
}
return AZ::Success(prefabSystemComponentInterface->IsTemplateDirty(templateId));
return AZ::Success(m_prefabSystemComponentInterface->IsTemplateDirty(templateId));
}
PrefabOperationResult PrefabPublicHandler::DeleteEntitiesInInstance(const EntityIdList& entityIds)
@@ -91,8 +91,9 @@ namespace AzToolsFramework
m_instanceUpdateExecutor.UpdateTemplateInstancesInQueue();
}
AZStd::unique_ptr<Instance> PrefabSystemComponent::CreatePrefab(const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity)
AZStd::unique_ptr<Instance> PrefabSystemComponent::CreatePrefab(
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity, bool shouldCreateLinks)
{
AZ::IO::Path relativeFilePath = m_prefabLoader.GetRelativePathToProject(filePath);
if (GetTemplateIdFromFilePath(relativeFilePath) != InvalidTemplateId)
@@ -123,7 +124,7 @@ namespace AzToolsFramework
newInstance->SetTemplateSourcePath(relativeFilePath);
newInstance->SetContainerEntityName(relativeFilePath.Stem().Native());
TemplateId newTemplateId = CreateTemplateFromInstance(*newInstance);
TemplateId newTemplateId = CreateTemplateFromInstance(*newInstance, shouldCreateLinks);
if (newTemplateId == InvalidTemplateId)
{
AZ_Error("Prefab", false,
@@ -289,7 +290,7 @@ namespace AzToolsFramework
return newInstance;
}
TemplateId PrefabSystemComponent::CreateTemplateFromInstance(Instance& instance)
TemplateId PrefabSystemComponent::CreateTemplateFromInstance(Instance& instance, bool shouldCreateLinks)
{
// We will register the template to match the path the instance has
const AZ::IO::Path& templateSourcePath = instance.GetTemplateSourcePath();
@@ -323,14 +324,15 @@ namespace AzToolsFramework
return InvalidTemplateId;
}
if (!GenerateLinksForNewTemplate(newTemplateId, instance))
if (shouldCreateLinks)
{
// Clear new template and any links associated with it
RemoveTemplate(newTemplateId);
return InvalidTemplateId;
if (!GenerateLinksForNewTemplate(newTemplateId, instance))
{
// Clear new template and any links associated with it
RemoveTemplate(newTemplateId);
return InvalidTemplateId;
}
}
return newTemplateId;
}
@@ -187,17 +187,22 @@ namespace AzToolsFramework
* @param entities A vector of entities that will be used in the new instance. May be empty
* @param instances A vector of Prefab Instances that will be nested in the new instance, will be consumed and moved.
* May be empty
* @param filePath the path to associate the template of the new instance to
* @param filePath the path to associate the template of the new instance to.
* @param containerEntity The container entity for the prefab to be created. It will be created if a nullptr is provided.
* @param shouldCreateLinks The flag indicating if links should be created between the templates of the instance
* and its nested instances.
* @return A pointer to the newly created instance. nullptr on failure
*/
AZStd::unique_ptr<Instance> CreatePrefab(const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr) override;
AZStd::unique_ptr<Instance> CreatePrefab(
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume,
AZ::IO::PathView filePath, AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr,
bool ShouldCreateLinks = true) override;
PrefabDom& FindTemplateDom(TemplateId templateId) override;
/**
* Updates a template with the given updated DOM.
*
*
* @param templateId The id of the template to update.
* @param updatedDom The DOM to update the template with.
*/
@@ -260,9 +265,11 @@ namespace AzToolsFramework
/**
* Takes a prefab instance and generates a new Prefab Template
* along with any new Prefab Links representing any of the nested instances present
* @param instance The instance used to generate the new Template
* @param instance The instance used to generate the new Template.
* @param shouldCreateLinks The flag indicating if links should be created between the templates of the instance
* and its nested instances.
*/
TemplateId CreateTemplateFromInstance(Instance& instance);
TemplateId CreateTemplateFromInstance(Instance& instance, bool shouldCreateLinks);
/**
* Connect two templates with given link, and a nested instance value iterator
@@ -61,7 +61,7 @@ namespace AzToolsFramework
virtual AZStd::unique_ptr<Instance> InstantiatePrefab(const TemplateId& templateId) = 0;
virtual AZStd::unique_ptr<Instance> CreatePrefab(const AZStd::vector<AZ::Entity*>& entities,
AZStd::vector<AZStd::unique_ptr<Instance>>&& instancesToConsume, AZ::IO::PathView filePath,
AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr) = 0;
AZStd::unique_ptr<AZ::Entity> containerEntity = nullptr, bool ShouldCreateLinks = true) = 0;
};