Merge branch 'main' into non-uniform-scale-trackview
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
+14
-3
@@ -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)
|
||||
|
||||
+13
@@ -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
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user