From cff6fb97afe497647749ae6e9d82e010b0138089 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 12:49:41 -0800 Subject: [PATCH 01/42] Fix "expression result unused" warning This macro was expecting that parenthesis used in the macro would be removed during macro expansion, when they are not removed. The result was a function call like this: ```cpp AZ_Assert(g_SymGetSearchPath != 0, ("Can not load %s function!","SymGetSearchPath")); ``` The parenthesis cause the contents of the parenthsis to be evaluated first, and the result is an expression using the comma operator. The comma operator evaluates the left expression, discards the result, then evaluates the right expression, and returns that. So the above dropping the message, and just leaving: ```cpp AZ_Assert(g_SymGetSearchPath != 0, "SymGetSearchPath"); ``` Signed-off-by: Chris Burel --- .../Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index 90362a3ce8..688db347da 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -140,7 +140,7 @@ namespace AZ { SymRegisterCallback64_t g_SymRegisterCallback64; HMODULE g_dbgHelpDll; -#define LOAD_FUNCTION(A) { g_##A = (A##_t)GetProcAddress(g_dbgHelpDll, #A); AZ_Assert(g_##A != 0, ("Can not load %s function!",#A)); } +#define LOAD_FUNCTION(A) { g_##A = (A##_t)GetProcAddress(g_dbgHelpDll, #A); AZ_Assert(g_##A != 0, "Can not load %s function!",#A); } using namespace AZ::Debug; From b44c362af00ed2640be199658b94040572eb585e Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 12:50:56 -0800 Subject: [PATCH 02/42] Fix comparing an array in a conditional, which is always true Instead, check the intent of the original code, if the `szImg` string is not empty. Signed-off-by: Chris Burel --- .../Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index 688db347da..3969a1bf13 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -596,7 +596,7 @@ namespace AZ { result = GetLastError(); } ULONGLONG fileVersion = 0; - if (szImg != NULL) + if (szImg[0]) // !szImg.empty() { // try to retrieve the file-version: VS_FIXEDFILEINFO* fInfo = NULL; From 024cbdd2cd50a6ef3df5f5ce4726f0d58532fa5f Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 12:51:46 -0800 Subject: [PATCH 03/42] Remove unused `azSmyType` variable There's a lot of work done to set the value of this variable, but nothing read from it. Signed-off-by: Chris Burel --- .../AzCore/Debug/StackTracer_Windows.cpp | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index 3969a1bf13..a3f8b1e349 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -624,43 +624,6 @@ namespace AZ { } } - // Retrive some additional-infos about the module - IMAGEHLP_MODULE64 Module; - const char* szSymType = "-unknown-"; - if (GetModuleInfo(hProcess, baseAddr, &Module) != FALSE) - { - switch (Module.SymType) - { - case SymNone: - szSymType = "-nosymbols-"; - break; - case SymCoff: - szSymType = "COFF"; - break; - case SymCv: - szSymType = "CV"; - break; - case SymPdb: - szSymType = "PDB"; - break; - case SymExport: - szSymType = "-exported-"; - break; - case SymDeferred: - szSymType = "-deferred-"; - break; - case SymSym: - szSymType = "SYM"; - break; - case 8: //SymVirtual: - szSymType = "Virtual"; - break; - case 9: // SymDia: - szSymType = "DIA"; - break; - } - } - // find insert position if (g_moduleInfo.size() < g_moduleInfo.capacity()) { From 36487c15886dba229c295a9cb2fff6bea98ec1c5 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 12:57:09 -0800 Subject: [PATCH 04/42] Fix alignment of `CONTEXT` variable The previous code had the `alignas()` in the wrong place, it needs to be left of the typename. Furthermore, `CONTEXT` has a default alignment of 16, so using `alignas(8)` underaligns. Signed-off-by: Chris Burel --- .../Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index a3f8b1e349..0d3cc7e032 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -1036,7 +1036,7 @@ cleanup: } HANDLE hThread = nativeThread; - CONTEXT alignas(8) context; // Without this alignment the function randomly crashes in release. + alignas(alignof(CONTEXT)) CONTEXT context; // Without this alignment the function randomly crashes in release. context.ContextFlags = CONTEXT_ALL; GetThreadContext(hThread, &context); From 664403c5de6e995ab1de4d23e4041b36be8c2ae7 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:00:49 -0800 Subject: [PATCH 05/42] Mark benchmark state variables in for loops as unused in benchmarks Signed-off-by: Chris Burel --- Code/Framework/AzCore/Tests/AZStd/String.cpp | 36 ++-- .../AzCore/Tests/DOM/DomJsonBenchmarks.cpp | 18 +- .../AzCore/Tests/DOM/DomPathBenchmarks.cpp | 10 +- .../AzCore/Tests/DOM/DomValueBenchmarks.cpp | 18 +- .../AzCore/Tests/IO/Path/PathTests.cpp | 8 +- Code/Framework/AzCore/Tests/Jobs.cpp | 48 +++--- Code/Framework/AzCore/Tests/Math/CrcTests.cpp | 2 +- .../Tests/Math/FrustumPerformanceTests.cpp | 4 +- .../Tests/Math/Matrix3x3PerformanceTests.cpp | 96 +++++------ .../Tests/Math/Matrix3x4PerformanceTests.cpp | 158 +++++++++--------- .../Tests/Math/Matrix4x4PerformanceTests.cpp | 82 ++++----- .../AzCore/Tests/Math/ObbPerformanceTests.cpp | 38 ++--- .../Tests/Math/PlanePerformanceTests.cpp | 40 ++--- .../Tests/Math/QuaternionPerformanceTests.cpp | 108 ++++++------ .../ShapeIntersectionPerformanceTests.cpp | 10 +- .../Tests/Math/TransformPerformanceTests.cpp | 86 +++++----- .../Tests/Math/Vector2PerformanceTests.cpp | 86 +++++----- .../Tests/Math/Vector3PerformanceTests.cpp | 90 +++++----- .../Tests/Math/Vector4PerformanceTests.cpp | 86 +++++----- .../Tests/Memory/AllocatorBenchmarks.cpp | 6 +- .../IO/Streamer/StorageDriveTests_Windows.cpp | 2 +- Code/Framework/AzCore/Tests/TaskTests.cpp | 6 +- .../Tests/OctreePerformanceTests.cpp | 32 ++-- .../Benchmark/PrefabCreateBenchmarks.cpp | 8 +- .../Benchmark/PrefabInstantiateBenchmarks.cpp | 2 +- .../Prefab/Benchmark/PrefabLoadBenchmarks.cpp | 2 +- .../PrefabUpdateInstancesBenchmarks.cpp | 8 +- .../Spawnable/SpawnAllEntitiesBenchmarks.cpp | 6 +- .../Benchmark/SpawnableCreateBenchmarks.cpp | 2 +- .../Code/Tests/GradientSignalTestHelpers.cpp | 8 +- .../Benchmarks/PhysXCharactersBenchmarks.cpp | 6 +- .../PhysXCharactersRagdollBenchmarks.cpp | 4 +- .../Benchmarks/PhysXGenericBenchmarks.cpp | 2 +- .../Tests/Benchmarks/PhysXJointBenchmarks.cpp | 6 +- .../Benchmarks/PhysXRigidBodyBenchmarks.cpp | 6 +- .../Benchmarks/PhysXSceneQueryBenchmarks.cpp | 6 +- .../Code/Tests/SurfaceDataBenchmarks.cpp | 6 +- .../Code/Tests/TerrainSystemBenchmarks.cpp | 2 +- 38 files changed, 572 insertions(+), 572 deletions(-) diff --git a/Code/Framework/AzCore/Tests/AZStd/String.cpp b/Code/Framework/AzCore/Tests/AZStd/String.cpp index 50450a898c..f53a90047f 100644 --- a/Code/Framework/AzCore/Tests/AZStd/String.cpp +++ b/Code/Framework/AzCore/Tests/AZStd/String.cpp @@ -2537,7 +2537,7 @@ namespace Benchmark { AZStd::string test1{ "foo bar"}; AZStd::string test2{ "bar foo" }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { SwapStringViaPointerSizedSwaps(test1, test2); } @@ -2547,7 +2547,7 @@ namespace Benchmark { AZStd::string test1{ "The brown quick wolf jumped over the hyperactive cat" }; AZStd::string test2{ "The quick brown fox jumped over the lazy dog" }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { SwapStringViaPointerSizedSwaps(test1, test2); } @@ -2557,7 +2557,7 @@ namespace Benchmark { AZStd::string test1{ "foo bar" }; AZStd::string test2{ "bar foo" }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { SwapStringViaMemcpy(test1, test2); } @@ -2567,7 +2567,7 @@ namespace Benchmark { AZStd::string test1{ "The brown quick wolf jumped over the hyperactive cat" }; AZStd::string test2{ "The quick brown fox jumped over the lazy dog" }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { SwapStringViaMemcpy(test1, test2); } @@ -2584,7 +2584,7 @@ namespace Benchmark AZStd::string sourceString(state.range(0), 'a'); const char* sourceAddress = sourceString.c_str(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::string assignString; assignString.assign(sourceAddress); @@ -2600,7 +2600,7 @@ namespace Benchmark const char* sourceAddress = sourceString.c_str(); const size_t sourceSize = sourceString.size(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::string assignString; assignString.assign(sourceAddress, sourceSize); @@ -2616,7 +2616,7 @@ namespace Benchmark auto sourceBegin = sourceString.begin(); auto sourceEnd = sourceString.end(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::string assignString; assignString.assign(sourceBegin, sourceEnd); @@ -2631,7 +2631,7 @@ namespace Benchmark AZStd::string sourceString(state.range(0), 'a'); AZStd::string_view sourceView(sourceString); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::string assignString; assignString.assign(sourceView); @@ -2645,7 +2645,7 @@ namespace Benchmark { AZStd::string sourceString(state.range(0), 'a'); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::string assignString; assignString.assign(sourceString); @@ -2659,7 +2659,7 @@ namespace Benchmark { AZStd::string sourceString(state.range(0), 'a'); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::string assignString; assignString.assign(AZStd::move(sourceString)); @@ -2671,7 +2671,7 @@ namespace Benchmark BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_StringAssignFromSingleCharacter, AZStd::string)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::string assignString; assignString.assign(state.range(0), 'a'); @@ -2689,7 +2689,7 @@ namespace Benchmark AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); const char* sourceAddress = sourceString.c_str(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::fixed_string<1024> assignString; assignString.assign(sourceAddress); @@ -2705,7 +2705,7 @@ namespace Benchmark const char* sourceAddress = sourceString.c_str(); const size_t sourceSize = sourceString.size(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::fixed_string<1024> assignString; assignString.assign(sourceAddress, sourceSize); @@ -2721,7 +2721,7 @@ namespace Benchmark auto sourceBegin = sourceString.begin(); auto sourceEnd = sourceString.end(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::fixed_string<1024> assignString; assignString.assign(sourceBegin, sourceEnd); @@ -2736,7 +2736,7 @@ namespace Benchmark AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); AZStd::string_view sourceView(sourceString); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::fixed_string<1024> assignString; assignString.assign(sourceView); @@ -2750,7 +2750,7 @@ namespace Benchmark { AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::fixed_string<1024> assignString; assignString.assign(sourceString); @@ -2764,7 +2764,7 @@ namespace Benchmark { AZStd::fixed_string<1024> sourceString(state.range(0), 'a'); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::fixed_string<1024> assignString; assignString.assign(AZStd::move(sourceString)); @@ -2776,7 +2776,7 @@ namespace Benchmark BENCHMARK_TEMPLATE_DEFINE_F(StringTemplateBenchmarkFixture, BM_FixedStringAssignFromSingleCharacter, AZStd::fixed_string<1024>)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::fixed_string<1024> assignString; assignString.assign(state.range(0), 'a'); diff --git a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp index f84b60af07..65bd609e37 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomJsonBenchmarks.cpp @@ -29,7 +29,7 @@ namespace AZ::Dom::Benchmark AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); AZStd::string payloadCopy = serializedPayload; @@ -53,7 +53,7 @@ namespace AZ::Dom::Benchmark AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); AZStd::string payloadCopy = serializedPayload; @@ -77,7 +77,7 @@ namespace AZ::Dom::Benchmark AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { auto result = AZ::Dom::Json::WriteToRapidJsonDocument( [&](AZ::Dom::Visitor& visitor) @@ -97,7 +97,7 @@ namespace AZ::Dom::Benchmark AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { auto result = AZ::Dom::Utils::WriteToValue( [&](AZ::Dom::Visitor& visitor) @@ -117,7 +117,7 @@ namespace AZ::Dom::Benchmark AZ::Dom::JsonBackend backend; AZStd::string serializedPayload = GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { auto result = AZ::JsonSerializationUtils::ReadJsonString(serializedPayload); @@ -130,7 +130,7 @@ namespace AZ::Dom::Benchmark BENCHMARK_DEFINE_F(DomJsonBenchmark, RapidjsonMakeComplexObject)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { TakeAndDiscardWithoutTimingDtor(GenerateDomJsonBenchmarkPayload(state.range(0), state.range(1)), state); } @@ -152,7 +152,7 @@ namespace AZ::Dom::Benchmark document.GetAllocator()); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const AZStd::string& key : keys) { @@ -168,7 +168,7 @@ namespace AZ::Dom::Benchmark { rapidjson::Document original = GenerateDomJsonBenchmarkDocument(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { rapidjson::Document copy; copy.CopyFrom(original, copy.GetAllocator(), true); @@ -184,7 +184,7 @@ namespace AZ::Dom::Benchmark { rapidjson::Document original = GenerateDomJsonBenchmarkDocument(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { rapidjson::Document copy; copy.CopyFrom(original, copy.GetAllocator(), true); diff --git a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp index 4741900aa1..10c5fa1394 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp @@ -20,7 +20,7 @@ namespace AZ::Dom::Benchmark PathEntry end; end.SetEndOfArray(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { Path p; p /= entry1; @@ -40,7 +40,7 @@ namespace AZ::Dom::Benchmark PathEntry end; end.SetEndOfArray(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { Path p = Path() / entry1 / entry2 / 0 / end; } @@ -55,7 +55,7 @@ namespace AZ::Dom::Benchmark AZStd::string s; s.resize_no_construct(p.GetStringLength()); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { p.GetStringLength(); p.FormatString(s.data(), s.size()); @@ -69,7 +69,7 @@ namespace AZ::Dom::Benchmark { AZStd::string pathString = "/path/with/multiple/0/different/components/including-long-strings-like-this/65536/999/-"; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { Path p(pathString); benchmark::DoNotOptimize(p); @@ -86,7 +86,7 @@ namespace AZ::Dom::Benchmark PathEntry endOfArray; endOfArray.SetEndOfArray(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { name.IsEndOfArray(); index.IsEndOfArray(); diff --git a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp index 69d99eb12b..b73306f516 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomValueBenchmarks.cpp @@ -29,7 +29,7 @@ namespace AZ::Dom::Benchmark Value doubleValue(4.0); Value stringValue("foo", true); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { (intValue.GetType()); (boolValue.GetType()); @@ -118,7 +118,7 @@ namespace AZ::Dom::Benchmark value.GetInternalValue()); }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { (getTypeViaVisit(intValue)); (getTypeViaVisit(boolValue)); @@ -136,7 +136,7 @@ namespace AZ::Dom::Benchmark BENCHMARK_DEFINE_F(DomValueBenchmark, AzDomValueMakeComplexObject)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { TakeAndDiscardWithoutTimingDtor(GenerateDomBenchmarkPayload(state.range(0), state.range(1)), state); } @@ -149,7 +149,7 @@ namespace AZ::Dom::Benchmark { Value original = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { Value copy = original; benchmark::DoNotOptimize(copy); @@ -163,7 +163,7 @@ namespace AZ::Dom::Benchmark { Value original = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { Value copy = original; copy["entries"]["Key0"].ArrayPushBack(Value(42)); @@ -178,7 +178,7 @@ namespace AZ::Dom::Benchmark { Value original = GenerateDomBenchmarkPayload(state.range(0), state.range(1)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { Value copy = Utils::DeepCopy(original); TakeAndDiscardWithoutTimingDtor(AZStd::move(copy), state); @@ -199,7 +199,7 @@ namespace AZ::Dom::Benchmark value[key] = i; } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const AZ::Name& key : keys) { @@ -222,7 +222,7 @@ namespace AZ::Dom::Benchmark value[key] = i; } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const AZStd::string& key : keys) { @@ -245,7 +245,7 @@ namespace AZ::Dom::Benchmark value[key] = i; } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const AZStd::string& key : keys) { diff --git a/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp b/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp index cf239a0821..91620ae918 100644 --- a/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp +++ b/Code/Framework/AzCore/Tests/IO/Path/PathTests.cpp @@ -966,7 +966,7 @@ namespace Benchmark BENCHMARK_F(PathBenchmarkFixture, BM_PathAppendFixedPath)(benchmark::State& state) { AZ::IO::FixedMaxPath m_testPath{ "." }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const auto& appendPath : m_appendPaths) { @@ -977,7 +977,7 @@ namespace Benchmark BENCHMARK_F(PathBenchmarkFixture, BM_PathAppendAllocatingPath)(benchmark::State& state) { AZ::IO::Path m_testPath{ "." }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const auto& appendPath : m_appendPaths) { @@ -989,7 +989,7 @@ namespace Benchmark BENCHMARK_F(PathBenchmarkFixture, BM_StringFuncPathJoinFixedString)(benchmark::State& state) { AZStd::string m_testPath{ "." }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const auto& appendPath : m_appendPaths) { @@ -1000,7 +1000,7 @@ namespace Benchmark BENCHMARK_F(PathBenchmarkFixture, BM_StringFuncPathJoinAZStdString)(benchmark::State& state) { AZStd::string m_testPath{ "." }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (const auto& appendPath : m_appendPaths) { diff --git a/Code/Framework/AzCore/Tests/Jobs.cpp b/Code/Framework/AzCore/Tests/Jobs.cpp index 20c960535d..afe2d72acf 100644 --- a/Code/Framework/AzCore/Tests/Jobs.cpp +++ b/Code/Framework/AzCore/Tests/Jobs.cpp @@ -1741,7 +1741,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfLightWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(SMALL_NUMBER_OF_JOBS, LIGHT_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1749,7 +1749,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfLightWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(MEDIUM_NUMBER_OF_JOBS, LIGHT_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1757,7 +1757,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfLightWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(LARGE_NUMBER_OF_JOBS, LIGHT_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1765,7 +1765,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfMediumWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(SMALL_NUMBER_OF_JOBS, MEDIUM_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1773,7 +1773,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfMediumWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(MEDIUM_NUMBER_OF_JOBS, MEDIUM_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1781,7 +1781,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfMediumWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(LARGE_NUMBER_OF_JOBS, MEDIUM_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1789,7 +1789,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfHeavyWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(SMALL_NUMBER_OF_JOBS, HEAVY_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1797,7 +1797,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfHeavyWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(MEDIUM_NUMBER_OF_JOBS, HEAVY_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1805,7 +1805,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfHeavyWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithDefaultPriority(LARGE_NUMBER_OF_JOBS, HEAVY_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1813,7 +1813,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfRandomWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomDepthAndDefaultPriority(SMALL_NUMBER_OF_JOBS); } @@ -1821,7 +1821,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfRandomWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomDepthAndDefaultPriority(MEDIUM_NUMBER_OF_JOBS); } @@ -1829,7 +1829,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfRandomWeightJobsWithDefaultPriority)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomDepthAndDefaultPriority(LARGE_NUMBER_OF_JOBS); } @@ -1837,7 +1837,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfLightWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(SMALL_NUMBER_OF_JOBS, LIGHT_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1845,7 +1845,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfLightWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(MEDIUM_NUMBER_OF_JOBS, LIGHT_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1853,7 +1853,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfLightWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(LARGE_NUMBER_OF_JOBS, LIGHT_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1861,7 +1861,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfMediumWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(SMALL_NUMBER_OF_JOBS, MEDIUM_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1869,7 +1869,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfMediumWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(MEDIUM_NUMBER_OF_JOBS, MEDIUM_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1877,7 +1877,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfMediumWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(LARGE_NUMBER_OF_JOBS, MEDIUM_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1885,7 +1885,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfHeavyWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(SMALL_NUMBER_OF_JOBS, HEAVY_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1893,7 +1893,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfHeavyWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(MEDIUM_NUMBER_OF_JOBS, HEAVY_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1901,7 +1901,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfHeavyWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomPriority(LARGE_NUMBER_OF_JOBS, HEAVY_WEIGHT_JOB_CALCULATE_PI_DEPTH); } @@ -1909,7 +1909,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunSmallNumberOfRandomWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomDepthAndRandomPriority(SMALL_NUMBER_OF_JOBS); } @@ -1917,7 +1917,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunMediumNumberOfRandomWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomDepthAndRandomPriority(MEDIUM_NUMBER_OF_JOBS); } @@ -1925,7 +1925,7 @@ namespace Benchmark BENCHMARK_F(JobBenchmarkFixture, RunLargeNumberOfRandomWeightJobsWithRandomPriorities)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { RunMultipleCalculatePiJobsWithRandomDepthAndRandomPriority(LARGE_NUMBER_OF_JOBS); } diff --git a/Code/Framework/AzCore/Tests/Math/CrcTests.cpp b/Code/Framework/AzCore/Tests/Math/CrcTests.cpp index 0255c1ad6d..f152744486 100644 --- a/Code/Framework/AzCore/Tests/Math/CrcTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/CrcTests.cpp @@ -54,7 +54,7 @@ namespace Benchmark { // Runtime performance is not actually being measured by this test. // This function only exist to calculate AZ::Crc32 values at compile time - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { [[maybe_unused]] constexpr auto resultArray = Crc32Internal::GenerateTestCrc32Values(); } diff --git a/Code/Framework/AzCore/Tests/Math/FrustumPerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/FrustumPerformanceTests.cpp index e26d896e5a..7e753fffb9 100644 --- a/Code/Framework/AzCore/Tests/Math/FrustumPerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/FrustumPerformanceTests.cpp @@ -63,7 +63,7 @@ namespace Benchmark BENCHMARK_F(BM_MathFrustum, SphereIntersect)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& data : m_dataArray) { @@ -75,7 +75,7 @@ namespace Benchmark BENCHMARK_F(BM_MathFrustum, AabbIntersect)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& data : m_dataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/Matrix3x3PerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/Matrix3x3PerformanceTests.cpp index 918673d475..c6fe9c8178 100644 --- a/Code/Framework/AzCore/Tests/Math/Matrix3x3PerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Matrix3x3PerformanceTests.cpp @@ -68,7 +68,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateIdentity)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -80,7 +80,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateZero)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -92,7 +92,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetRowX3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -108,7 +108,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetColumnX3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -124,7 +124,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateFromValue)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -136,7 +136,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateFromRowMajorFloat9)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -148,7 +148,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateFromColumnMajorFloat9)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -162,7 +162,7 @@ namespace Benchmark { float storeValues[9]; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -176,7 +176,7 @@ namespace Benchmark { float storeValues[9]; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -188,7 +188,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateRotationX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -200,7 +200,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateRotationY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -212,7 +212,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateRotationZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -224,7 +224,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateFromTransform)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -236,7 +236,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateFromMatrix4x4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -248,7 +248,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateFromQuaternion)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -260,7 +260,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -272,7 +272,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateDiagonal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -284,7 +284,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, CreateCrossProduct)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -296,7 +296,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetElement)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -308,7 +308,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, SetElement)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -321,7 +321,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, SetRowX3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -336,7 +336,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, SetColumnX3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -351,7 +351,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetBasisX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -363,7 +363,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetBasisY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -375,7 +375,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetBasisZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -387,7 +387,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, OperatorAssign)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -399,7 +399,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, OperatorMultiply)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -411,7 +411,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, TransposedMultiply)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -423,7 +423,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, MultiplyVector)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -435,7 +435,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, OperatorSum)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -447,7 +447,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, OperatorDifference)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -459,7 +459,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, OperatorMultiplyScalar)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -471,7 +471,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, OperatorDivideScalar)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -483,7 +483,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, Transpose)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -494,7 +494,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetTranspose)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -506,7 +506,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, RetrieveScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -518,7 +518,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, ExtractScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -530,7 +530,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, MultiplyByScaleX2)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -542,7 +542,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetPolarDecomposition)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -557,7 +557,7 @@ namespace Benchmark AZ::Matrix3x3 orthogonalOut; AZ::Matrix3x3 symmetricOut; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -568,7 +568,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetInverseFast)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -580,7 +580,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetInverseFull)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -592,7 +592,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, Orthogonalize)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -603,7 +603,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetOrthogonalized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -615,7 +615,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, IsOrthogonal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -627,7 +627,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetDiagonal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -639,7 +639,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetDeterminant)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -651,7 +651,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x3, GetAdjugate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/Matrix3x4PerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/Matrix3x4PerformanceTests.cpp index 63ddefdd2c..fd942056a2 100644 --- a/Code/Framework/AzCore/Tests/Math/Matrix3x4PerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Matrix3x4PerformanceTests.cpp @@ -86,7 +86,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateIdentity)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -98,7 +98,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateZero)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -110,7 +110,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromValue)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -122,7 +122,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromRowMajorFloat12)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -134,7 +134,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromRows)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -146,7 +146,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromColumnMajorFloat12)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -158,7 +158,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromColumns)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -170,7 +170,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromColumnMajorFloat16)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -182,7 +182,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateRotationX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -194,7 +194,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateRotationY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -206,7 +206,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateRotationZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -218,7 +218,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromQuaternion)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -230,7 +230,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromQuaternionAndTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -242,7 +242,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromMatrix3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -254,7 +254,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromMatrix3x3AndTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -266,7 +266,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromTransform)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -278,7 +278,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -290,7 +290,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateFromTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -302,7 +302,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, CreateLookAt)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -316,7 +316,7 @@ namespace Benchmark { float testFloats[12]; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -330,7 +330,7 @@ namespace Benchmark { float testFloats[12]; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -344,7 +344,7 @@ namespace Benchmark { float testFloats[16]; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -356,7 +356,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetElement)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -368,7 +368,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetElement)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -381,7 +381,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetRow)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -393,7 +393,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetRowAsVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -405,7 +405,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetRowWithFloats)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -418,7 +418,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetRowWithVector3AndFloat)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -431,7 +431,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetRowWithVector4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -444,7 +444,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetRows)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -459,7 +459,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetRows)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -472,7 +472,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetColumn)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -484,7 +484,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetColumnWithFloats)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -497,7 +497,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetColumnWithVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -510,7 +510,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetColumns)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -526,7 +526,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetColumns)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -539,7 +539,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetBasisX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -551,7 +551,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetBasisXWithFloats)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -564,7 +564,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetBasisXWithVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -577,7 +577,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetBasisY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -589,7 +589,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetBasisYWithFloats)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -602,7 +602,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetBasisYWithVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -615,7 +615,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetBasisZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -627,7 +627,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetBasisZWithFloats)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -640,7 +640,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetBasisZWithVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -653,7 +653,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -665,7 +665,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetTranslationWithFloats)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -678,7 +678,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetTranslationWithVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -691,7 +691,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetBasisAndTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -707,7 +707,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetBasisAndTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -720,7 +720,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, OperatorMultiplyMatrix3x4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -732,7 +732,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, OperatorMultiplyEqualsMatrix3x4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -745,7 +745,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, TransformPointVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -757,7 +757,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, TransformVectorVector4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -769,7 +769,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, Multiply3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -781,7 +781,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetTranspose)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -793,7 +793,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, Transpose)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -806,7 +806,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetTranspose3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -818,7 +818,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, Transpose3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -831,7 +831,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetInverseFull)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -843,7 +843,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, InvertFull)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -856,7 +856,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetInverseFast)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -868,7 +868,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, InvertFast)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -881,7 +881,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, RetrieveScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -893,7 +893,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, ExtractScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -906,7 +906,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, MultiplyByScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -919,7 +919,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, IsOrthogonal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -931,7 +931,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetOrthogonalized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -943,7 +943,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, Orthogonalize)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -956,7 +956,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, IsCloseExactAndDifferent)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -971,7 +971,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, OperatorEqualEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -983,7 +983,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, OperatorNotEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -995,7 +995,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetEulerDegrees)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -1007,7 +1007,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetEulerRadians)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -1019,7 +1019,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetFromEulerDegrees)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -1032,7 +1032,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetFromEulerRadians)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -1045,7 +1045,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, SetRotationPartFromQuaternion)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -1058,7 +1058,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, GetDeterminant3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -1070,7 +1070,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix3x4, IsFinite)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/Matrix4x4PerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/Matrix4x4PerformanceTests.cpp index 21f440c3a1..49a433a7fc 100644 --- a/Code/Framework/AzCore/Tests/Math/Matrix4x4PerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Matrix4x4PerformanceTests.cpp @@ -64,7 +64,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateIdentity)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -76,7 +76,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateZero)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -88,7 +88,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetRowX4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -106,7 +106,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetColumnX3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -124,7 +124,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateFromValue)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -136,7 +136,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateFromRowMajorFloat16)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -148,7 +148,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateFromColumnMajorFloat9)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -160,7 +160,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateProjection)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -172,7 +172,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateProjectionFov)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -184,7 +184,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateInterpolated)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -198,7 +198,7 @@ namespace Benchmark { float storeValues[16]; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -212,7 +212,7 @@ namespace Benchmark { float storeValues[16]; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -224,7 +224,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateRotationX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -236,7 +236,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateRotationY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -248,7 +248,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateRotationZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -260,7 +260,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateFromQuaternion)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -272,7 +272,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -284,7 +284,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateDiagonal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -296,7 +296,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetElement)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -308,7 +308,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, SetElement)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -321,7 +321,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, SetRowX3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -337,7 +337,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, SetColumnX3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -353,7 +353,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetBasisX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -365,7 +365,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetBasisY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -377,7 +377,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetBasisZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -389,7 +389,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, CreateTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -401,7 +401,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, SetTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -414,7 +414,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -426,7 +426,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, OperatorAssign)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -438,7 +438,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, OperatorMultiply)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -450,7 +450,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, OperatorMultiplyAssign)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -463,7 +463,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, OperatorMultiplyVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -475,7 +475,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, OperatorMultiplyVector4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -487,7 +487,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, TransposedMultiply3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -499,7 +499,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, Multiply3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -511,7 +511,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, Transpose)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -524,7 +524,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetTranspose)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -536,7 +536,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetInverseFast)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -552,7 +552,7 @@ namespace Benchmark AZ::Matrix4x4 mat = AZ::Matrix4x4::CreateRotationX(1.0f); mat.SetElement(0, 1, 23.1234f); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -564,7 +564,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, GetInverseFull)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -576,7 +576,7 @@ namespace Benchmark BENCHMARK_F(BM_MathMatrix4x4, SetRotationPartFromQuaternion)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/ObbPerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/ObbPerformanceTests.cpp index d1e8ac2225..ac95912035 100644 --- a/Code/Framework/AzCore/Tests/Math/ObbPerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/ObbPerformanceTests.cpp @@ -47,7 +47,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, CreateFromPositionRotationAndHalfLengths)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -60,7 +60,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, SetPosition)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -72,7 +72,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetPosition)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -84,7 +84,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetAxisX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -96,7 +96,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetAxisY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -108,7 +108,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetAxisZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -120,7 +120,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetAxisIndex3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -136,7 +136,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, SetHalfLengthX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -148,7 +148,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetHalfLengthX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -160,7 +160,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, SetHalfLengthY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -172,7 +172,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetHalfLengthY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -184,7 +184,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, SetHalfLengthZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -196,7 +196,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetHalfLengthZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -208,7 +208,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, SetHalfLengthIndex3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -222,7 +222,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, GetHalfLengthIndex3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -242,7 +242,7 @@ namespace Benchmark AZ::Vector3 max(120.0f, 300.0f, 50.0f); AZ::Aabb aabb = AZ::Aabb::CreateFromMinMax(min, max); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -256,7 +256,7 @@ namespace Benchmark { AZ::Transform transform = AZ::Transform::CreateRotationY(AZ::DegToRad(90.0f)); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -268,7 +268,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, Equal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { @@ -280,7 +280,7 @@ namespace Benchmark BENCHMARK_F(BM_MathObb, IsFinite)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < numIters; ++i) { diff --git a/Code/Framework/AzCore/Tests/Math/PlanePerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/PlanePerformanceTests.cpp index e066207635..919dc72988 100644 --- a/Code/Framework/AzCore/Tests/Math/PlanePerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/PlanePerformanceTests.cpp @@ -73,7 +73,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, CreateFromNormalAndDistance)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -85,7 +85,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, GetDistance)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -97,7 +97,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, GetNormal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -109,7 +109,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, CreateFromNormalAndPoint)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -128,7 +128,7 @@ namespace Benchmark coeff.push_back(unif(rng)); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -148,7 +148,7 @@ namespace Benchmark coeff.push_back(unif(rng)); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -160,7 +160,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, SetVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -179,7 +179,7 @@ namespace Benchmark vecs.push_back(AZ::Vector4(unif(rng), unif(rng), unif(rng), unif(rng))); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -192,7 +192,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, SetNormal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -205,7 +205,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, SetDistance)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -218,7 +218,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, GetPlaneEquationCoefficients)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -236,7 +236,7 @@ namespace Benchmark trans.push_back(AZ::Transform::CreateRotationY(AZ::DegToRad(unif(rng)))); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -254,7 +254,7 @@ namespace Benchmark trans.push_back(AZ::Transform::CreateRotationY(AZ::DegToRad(unif(rng)))); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -265,7 +265,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, GetPointDist)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -277,7 +277,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, GetProjected)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -291,7 +291,7 @@ namespace Benchmark { AZ::Vector3 rayResult; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -305,7 +305,7 @@ namespace Benchmark { float rayResult; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { @@ -319,7 +319,7 @@ namespace Benchmark { AZ::Vector3 rayResult; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters - 1; ++i) { @@ -333,7 +333,7 @@ namespace Benchmark { float rayResult; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters - 1; ++i) { @@ -345,7 +345,7 @@ namespace Benchmark BENCHMARK_F(BM_MathPlane, IsFinite)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (int i = 0; i < m_numIters; ++i) { diff --git a/Code/Framework/AzCore/Tests/Math/QuaternionPerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/QuaternionPerformanceTests.cpp index 486a33ba67..4ef42c3016 100644 --- a/Code/Framework/AzCore/Tests/Math/QuaternionPerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/QuaternionPerformanceTests.cpp @@ -68,7 +68,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SplatFloatConstruction)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -80,7 +80,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, NonNormalized4FloatsConstruction)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -92,7 +92,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, CreateFromIdentity)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& quatData : m_quatDataArray) { @@ -104,7 +104,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, CreateZero)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& quatData : m_quatDataArray) { @@ -116,7 +116,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, CreateRotationX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -128,7 +128,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, CreateRotationY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -140,7 +140,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, CreateRotationZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -155,7 +155,7 @@ namespace Benchmark const AZ::Vector3 vec1 = AZ::Vector3(1.0f, 2.0f, 3.0f).GetNormalized(); const AZ::Vector3 vec2 = AZ::Vector3(-2.0f, 7.0f, -1.0f).GetNormalized(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& quatData : m_quatDataArray) { @@ -170,7 +170,7 @@ namespace Benchmark const AZ::Vector3 vec1 = AZ::Vector3(1.0f, 2.0f, 3.0f).GetNormalized(); const AZ::Vector3 vec2 = AZ::Vector3(-1.0f, -2.0f, -3.0f).GetNormalized(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& quatData : m_quatDataArray) { @@ -182,7 +182,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -194,7 +194,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -206,7 +206,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -218,7 +218,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetW)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -230,7 +230,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -243,7 +243,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -256,7 +256,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -269,7 +269,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetW)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -282,7 +282,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetSplat)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -295,7 +295,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetAll)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -310,7 +310,7 @@ namespace Benchmark { AZ::Vector3 vec(5.0f, 6.0f, 7.0f); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& quatData : m_quatDataArray) { @@ -324,7 +324,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetArray)(benchmark::State& state) { const float quatArray[4] = { 5.0f, 6.0f, 7.0f, 8.0f }; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& quatData : m_quatDataArray) { @@ -337,7 +337,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetElements)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -353,7 +353,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetElement)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -374,7 +374,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetConjugate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -386,7 +386,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetInverseFast)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -398,7 +398,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetInverseFull)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -410,7 +410,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, Dot)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -422,7 +422,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetLength)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -434,7 +434,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetLengthEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -446,7 +446,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetLengthReciprocal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -458,7 +458,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetLengthReciprocalEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -470,7 +470,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetNormalized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -482,7 +482,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetNormalizedEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -494,7 +494,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, NormalizeWithLength)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -506,7 +506,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, NormalizeWithLengthEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -518,7 +518,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, Lerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -530,7 +530,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, NLerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -542,7 +542,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, Slerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -554,7 +554,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, OperatorEquality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -566,7 +566,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, OperatorInequality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -578,7 +578,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, OperatorNegate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -590,7 +590,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, OperatorSum)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -602,7 +602,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, OperatorSub)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -614,7 +614,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, OperatorMultiply)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -626,7 +626,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, OperatorMultiplyScalar)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -638,7 +638,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, TransformVector)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -653,7 +653,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, IsClose)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -665,7 +665,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, IsIdentity)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -677,7 +677,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetEulerDegrees)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -689,7 +689,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, GetEulerRadians)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -701,7 +701,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetFromEulerRadians)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -715,7 +715,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, SetFromEulerDegrees)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -729,7 +729,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, ConvertToAxisAngle)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& quatData : m_quatDataArray) { @@ -744,7 +744,7 @@ namespace Benchmark BENCHMARK_F(BM_MathQuaternion, AggregateMultiply)(::benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZ::Vector3 position = AZ::Vector3::CreateZero(); for (auto& quatData : m_quatDataArray) diff --git a/Code/Framework/AzCore/Tests/Math/ShapeIntersectionPerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/ShapeIntersectionPerformanceTests.cpp index ecab1717b2..7526bdb778 100644 --- a/Code/Framework/AzCore/Tests/Math/ShapeIntersectionPerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/ShapeIntersectionPerformanceTests.cpp @@ -80,7 +80,7 @@ namespace Benchmark BENCHMARK_F(BM_MathShapeIntersection, ContainsFrustumPoint)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -103,7 +103,7 @@ namespace Benchmark BENCHMARK_F(BM_MathShapeIntersection, OverlapsFrustumSphere)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -120,7 +120,7 @@ namespace Benchmark BENCHMARK_F(BM_MathShapeIntersection, ContainsFrustumSphere)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -137,7 +137,7 @@ namespace Benchmark BENCHMARK_F(BM_MathShapeIntersection, OverlapsFrustumAabb)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -154,7 +154,7 @@ namespace Benchmark BENCHMARK_F(BM_MathShapeIntersection, ContainsFrustumAabb)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp index dde0192ef9..37d9a32820 100644 --- a/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp @@ -78,7 +78,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateIdentity)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for ([[maybe_unused]] auto& testData : m_testDataArray) { @@ -90,7 +90,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateRotationX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -102,7 +102,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateRotationY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -114,7 +114,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateRotationZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -126,7 +126,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateFromQuaternion)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -138,7 +138,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateFromQuaternionAndTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -150,7 +150,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateFromMatrix3x3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -162,7 +162,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateFromMatrix3x3AndTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -174,7 +174,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateFromMatrix3x4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -186,7 +186,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateUniformScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -198,7 +198,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateFromTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -210,7 +210,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, CreateLookAt)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -223,7 +223,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetBasis)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -235,7 +235,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetBasisX)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -247,7 +247,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetBasisY)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -259,7 +259,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetBasisZ)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -271,7 +271,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetBasisAndTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -287,7 +287,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetTranslation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -299,7 +299,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, SetTranslationWithFloats)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -312,7 +312,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, SetTranslationWithVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -325,7 +325,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetRotation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -337,7 +337,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, SetRotation)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -350,7 +350,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetUniformScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -362,7 +362,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, SetUniformScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -375,7 +375,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, ExtractUniformScale)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -388,7 +388,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, OperatorMultiplyTransform)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -400,7 +400,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, OperatorMultiplyEqualsTransform)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -413,7 +413,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, TransformPointVector3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -425,7 +425,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, TransformPointVector4)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -437,7 +437,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, TransformVector)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -449,7 +449,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetInverse)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -461,7 +461,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, Invert)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -474,7 +474,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, IsOrthogonal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -486,7 +486,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetOrthogonalized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -498,7 +498,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, Orthogonalize)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -511,7 +511,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, IsCloseExactAndDifferent)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -526,7 +526,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, OperatorEqualEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -538,7 +538,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, OperatorNotEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -550,7 +550,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetEulerDegrees)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -562,7 +562,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, GetEulerRadians)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -574,7 +574,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, SetFromEulerDegrees)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -587,7 +587,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, SetFromEulerRadians)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { @@ -600,7 +600,7 @@ namespace Benchmark BENCHMARK_F(BM_MathTransform, IsFinite)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& testData : m_testDataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/Vector2PerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/Vector2PerformanceTests.cpp index 3ab306ff66..6c8e575481 100644 --- a/Code/Framework/AzCore/Tests/Math/Vector2PerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Vector2PerformanceTests.cpp @@ -58,7 +58,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetSet)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZ::Vector2 v1, v2; float x = 0.0f, y = 0.0f; @@ -84,7 +84,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, ElementAccess)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZ::Vector2 v1, v2; float x = 0.0f, y = 0.0f; @@ -111,7 +111,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, CreateSelectCmpEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -123,7 +123,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, CreateSelectCmpGreaterEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -135,7 +135,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, CreateSelectCmpGreater)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -147,7 +147,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetNormalized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -159,7 +159,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetNormalizedEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -171,7 +171,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, NormalizeWithLength)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -183,7 +183,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, NormalizeWithLengthEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -195,7 +195,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetNormalizedSafe)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -207,7 +207,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetNormalizedSafeEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -219,7 +219,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetDistance)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -231,7 +231,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetDistanceEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -243,7 +243,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Lerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -267,7 +267,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Slerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -291,7 +291,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Nlerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -315,7 +315,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Dot)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -327,7 +327,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Equality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -339,7 +339,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Inequality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -351,7 +351,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, IsLessThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -363,7 +363,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, IsLessEqualThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -375,7 +375,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, IsGreaterThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -387,7 +387,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, IsGreaterEqualThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -399,7 +399,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetMin)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -411,7 +411,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetMax)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -423,7 +423,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetClamp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -435,7 +435,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Sub)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -447,7 +447,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Sum)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -459,7 +459,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Mul)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -471,7 +471,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Div)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -483,7 +483,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetSin)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -495,7 +495,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetCos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -507,7 +507,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetSinCos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -521,7 +521,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetAcos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -533,7 +533,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetAtan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -545,7 +545,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetAtan2)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -557,7 +557,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetAngleMod)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -569,7 +569,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, Angle)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -581,7 +581,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, AngleDeg)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -593,7 +593,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetAbs)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -605,7 +605,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetReciprocal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -617,7 +617,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetReciprocalEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -629,7 +629,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector2, GetProjected)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/Vector3PerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/Vector3PerformanceTests.cpp index 5f33730bca..3e54e435d8 100644 --- a/Code/Framework/AzCore/Tests/Math/Vector3PerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Vector3PerformanceTests.cpp @@ -58,7 +58,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetSet)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZ::Vector3 v1, v2, v3; float x = 0.0f, y = 0.0f, z = 0.0f; @@ -98,7 +98,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, ElementAccess)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZ::Vector3 v1, v2, v3; float x = 0.0f, y = 0.0f, z = 0.0f; @@ -138,7 +138,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, CreateSelectCmpEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -150,7 +150,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, CreateSelectCmpGreaterEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -162,7 +162,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, CreateSelectCmpGreater)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -174,7 +174,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetNormalized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -186,7 +186,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetNormalizedEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -198,7 +198,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, NormalizeWithLength)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -210,7 +210,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, NormalizeWithLengthEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -222,7 +222,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetNormalizedSafe)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -234,7 +234,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetNormalizedSafeEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -246,7 +246,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetDistance)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -258,7 +258,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetDistanceEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -270,7 +270,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Lerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -294,7 +294,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Slerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -318,7 +318,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Nlerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -342,7 +342,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Dot)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -354,7 +354,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Cross)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -366,7 +366,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Equality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -378,7 +378,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Inequality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -390,7 +390,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, IsLessThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -402,7 +402,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, IsLessEqualThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -414,7 +414,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, IsGreaterThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -426,7 +426,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, IsGreaterEqualThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -438,7 +438,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetMin)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -450,7 +450,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetMax)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -462,7 +462,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetClamp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -474,7 +474,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Sub)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -486,7 +486,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Sum)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -498,7 +498,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Mul)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -510,7 +510,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Div)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -522,7 +522,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetSin)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -534,7 +534,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetCos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -546,7 +546,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetSinCos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -560,7 +560,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetAcos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -572,7 +572,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetAtan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -584,7 +584,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetAngleMod)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -596,7 +596,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, Angle)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -608,7 +608,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, AngleDeg)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -620,7 +620,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetAbs)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -632,7 +632,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetReciprocal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -644,7 +644,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetReciprocalEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -656,7 +656,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, IsPerpendicular)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -668,7 +668,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetOrthogonalVector)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -680,7 +680,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector3, GetProjected)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { diff --git a/Code/Framework/AzCore/Tests/Math/Vector4PerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/Vector4PerformanceTests.cpp index f12851b1ed..d2a5bbd46b 100644 --- a/Code/Framework/AzCore/Tests/Math/Vector4PerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/Vector4PerformanceTests.cpp @@ -60,7 +60,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetSet)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZ::Vector4 v1, v2, v3, v4; float x = 0.0f, y = 0.0f, z = 0.0f, w = 0.0f; @@ -117,7 +117,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, ElementAccess)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZ::Vector4 v1, v2, v3, v4; float x = 0.0f, y = 0.0f, z = 0.0f, w = 0.0f; @@ -174,7 +174,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, CreateSelectCmpEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -186,7 +186,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, CreateSelectCmpGreaterEqual)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -198,7 +198,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, CreateSelectCmpGreater)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -210,7 +210,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetNormalized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -222,7 +222,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetNormalizedEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -234,7 +234,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, NormalizeWithLength)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -246,7 +246,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, NormalizeWithLengthEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -258,7 +258,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetNormalizedSafe)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -270,7 +270,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetNormalizedSafeEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -282,7 +282,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetDistance)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -294,7 +294,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetDistanceEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -306,7 +306,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Lerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -330,7 +330,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Slerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -354,7 +354,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Nlerp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -378,7 +378,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Dot)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -390,7 +390,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Dot3)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -402,7 +402,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetHomogenized)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -414,7 +414,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Equality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -426,7 +426,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Inequality)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -438,7 +438,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, IsLessThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -450,7 +450,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, IsLessEqualThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -462,7 +462,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, IsGreaterThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -474,7 +474,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, IsGreaterEqualThan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -486,7 +486,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetMin)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -498,7 +498,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetMax)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -510,7 +510,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetClamp)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -522,7 +522,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Sub)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -534,7 +534,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Sum)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -546,7 +546,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Mul)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -558,7 +558,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Div)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -570,7 +570,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetSin)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -582,7 +582,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetCos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -594,7 +594,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetSinCos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -608,7 +608,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetAcos)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -620,7 +620,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetAtan)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -632,7 +632,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetAngleMod)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -644,7 +644,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, Angle)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -656,7 +656,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, AngleDeg)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -668,7 +668,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetAbs)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -680,7 +680,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetReciprocal)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { @@ -692,7 +692,7 @@ namespace Benchmark BENCHMARK_F(BM_MathVector4, GetReciprocalEstimate)(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& vecData : m_vecDataArray) { diff --git a/Code/Framework/AzCore/Tests/Memory/AllocatorBenchmarks.cpp b/Code/Framework/AzCore/Tests/Memory/AllocatorBenchmarks.cpp index e027b03a49..f7ebc2f632 100644 --- a/Code/Framework/AzCore/Tests/Memory/AllocatorBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/Memory/AllocatorBenchmarks.cpp @@ -288,7 +288,7 @@ namespace Benchmark public: void Benchmark(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); @@ -333,7 +333,7 @@ namespace Benchmark public: void Benchmark(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); AZStd::vector& perThreadAllocations = base::GetPerThreadAllocations(state.thread_index); @@ -420,7 +420,7 @@ namespace Benchmark void Benchmark(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); diff --git a/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp b/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp index 95b0626d7f..3f3386241a 100644 --- a/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp +++ b/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp @@ -1248,7 +1248,7 @@ namespace Benchmark AZStd::unique_ptr buffer(new char[FileSize]); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::binary_semaphore waitForReads; AZStd::atomic end; diff --git a/Code/Framework/AzCore/Tests/TaskTests.cpp b/Code/Framework/AzCore/Tests/TaskTests.cpp index 53fa89900e..7d805ce1f7 100644 --- a/Code/Framework/AzCore/Tests/TaskTests.cpp +++ b/Code/Framework/AzCore/Tests/TaskTests.cpp @@ -677,7 +677,7 @@ namespace Benchmark [] { }); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { TaskGraphEvent ev; graph->SubmitOnExecutor(*executor, &ev); @@ -699,7 +699,7 @@ namespace Benchmark }); a.Precedes(b); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { TaskGraphEvent ev; graph->SubmitOnExecutor(*executor, &ev); @@ -729,7 +729,7 @@ namespace Benchmark e.Follows(a, b, c, d); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { TaskGraphEvent ev; graph->SubmitOnExecutor(*executor, &ev); diff --git a/Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp b/Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp index 64fba61e2c..7ab2638af6 100644 --- a/Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp +++ b/Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp @@ -142,7 +142,7 @@ namespace Benchmark BENCHMARK_F(BM_Octree, InsertDelete1000)(benchmark::State& state) { constexpr uint32_t EntryCount = 1000; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { InsertEntries(EntryCount); RemoveEntries(EntryCount); @@ -152,7 +152,7 @@ namespace Benchmark BENCHMARK_F(BM_Octree, InsertDelete10000)(benchmark::State& state) { constexpr uint32_t EntryCount = 10000; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { InsertEntries(EntryCount); RemoveEntries(EntryCount); @@ -162,7 +162,7 @@ namespace Benchmark BENCHMARK_F(BM_Octree, InsertDelete100000)(benchmark::State& state) { constexpr uint32_t EntryCount = 100000; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { InsertEntries(EntryCount); RemoveEntries(EntryCount); @@ -172,7 +172,7 @@ namespace Benchmark BENCHMARK_F(BM_Octree, InsertDelete1000000)(benchmark::State& state) { constexpr uint32_t EntryCount = 1000000; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { InsertEntries(EntryCount); RemoveEntries(EntryCount); @@ -183,7 +183,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 1000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -197,7 +197,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 10000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -211,7 +211,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 100000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -225,7 +225,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 1000000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -239,7 +239,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 1000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -253,7 +253,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 10000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -267,7 +267,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 100000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -281,7 +281,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 1000000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -295,7 +295,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 1000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -309,7 +309,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 10000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -323,7 +323,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 100000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { @@ -337,7 +337,7 @@ namespace Benchmark { constexpr uint32_t EntryCount = 1000000; InsertEntries(EntryCount); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (auto& queryData : m_queryDataArray) { diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp index 8cc5e5f4d2..debca753de 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabCreateBenchmarks.cpp @@ -21,7 +21,7 @@ namespace Benchmark CreateFakePaths(numInstances); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); @@ -60,7 +60,7 @@ namespace Benchmark { const unsigned int numEntities = static_cast(state.range()); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); @@ -100,7 +100,7 @@ namespace Benchmark // plus the instance receiving them CreateFakePaths(numInstancesToAdd + 1); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); @@ -150,7 +150,7 @@ namespace Benchmark // plus the root instance CreateFakePaths(numInstances + 1); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp index f2f3cf82b0..cc1caf1a82 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabInstantiateBenchmarks.cpp @@ -24,7 +24,7 @@ namespace Benchmark m_pathString); TemplateId templateToInstantiateId = firstInstance->GetTemplateId(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp index dd29654416..60e87a7a82 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabLoadBenchmarks.cpp @@ -19,7 +19,7 @@ namespace Benchmark const unsigned int numTemplates = static_cast(state.range()); CreateFakePaths(numTemplates); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp index 92a30b89f2..4f50da66c8 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp @@ -24,7 +24,7 @@ namespace Benchmark const auto& nestedTemplatePath = m_paths.front(); const auto& enclosingTemplatePath = m_paths.back(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); @@ -85,7 +85,7 @@ namespace Benchmark const unsigned int numInstances = maxDepth; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); @@ -137,7 +137,7 @@ namespace Benchmark const unsigned int numInstances = numRootInstances * maxDepth; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); @@ -197,7 +197,7 @@ namespace Benchmark const unsigned int numInstances = (1 << maxDepth) - 1; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp index ba0c3a4838..a44ce6dd28 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/Spawnable/SpawnAllEntitiesBenchmarks.cpp @@ -22,7 +22,7 @@ namespace Benchmark SetUpSpawnableAsset(entityCountInSourcePrefab); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); m_spawnTicket = aznew AzFramework::EntitySpawnTicket(m_spawnableAsset); @@ -59,7 +59,7 @@ namespace Benchmark SetUpSpawnableAsset(entityCountInSpawnable); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); m_spawnTicket = aznew AzFramework::EntitySpawnTicket(m_spawnableAsset); @@ -94,7 +94,7 @@ namespace Benchmark SetUpSpawnableAsset(entityCountInSpawnable); auto spawner = AzFramework::SpawnableEntitiesInterface::Get(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { state.PauseTiming(); m_spawnTicket = aznew AzFramework::EntitySpawnTicket(m_spawnableAsset); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp index d9024114a5..e625a1ba0c 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/SpawnableCreateBenchmarks.cpp @@ -27,7 +27,7 @@ namespace Benchmark auto& prefabDom = m_prefabSystemComponent->FindTemplateDom(instance->GetTemplateId()); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { // Create a vector to store spawnables so that they don't get destroyed immediately after construction. AZStd::vector> spawnables; diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp index d3c537ea1d..c05d34221b 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp @@ -259,7 +259,7 @@ namespace UnitTest const float width = aznumeric_cast(queryRange); // Call GetValue() on the EBus for every height and width in our ranges. - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (float y = 0.0f; y < height; y += 1.0f) { @@ -285,7 +285,7 @@ namespace UnitTest int64_t totalQueryPoints = queryRange * queryRange; // Call GetValues() for every height and width in our ranges. - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. @@ -313,7 +313,7 @@ namespace UnitTest const float width = aznumeric_cast(queryRange); // Call GetValue() through the GradientSampler for every height and width in our ranges. - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (float y = 0.0f; y < height; y += 1.0f) { @@ -343,7 +343,7 @@ namespace UnitTest const int64_t totalQueryPoints = queryRange * queryRange; // Call GetValues() through the GradientSampler for every height and width in our ranges. - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable. diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersBenchmarks.cpp index cd9e3c0395..55d7305a70 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersBenchmarks.cpp @@ -235,7 +235,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker AZStd::vector tickTimes; tickTimes.reserve(CharacterConstants::GameFramesToSimulate); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < CharacterConstants::GameFramesToSimulate; i++) { @@ -294,7 +294,7 @@ namespace PhysX::Benchmarks AZStd::vector tickTimes; tickTimes.reserve(CharacterConstants::GameFramesToSimulate); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < CharacterConstants::GameFramesToSimulate; i++) { @@ -361,7 +361,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker AZStd::vector tickTimes; tickTimes.reserve(CharacterConstants::GameFramesToSimulate); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { //run each simulation part, and change direction each time for (AZ::u32 i = 0; i < numDirectionChanges; i++) diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersRagdollBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersRagdollBenchmarks.cpp index c82d222e80..e86125c1f5 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersRagdollBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXCharactersRagdollBenchmarks.cpp @@ -198,7 +198,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker AZStd::vector tickTimes; tickTimes.reserve(RagdollConstants::GameFramesToSimulate); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < RagdollConstants::GameFramesToSimulate; i++) { @@ -264,7 +264,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker AZStd::vector tickTimes; tickTimes.reserve(RagdollConstants::GameFramesToSimulate); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < RagdollConstants::GameFramesToSimulate; i++) { diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXGenericBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXGenericBenchmarks.cpp index c2cf7f1246..1e556c3af7 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXGenericBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXGenericBenchmarks.cpp @@ -31,7 +31,7 @@ namespace PhysX::Benchmarks void BM_PhysXBenchmarkFixture(benchmark::State& state) { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { auto fixture = std::make_unique(); fixture->SetUp(); diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp index de8a9d2146..8606735174 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXJointBenchmarks.cpp @@ -245,7 +245,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker Types::TimeList tickTimes; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < JointConstants::GameFramesToSimulate; i++) { @@ -300,7 +300,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker Types::TimeList tickTimes; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < JointConstants::GameFramesToSimulate; i++) { @@ -399,7 +399,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker Types::TimeList tickTimes; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < JointConstants::GameFramesToSimulate; i++) { diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp index 58cbd0da23..616c248667 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXRigidBodyBenchmarks.cpp @@ -229,7 +229,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker Types::TimeList tickTimes; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < RigidBodyConstants::GameFramesToSimulate; i++) { @@ -302,7 +302,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker AZStd::vector tickTimes; tickTimes.reserve(RigidBodyConstants::GameFramesToSimulate); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < RigidBodyConstants::GameFramesToSimulate; i++) { @@ -471,7 +471,7 @@ namespace PhysX::Benchmarks //setup the frame timer tracker AZStd::vector tickTimes; tickTimes.reserve(RigidBodyConstants::GameFramesToSimulate); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { for (AZ::u32 i = 0; i < RigidBodyConstants::GameFramesToSimulate; i++) { diff --git a/Gems/PhysX/Code/Tests/Benchmarks/PhysXSceneQueryBenchmarks.cpp b/Gems/PhysX/Code/Tests/Benchmarks/PhysXSceneQueryBenchmarks.cpp index 9a8a28a85e..ba3f7aad40 100644 --- a/Gems/PhysX/Code/Tests/Benchmarks/PhysXSceneQueryBenchmarks.cpp +++ b/Gems/PhysX/Code/Tests/Benchmarks/PhysXSceneQueryBenchmarks.cpp @@ -141,7 +141,7 @@ namespace PhysX::Benchmarks auto* sceneInterface = AZ::Interface::Get(); auto next = 0; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { request.m_direction = m_boxes[next].GetNormalized(); @@ -175,7 +175,7 @@ namespace PhysX::Benchmarks auto* sceneInterface = AZ::Interface::Get(); auto next = 0; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { request.m_direction = m_boxes[next].GetNormalized(); @@ -206,7 +206,7 @@ namespace PhysX::Benchmarks auto* sceneInterface = AZ::Interface::Get(); auto next = 0; - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { request.m_pose = AZ::Transform::CreateTranslation(m_boxes[next]); diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp index becb91f0ce..a507391ae6 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp @@ -181,7 +181,7 @@ namespace UnitTest SurfaceData::SurfaceTagVector filterTags = CreateBenchmarkTagFilterList(); // Query every point in our world at 1 meter intervals. - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { // This is declared outside the loop so that the list of points doesn't fully reallocate on every query. SurfaceData::SurfacePointList points; @@ -211,7 +211,7 @@ namespace UnitTest SurfaceData::SurfaceTagVector filterTags = CreateBenchmarkTagFilterList(); // Query every point in our world at 1 meter intervals. - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { SurfaceData::SurfacePointLists points; @@ -235,7 +235,7 @@ namespace UnitTest SurfaceData::SurfaceTagVector filterTags = CreateBenchmarkTagFilterList(); // Query every point in our world at 1 meter intervals. - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { AZStd::vector queryPositions; queryPositions.reserve(worldSizeInt * worldSizeInt); diff --git a/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp b/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp index 6aad3f9568..c2df02779d 100644 --- a/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp +++ b/Gems/Terrain/Code/Tests/TerrainSystemBenchmarks.cpp @@ -267,7 +267,7 @@ namespace UnitTest auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution, worldBounds); // Call the terrain API we're testing for every height and width in our ranges. - for (auto stateIterator : state) + for ([[maybe_unused]] auto stateIterator : state) { ApiCaller(queryResolution, worldBounds, sampler); } From ddb66786dc4711d31e2276765c435820c0974b0e Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:01:07 -0800 Subject: [PATCH 06/42] Remove unused variable Signed-off-by: Chris Burel --- Code/Framework/AzCore/Tests/Memory.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Memory.cpp b/Code/Framework/AzCore/Tests/Memory.cpp index 0e0103d162..2be694c384 100644 --- a/Code/Framework/AzCore/Tests/Memory.cpp +++ b/Code/Framework/AzCore/Tests/Memory.cpp @@ -141,7 +141,6 @@ namespace UnitTest //////////////////////////////////////////////////////////////////////// // Create some threads and simulate concurrent allocation and deallocation - AZStd::chrono::system_clock::time_point startTime = AZStd::chrono::system_clock::now(); { AZStd::thread m_threads[m_maxNumThreads]; for (unsigned int i = 0; i < m_maxNumThreads; ++i) @@ -156,8 +155,6 @@ namespace UnitTest m_threads[i].join(); } } - //AZStd::chrono::microseconds exTime = AZStd::chrono::system_clock::now() - startTime; - //AZ_Printf("UnitTest::SystemAllocatorTest::deafult","Time: %d Ms\n",exTime.count()); ////////////////////////////////////////////////////////////////////////// AllocatorInstance::Destroy(); From b79d5faa1602bdc864f36daf35540a16deba5471 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:02:00 -0800 Subject: [PATCH 07/42] Remove unused captures Signed-off-by: Chris Burel --- .../Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp b/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp index 3f3386241a..4efcd0d86e 100644 --- a/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp +++ b/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp @@ -981,7 +981,7 @@ namespace AZ::IO AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the // capture. Newer versions issue unused warning - auto callback = [numChunks, &numCallbacks, &waitForReads](FileRequestHandle request) + auto callback = [&numCallbacks, &waitForReads](FileRequestHandle request) AZ_POP_DISABLE_WARNING { IStreamer* streamer = Interface::Get(); @@ -1052,7 +1052,7 @@ namespace AZ::IO AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the // capture. Newer versions issue unused warning - auto callback = [numChunks, &waitForReads, &waitForSingleRead, &numReadCallbacks]([[maybe_unused]] FileRequestHandle request) + auto callback = [&waitForReads, &waitForSingleRead, &numReadCallbacks]([[maybe_unused]] FileRequestHandle request) AZ_POP_DISABLE_WARNING { numReadCallbacks++; @@ -1076,7 +1076,7 @@ namespace AZ::IO cancels.push_back(m_streamer->Cancel(requests[numChunks - i - 1])); AZ_PUSH_DISABLE_WARNING(5233, "-Wunknown-warning-option") // Older versions of MSVC toolchain require to pass constexpr in the // capture. Newer versions issue unused warning - auto callback = [&numCancelCallbacks, &waitForCancels, numChunks](FileRequestHandle request) + auto callback = [&numCancelCallbacks, &waitForCancels](FileRequestHandle request) AZ_POP_DISABLE_WARNING { auto result = Interface::Get()->GetRequestStatus(request); From 5cc258d509781beb6fccfe67b1f86da8f9f40604 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:02:11 -0800 Subject: [PATCH 08/42] Remove unused variable Signed-off-by: Chris Burel --- .../Platform/Windows/AzFramework/Process/ProcessWatcher_Win.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessWatcher_Win.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessWatcher_Win.cpp index b0ef2f09a4..387a1abfe7 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessWatcher_Win.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessWatcher_Win.cpp @@ -374,8 +374,6 @@ namespace AzFramework // is double-quoted, then the double-quotes must be escaped properly otherwise // it will be absorbed by the native argument parser and possibly evaluated as // multiple values for arguments - AZStd::string_view escapedDoubleQuote = R"("\")"; - AZStd::vector preprocessedCommandArray; for (const auto& commandArg : commandLineArray) From f59ac65d2c55e197d81995a58823cfc3c6e0245e Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:02:49 -0800 Subject: [PATCH 09/42] Move platform-specific variable to be inside a platform-specific `#ifdef` Signed-off-by: Chris Burel --- .../AzQtComponents/AzQtComponents/Components/FancyDocking.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp index 7e78f64778..26b9e13e18 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp @@ -276,7 +276,6 @@ namespace AzQtComponents */ void FancyDocking::updateDockingGeometry() { - QRect totalScreenRect; int numScreens = QApplication::screens().count(); #ifdef AZ_PLATFORM_WINDOWS @@ -286,6 +285,9 @@ namespace AzQtComponents m_perScreenFullScreenWidgets.clear(); #endif +#if !defined(AZ_PLATFORM_WINDOWS) + QRect totalScreenRect; +#endif for (int i = 0; i < numScreens; ++i) { #ifdef AZ_PLATFORM_WINDOWS From fc2fc8459bbb7db0f5699cb71fb3f78534e69a6e Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:04:10 -0800 Subject: [PATCH 10/42] Fix missing `return;` statement (this is why we use `-Wunused-value`) Signed-off-by: Chris Burel --- Gems/Atom/RHI/DX12/Code/Source/RHI/AliasedHeap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/AliasedHeap.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/AliasedHeap.cpp index c988c4e14e..dcd4a2574c 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/AliasedHeap.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/AliasedHeap.cpp @@ -113,7 +113,7 @@ namespace AZ if (!memoryView.IsValid()) { - RHI::ResultCode::OutOfMemory; + return RHI::ResultCode::OutOfMemory; } buffer->SetDescriptor(descriptor); From bdac37477521b37ab72d3948b1b2e8b60cd2ad5a Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:07:50 -0800 Subject: [PATCH 11/42] Fix case-insensitive non-portable include paths Signed-off-by: Chris Burel --- .../Code/Include/Platform/Windows/Atom_RHI_Vulkan_Windows.h | 2 +- Gems/Blast/Code/Source/Components/BlastFamilyComponent.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_Windows.h b/Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_Windows.h index 2b2c2b015e..de5931f693 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_Windows.h +++ b/Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_Windows.h @@ -8,7 +8,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/Gems/Blast/Code/Source/Components/BlastFamilyComponent.h b/Gems/Blast/Code/Source/Components/BlastFamilyComponent.h index 99957d0fce..1a0e8135d9 100644 --- a/Gems/Blast/Code/Source/Components/BlastFamilyComponent.h +++ b/Gems/Blast/Code/Source/Components/BlastFamilyComponent.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include #include #include #include From d4eb3109506079ca57a5590185828d570b5acee4 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:08:12 -0800 Subject: [PATCH 12/42] Mark unused variables as unused Signed-off-by: Chris Burel --- Code/Framework/AzCore/Tests/AZStd/Examples.cpp | 2 +- Gems/Blast/Code/Source/Family/DamageManager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/Tests/AZStd/Examples.cpp b/Code/Framework/AzCore/Tests/AZStd/Examples.cpp index 518eb5eed6..89441b711e 100644 --- a/Code/Framework/AzCore/Tests/AZStd/Examples.cpp +++ b/Code/Framework/AzCore/Tests/AZStd/Examples.cpp @@ -443,7 +443,7 @@ namespace UnitTest : m_data(data) { /* expensive operations */ } private: - int m_data; + [[maybe_unused]] int m_data; }; ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Blast/Code/Source/Family/DamageManager.h b/Gems/Blast/Code/Source/Family/DamageManager.h index ed8d03da18..28892074b0 100644 --- a/Gems/Blast/Code/Source/Family/DamageManager.h +++ b/Gems/Blast/Code/Source/Family/DamageManager.h @@ -83,7 +83,7 @@ namespace Blast static AZ::Vector3 TransformToLocal(BlastActor& actor, const AZ::Vector3& globalPosition); BlastMaterial m_blastMaterial; - ActorTracker& m_actorTracker; + [[maybe_unused]] ActorTracker& m_actorTracker; }; template From 3d0a15f009c233f44224fa81cc899025fa59d362 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 13:24:27 -0800 Subject: [PATCH 13/42] Remove `AZStd::to_string(string&, bool)` overload from MCore's StringConversion header This overload has significant impact on overload resolution. Consider these overloads: ```cpp void to_string(AZStd::string& dest, AZStd::wstring_view src); void to_string(string& str, bool value); ``` And then calling code like this: ``` WCHAR src[260]; AZStd::string dst; AZStd::to_string(dst, src); // Which overload does this call? ``` If the .cpp has not included `MCore/Source/StringConversions.h`, the call to `to_string()` will convert the `WCHAR[260]` type to a `AZStd::wstring_view`, and call the first overload. But if `StringConversions.h` _has_ been included, the implicit conversion of `WCHAR[260]` to `bool` has a higher precedence, and it will be chosen instead. This overload was causing some uses of `to_string` in `AnimGraph/GameController.cpp` to resolve to the wrong overload in unity builds. Signed-off-by: Chris Burel --- Gems/EMotionFX/Code/MCore/Source/StringConversions.cpp | 5 ----- Gems/EMotionFX/Code/MCore/Source/StringConversions.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/Gems/EMotionFX/Code/MCore/Source/StringConversions.cpp b/Gems/EMotionFX/Code/MCore/Source/StringConversions.cpp index 88a22db245..5f57a036c2 100644 --- a/Gems/EMotionFX/Code/MCore/Source/StringConversions.cpp +++ b/Gems/EMotionFX/Code/MCore/Source/StringConversions.cpp @@ -76,11 +76,6 @@ namespace MCore namespace AZStd { - void to_string(string& str, bool value) - { - str = value ? "true" : "false"; - } - void to_string(string& str, const AZ::Vector2& value) { str = AZStd::string::format("%.8f,%.8f", diff --git a/Gems/EMotionFX/Code/MCore/Source/StringConversions.h b/Gems/EMotionFX/Code/MCore/Source/StringConversions.h index fd1c59208d..01b41091cf 100644 --- a/Gems/EMotionFX/Code/MCore/Source/StringConversions.h +++ b/Gems/EMotionFX/Code/MCore/Source/StringConversions.h @@ -49,7 +49,6 @@ namespace MCore namespace AZStd { - void to_string(string& str, bool value); void to_string(string& str, const AZ::Vector2& value); void to_string(string& str, const AZ::Vector3& value); void to_string(string& str, const AZ::Vector4& value); @@ -57,7 +56,6 @@ namespace AZStd void to_string(string& str, const AZ::Matrix4x4& value); void to_string(string& str, const AZ::Transform& value); - inline AZStd::string to_string(bool val) { AZStd::string str; to_string(str, val); return str; } inline AZStd::string to_string(const AZ::Vector2& val) { AZStd::string str; to_string(str, val); return str; } inline AZStd::string to_string(const AZ::Vector3& val) { AZStd::string str; to_string(str, val); return str; } inline AZStd::string to_string(const AZ::Vector4& val) { AZStd::string str; to_string(str, val); return str; } From ae7f370fed796cd130ef0855d6d06afda730c465 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:15:34 -0800 Subject: [PATCH 14/42] Fix lambda returning `false` instead of `nullptr` Signed-off-by: Chris Burel --- .../Windows/Editor/Core/QtEditorApplication_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Editor/Platform/Windows/Editor/Core/QtEditorApplication_windows.cpp b/Code/Editor/Platform/Windows/Editor/Core/QtEditorApplication_windows.cpp index f8065af931..1fd7f29ca3 100644 --- a/Code/Editor/Platform/Windows/Editor/Core/QtEditorApplication_windows.cpp +++ b/Code/Editor/Platform/Windows/Editor/Core/QtEditorApplication_windows.cpp @@ -135,7 +135,7 @@ namespace Editor } widget = widget->parentWidget(); } - return false; + return nullptr; }; if (object == toolBarAt(QCursor::pos())) { From 07ce8c6e785636af5d10cb79b69b599d005f2023 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:16:11 -0800 Subject: [PATCH 15/42] Remove unused functions and variables Signed-off-by: Chris Burel --- Code/Legacy/CrySystem/DebugCallStack.cpp | 4 ---- .../CrySystem/LocalizedStringManager.cpp | 21 +------------------ 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/Code/Legacy/CrySystem/DebugCallStack.cpp b/Code/Legacy/CrySystem/DebugCallStack.cpp index 201582b949..440525d7c8 100644 --- a/Code/Legacy/CrySystem/DebugCallStack.cpp +++ b/Code/Legacy/CrySystem/DebugCallStack.cpp @@ -47,8 +47,6 @@ extern HMODULE gDLLHandle; static HWND hwndException = 0; static bool g_bUserDialog = true; // true=on crash show dialog box, false=supress user interaction -static int PrintException(EXCEPTION_POINTERS* pex); - static bool IsFloatingPointException(EXCEPTION_POINTERS* pex); extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers); @@ -667,8 +665,6 @@ INT_PTR CALLBACK DebugCallStack::ExceptionDialogProc(HWND hwndDlg, UINT message, { static EXCEPTION_POINTERS* pex; - static char errorString[32768] = ""; - switch (message) { case WM_INITDIALOG: diff --git a/Code/Legacy/CrySystem/LocalizedStringManager.cpp b/Code/Legacy/CrySystem/LocalizedStringManager.cpp index c48baa95a7..b69fc539f9 100644 --- a/Code/Legacy/CrySystem/LocalizedStringManager.cpp +++ b/Code/Legacy/CrySystem/LocalizedStringManager.cpp @@ -2620,26 +2620,7 @@ namespace UnixTimeToFileTime(unixtime, &filetime); FileTimeToSystemTime(&filetime, systemtime); } - - time_t UnixTimeFromFileTime(const FILETIME* filetime) - { - LONGLONG longlong = filetime->dwHighDateTime; - longlong <<= 32; - longlong |= filetime->dwLowDateTime; - longlong -= 116444736000000000; - return longlong / 10000000; - } - - time_t UnixTimeFromSystemTime(const SYSTEMTIME* systemtime) - { - // convert systemtime to filetime - FILETIME filetime; - SystemTimeToFileTime(systemtime, &filetime); - // convert filetime to unixtime - time_t unixtime = UnixTimeFromFileTime(&filetime); - return unixtime; - } -}; +} void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool bShowSeconds, AZStd::string& outTimeString) { From 0b133f1154ca2788cd271df9f39f8793b3679d4f Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:16:50 -0800 Subject: [PATCH 16/42] Fix format string used for `size_t` (should be `%zu`), remove unused vararg Signed-off-by: Chris Burel --- .../Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp index a90f2cf4a2..428ab16f13 100644 --- a/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp +++ b/Code/Tools/TestImpactFramework/Frontend/Console/Code/Source/TestImpactConsoleTestSequenceEventHandler.cpp @@ -186,7 +186,7 @@ namespace TestImpact void TestRunCompleteCallback(const Client::TestRunBase& testRun, size_t numTestRunsCompleted, size_t totalNumTestRuns) { const auto progress = - AZStd::string::format("(%03u/%03u)", numTestRunsCompleted, totalNumTestRuns, testRun.GetTargetName().c_str()); + AZStd::string::format("(%03zu/%03zu)", numTestRunsCompleted, totalNumTestRuns); AZStd::string result; switch (testRun.GetResult()) From 66ba970a3bffa75ac0badc931960cb8f3409b0c6 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:17:19 -0800 Subject: [PATCH 17/42] Fix methods that recurse infinitely Signed-off-by: Chris Burel --- .../TestImpactClientSequenceReport.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h index b668bda155..5c4ac76031 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactClientSequenceReport.h @@ -391,57 +391,57 @@ namespace TestImpact // SequenceReport overrides ... AZStd::chrono::milliseconds GetDuration() const override { - return GetDuration() + m_draftedTestRunReport.GetDuration(); + return SequenceReportBase::GetDuration() + m_draftedTestRunReport.GetDuration(); } TestSequenceResult GetResult() const override { - return CalculateMultiTestSequenceResult({ GetResult(), m_draftedTestRunReport.GetResult() }); + return CalculateMultiTestSequenceResult({ SequenceReportBase::GetResult(), m_draftedTestRunReport.GetResult() }); } size_t GetTotalNumTestRuns() const override { - return GetTotalNumTestRuns() + m_draftedTestRunReport.GetTotalNumTestRuns(); + return SequenceReportBase::GetTotalNumTestRuns() + m_draftedTestRunReport.GetTotalNumTestRuns(); } size_t GetTotalNumPassingTests() const override { - return GetTotalNumPassingTests() + m_draftedTestRunReport.GetTotalNumPassingTests(); + return SequenceReportBase::GetTotalNumPassingTests() + m_draftedTestRunReport.GetTotalNumPassingTests(); } size_t GetTotalNumFailingTests() const override { - return GetTotalNumFailingTests() + m_draftedTestRunReport.GetTotalNumFailingTests(); + return SequenceReportBase::GetTotalNumFailingTests() + m_draftedTestRunReport.GetTotalNumFailingTests(); } size_t GetTotalNumDisabledTests() const override { - return GetTotalNumDisabledTests() + m_draftedTestRunReport.GetTotalNumDisabledTests(); + return SequenceReportBase::GetTotalNumDisabledTests() + m_draftedTestRunReport.GetTotalNumDisabledTests(); } size_t GetTotalNumPassingTestRuns() const override { - return GetTotalNumPassingTestRuns() + m_draftedTestRunReport.GetNumPassingTestRuns(); + return SequenceReportBase::GetTotalNumPassingTestRuns() + m_draftedTestRunReport.GetNumPassingTestRuns(); } size_t GetTotalNumFailingTestRuns() const override { - return GetTotalNumFailingTestRuns() + m_draftedTestRunReport.GetNumFailingTestRuns(); + return SequenceReportBase::GetTotalNumFailingTestRuns() + m_draftedTestRunReport.GetNumFailingTestRuns(); } size_t GetTotalNumExecutionFailureTestRuns() const override { - return GetTotalNumExecutionFailureTestRuns() + m_draftedTestRunReport.GetNumExecutionFailureTestRuns(); + return SequenceReportBase::GetTotalNumExecutionFailureTestRuns() + m_draftedTestRunReport.GetNumExecutionFailureTestRuns(); } size_t GetTotalNumTimedOutTestRuns() const override { - return GetTotalNumTimedOutTestRuns() + m_draftedTestRunReport.GetNumTimedOutTestRuns(); + return SequenceReportBase::GetTotalNumTimedOutTestRuns() + m_draftedTestRunReport.GetNumTimedOutTestRuns(); } size_t GetTotalNumUnexecutedTestRuns() const override { - return GetTotalNumUnexecutedTestRuns() + m_draftedTestRunReport.GetNumUnexecutedTestRuns(); + return SequenceReportBase::GetTotalNumUnexecutedTestRuns() + m_draftedTestRunReport.GetNumUnexecutedTestRuns(); } private: AZStd::vector m_draftedTestRuns; From 24339e36ab48164cb8a6bb296bba004530efeb9b Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:19:26 -0800 Subject: [PATCH 18/42] Fix non-constexpr `RepoPath` class to not try to be `constexpr` `RepoPath` is implemented with an `AZ::IO::Path`, which is not `constexpr`. Consequently, its constructors also cannot be `constexpr`. This also marks the function definitions in the header as `inline`, to avoid ODR violations. Signed-off-by: Chris Burel --- .../TestImpactFramework/TestImpactRepoPath.h | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h index e784c43500..eede3e5968 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h @@ -24,13 +24,13 @@ namespace TestImpact using value_type = AZ::IO::Path::value_type; constexpr RepoPath() = default; - constexpr RepoPath(const RepoPath&) = default; - constexpr RepoPath(RepoPath&&) noexcept = default; - constexpr RepoPath(const string_type& path) noexcept; - constexpr RepoPath(const string_view_type& path) noexcept; - constexpr RepoPath(const value_type* path) noexcept; - constexpr RepoPath(const AZ::IO::PathView& path); - constexpr RepoPath(const AZ::IO::Path& path); + RepoPath(const RepoPath&) = default; + RepoPath(RepoPath&&) noexcept = default; + RepoPath(const string_type& path) noexcept; + RepoPath(const string_view_type& path) noexcept; + RepoPath(const value_type* path) noexcept; + RepoPath(const AZ::IO::PathView& path); + RepoPath(const AZ::IO::Path& path); RepoPath& operator=(const RepoPath&) noexcept = default; RepoPath& operator=(const string_type&) noexcept; @@ -67,27 +67,27 @@ namespace TestImpact AZ::IO::Path m_path; }; - constexpr RepoPath::RepoPath(const string_type& path) noexcept + inline RepoPath::RepoPath(const string_type& path) noexcept : m_path(AZ::IO::Path(path).MakePreferred()) { } - constexpr RepoPath::RepoPath(const string_view_type& path) noexcept + inline RepoPath::RepoPath(const string_view_type& path) noexcept : m_path(AZ::IO::Path(path).MakePreferred()) { } - constexpr RepoPath::RepoPath(const value_type* path) noexcept + inline RepoPath::RepoPath(const value_type* path) noexcept : m_path(AZ::IO::Path(path).MakePreferred()) { } - constexpr RepoPath::RepoPath(const AZ::IO::PathView& path) + inline RepoPath::RepoPath(const AZ::IO::PathView& path) : m_path(AZ::IO::Path(path).MakePreferred()) { } - constexpr RepoPath::RepoPath(const AZ::IO::Path& path) + inline RepoPath::RepoPath(const AZ::IO::Path& path) : m_path(AZ::IO::Path(path).MakePreferred()) { } From 20e268930ca72de7be5c4024792b9aaa20025364 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:21:20 -0800 Subject: [PATCH 19/42] Correct use of the `typename` keyword Signed-off-by: Chris Burel --- .../Include/TestImpactFramework/TestImpactRepoPath.h | 4 ++-- .../Process/JobRunner/TestImpactProcessJobRunner.h | 10 +++++----- .../Code/Source/TestEngine/TestImpactTestEngine.cpp | 4 ++-- .../TestImpactClientSequenceReportSerializer.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h index eede3e5968..0cd01f73aa 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Include/TestImpactFramework/TestImpactRepoPath.h @@ -52,11 +52,11 @@ namespace TestImpact // Wrappers around the AZ::IO::Path concatenation operator friend RepoPath operator/(const RepoPath& lhs, const AZ::IO::PathView& rhs); friend RepoPath operator/(const RepoPath& lhs, AZStd::string_view rhs); - friend RepoPath operator/(const RepoPath& lhs, const typename value_type* rhs); + friend RepoPath operator/(const RepoPath& lhs, const value_type* rhs); friend RepoPath operator/(const RepoPath& lhs, const RepoPath& rhs); RepoPath& operator/=(const AZ::IO::PathView& rhs); RepoPath& operator/=(AZStd::string_view rhs); - RepoPath& operator/=(const typename value_type* rhs); + RepoPath& operator/=(const value_type* rhs); RepoPath& operator/=(const RepoPath& rhs); friend bool operator==(const RepoPath& lhs, const RepoPath& rhs) noexcept; diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/JobRunner/TestImpactProcessJobRunner.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/JobRunner/TestImpactProcessJobRunner.h index 8144615aeb..c46edbbfb7 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/JobRunner/TestImpactProcessJobRunner.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/JobRunner/TestImpactProcessJobRunner.h @@ -58,14 +58,14 @@ namespace TestImpact //! @param payloadMapProducer The client callback to be called when all jobs have finished to transform the work produced by each job into the desired output. //! @param jobCallback The client callback to be called when each job changes state. //! @return The result of the run sequence and the jobs with their associated payloads. - AZStd::pair> Execute( + AZStd::pair> Execute( const AZStd::vector& jobs, PayloadMapProducer payloadMapProducer, StdOutputRouting stdOutRouting, StdErrorRouting stdErrRouting, AZStd::optional jobTimeout, AZStd::optional runnerTimeout, - JobCallback jobCallback); + JobCallback jobCallback); private: ProcessScheduler m_processScheduler; @@ -82,17 +82,17 @@ namespace TestImpact } template - AZStd::pair> JobRunner::Execute( + AZStd::pair> JobRunner::Execute( const AZStd::vector& jobInfos, PayloadMapProducer payloadMapProducer, StdOutputRouting stdOutRouting, StdErrorRouting stdErrRouting, AZStd::optional jobTimeout, AZStd::optional runnerTimeout, - JobCallback jobCallback) + JobCallback jobCallback) { AZStd::vector processes; - AZStd::unordered_map> metas; + AZStd::unordered_map> metas; AZStd::vector jobs; jobs.reserve(jobInfos.size()); processes.reserve(jobInfos.size()); diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp index c84700065f..e5269a5769 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp @@ -162,7 +162,7 @@ namespace TestImpact { } - [[nodiscard]] ProcessCallbackResult operator()(const typename JobInfo& jobInfo, const TestImpact::JobMeta& meta) + [[nodiscard]] ProcessCallbackResult operator()(const JobInfo& jobInfo, const TestImpact::JobMeta& meta) { const auto id = jobInfo.GetId().m_value; const auto& args = jobInfo.GetCommand().m_args; @@ -189,7 +189,7 @@ namespace TestImpact private: const AZStd::vector& m_testTargets; - TestEngineJobMap* m_engineJobs; + TestEngineJobMap* m_engineJobs; Policy::ExecutionFailure m_executionFailurePolicy; Policy::TestFailure m_testFailurePolicy; AZStd::optional* m_callback; diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp index 944fd4ac38..46a2d2dab9 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp @@ -775,7 +775,7 @@ namespace TestImpact serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::MaxConcurrency]].GetUint64(), testTargetTimeout ? AZStd::optional{ testTargetTimeout } : AZStd::nullopt, globalTimeout ? AZStd::optional{ globalTimeout } : AZStd::nullopt, - DeserializePolicyStateType(serialSequenceReportBase), + DeserializePolicyStateType(serialSequenceReportBase), SuiteTypeFromString(serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::Suite]].GetString()), DeserializeTestSelection(serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::SelectedTestRuns]]), DeserializeTestRunReport(serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::SelectedTestRunReport]])); From 86aa5093eca9c72415f81a5c4ac0b09953aef52b Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:23:48 -0800 Subject: [PATCH 20/42] Use `enable_if` to control what types can instantiate a template Using a `static_assert(false, ...)` expression in the `else` block of a `if constexpr` statement doesn't work. The `else` block is not protected by the `constexpr`-ness of the `if`s, so it is always compiled. Consequently it will always fail to compile. Signed-off-by: Chris Burel --- .../TestImpactClientSequenceReportSerializer.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp index 46a2d2dab9..65a5c88883 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactClientSequenceReportSerializer.cpp @@ -6,6 +6,7 @@ * */ +#include #include #include #include @@ -735,7 +736,11 @@ namespace TestImpact }; } - template + template, + AZStd::is_same, + AZStd::is_same + >>> PolicyStateType DeserializePolicyStateType(const rapidjson::Value& serialPolicyStateType) { if constexpr (AZStd::is_same_v) @@ -750,10 +755,6 @@ namespace TestImpact { return DeserializeImpactAnalysisSequencePolicyStateMembers(serialPolicyStateType); } - else - { - static_assert(false, "Template paramater must be a valid policy state type"); - } } template From be785dbae863a8d7b55680beb98f041cff842065 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:30:09 -0800 Subject: [PATCH 21/42] Correct the signature for the copy constructor of `TestImpact::Pipe` Signed-off-by: Chris Burel --- .../Source/Platform/Windows/Process/TestImpactWin32_Pipe.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Pipe.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Pipe.h index 19c11dd4da..9f55ad6074 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Pipe.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Platform/Windows/Process/TestImpactWin32_Pipe.h @@ -24,8 +24,8 @@ namespace TestImpact public: Pipe(SECURITY_ATTRIBUTES& sa, HANDLE& stdChannel); Pipe(Pipe&& other) = delete; - Pipe(Pipe& other) = delete; - Pipe& operator=(Pipe& other) = delete; + Pipe(const Pipe& other) = delete; + Pipe& operator=(const Pipe& other) = delete; Pipe& operator=(Pipe&& other) = delete; //! Releases the child end of the pipe (not needed once parent has their end). From 41be03f193c5163b209ba255707b7c804048deeb Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:30:39 -0800 Subject: [PATCH 22/42] Silence warning about unnecessary lambda captures with clang The `unused-lambda-capture` will be triggered by the following code: ```cpp void foo(int); int main() { const int i = 0; auto l = [i](){foo(i);}; } ``` The issue here is that reading from the constant variable `i` does not constitute an ODR-use, and consequently the variable does not have to be captured. See https://github.com/llvm/llvm-project/issues/34213#issuecomment-980987311 for a related discussion. However, MSVC sees it differently. In order to make both compilers happy, mark this variable with `AZ_UNUSED`, since lambda captures can't be marked with attributes like `[[maybe_unused]]`. Signed-off-by: Chris Burel --- .../Source/Artifact/Factory/TestImpactTestRunSuiteFactory.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestRunSuiteFactory.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestRunSuiteFactory.cpp index f39cfaaf10..dfa8c9c49b 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestRunSuiteFactory.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Artifact/Factory/TestImpactTestRunSuiteFactory.cpp @@ -69,6 +69,7 @@ namespace TestImpact const auto getDuration = [Keys](const AZ::rapidxml::xml_node<>* node) AZ_POP_DISABLE_WARNING { + AZ_UNUSED(Keys); // Clang reports a warning that capturing Keys is not necessary because it is not odr-used const AZStd::string duration = node->first_attribute(Keys[DurationKey])->value(); return AZStd::chrono::milliseconds(static_cast(AZStd::stof(duration) * 1000.f)); }; @@ -86,6 +87,7 @@ namespace TestImpact const auto getStatus = [Keys](const AZ::rapidxml::xml_node<>* node) AZ_POP_DISABLE_WARNING { + AZ_UNUSED(Keys); // Clang reports a warning that capturing Keys is not necessary because it is not odr-used const AZStd::string status = node->first_attribute(Keys[StatusKey])->value(); if (status == Keys[RunKey]) { From 872f2a0cfad5658f8cdf37c598f3e275fa37cf49 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:30:54 -0800 Subject: [PATCH 23/42] Remove unused private class member Signed-off-by: Chris Burel --- .../Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp | 3 +-- .../Runtime/Code/Source/TestEngine/TestImpactTestEngine.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp index e5269a5769..75f02982c0 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.cpp @@ -239,8 +239,7 @@ namespace TestImpact const RepoPath& testRunnerBinary, const RepoPath& instrumentBinary, size_t maxConcurrentRuns) - : m_maxConcurrentRuns(maxConcurrentRuns) - , m_testJobInfoGenerator(AZStd::make_unique( + : m_testJobInfoGenerator(AZStd::make_unique( sourceDir, targetBinaryDir, cacheDir, artifactDir, testRunnerBinary, instrumentBinary)) , m_testEnumerator(AZStd::make_unique(maxConcurrentRuns)) , m_instrumentedTestRunner(AZStd::make_unique(maxConcurrentRuns)) diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.h index 6b097f241f..bba94e38b3 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.h +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/TestImpactTestEngine.h @@ -117,7 +117,6 @@ namespace TestImpact //! Cleans up the artifacts directory of any artifacts from previous runs. void DeleteArtifactXmls() const; - size_t m_maxConcurrentRuns = 0; AZStd::unique_ptr m_testJobInfoGenerator; AZStd::unique_ptr m_testEnumerator; AZStd::unique_ptr m_instrumentedTestRunner; From ca297fdf38c2c4a0ae3df6c4f8a6ba69e648c9f1 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 10 Feb 2022 15:31:24 -0800 Subject: [PATCH 24/42] Remove unused variables Signed-off-by: Chris Burel --- Code/Editor/Util/3DConnexionDriver.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Code/Editor/Util/3DConnexionDriver.cpp b/Code/Editor/Util/3DConnexionDriver.cpp index 9dc1600185..c0d4393b49 100644 --- a/Code/Editor/Util/3DConnexionDriver.cpp +++ b/Code/Editor/Util/3DConnexionDriver.cpp @@ -116,9 +116,6 @@ bool C3DConnexionDriver::GetInputMessageData(LPARAM lParam, S3DConnexionMessage& { if (event->header.dwType == RIM_TYPEHID) { - static bool bGotTranslation = false, - bGotRotation = false; - static int all6DOFs[6] = {0}; LPRAWHID pRawHid = &event->data.hid; // Translation or Rotation packet? They come in two different packets. From bb81dd86eedf97ad98de4f1f9de2298443654c88 Mon Sep 17 00:00:00 2001 From: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> Date: Fri, 11 Feb 2022 18:26:38 -0700 Subject: [PATCH 25/42] Added the DiffuseProbeGridVisualizationCompositePass. Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> --- AutomatedTesting/Passes/MainPipeline.pass | 31 +++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Passes/MainPipeline.pass b/AutomatedTesting/Passes/MainPipeline.pass index 39b992a11d..8ad4006570 100644 --- a/AutomatedTesting/Passes/MainPipeline.pass +++ b/AutomatedTesting/Passes/MainPipeline.pass @@ -460,6 +460,33 @@ } ] }, + { + "Name": "DiffuseProbeGridVisualizationCompositePass", + "TemplateName": "DiffuseProbeGridVisualizationCompositePassTemplate", + "Connections": [ + { + "LocalSlot": "VisualizationInput", + "AttachmentRef": { + "Pass": "OpaquePass", + "Attachment": "DiffuseProbeGridVisualization" + } + }, + { + "LocalSlot": "Depth", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + }, + { + "LocalSlot": "ColorInputOutput", + "AttachmentRef": { + "Pass": "PostProcessPass", + "Attachment": "Output" + } + } + ] + }, { "Name": "AuxGeomPass", "TemplateName": "AuxGeomPassTemplate", @@ -468,8 +495,8 @@ { "LocalSlot": "ColorInputOutput", "AttachmentRef": { - "Pass": "PostProcessPass", - "Attachment": "Output" + "Pass": "DiffuseProbeGridVisualizationCompositePass", + "Attachment": "ColorInputOutput" } }, { From 0e204163a6ac69b599c391ee92a1be8cc9bfa854 Mon Sep 17 00:00:00 2001 From: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> Date: Mon, 14 Feb 2022 09:59:20 -0600 Subject: [PATCH 26/42] Adds support for additional VS debugger args Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> --- Code/LauncherUnified/launcher_generator.cmake | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake index 70bcf776af..fe0f5e1f85 100644 --- a/Code/LauncherUnified/launcher_generator.cmake +++ b/Code/LauncherUnified/launcher_generator.cmake @@ -124,7 +124,9 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC # After ensuring that we correctly support DPI scaling, this should be switched to "PerMonitor" set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DPI_AWARE "OFF") if(LY_DEFAULT_PROJECT_PATH) - set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\"") + get_property(project_game_launcher_additional_args GLOBAL PROPERTY ${project_name}_GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) + set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS + "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${project_game_launcher_additional_args}") endif() # Associate the Clients Gem Variant with each projects GameLauncher @@ -173,7 +175,9 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC ) if(LY_DEFAULT_PROJECT_PATH) - set_property(TARGET ${project_name}.ServerLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\"") + get_property(project_server_launcher_additional_args GLOBAL PROPERTY ${project_name}_SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) + set_property(TARGET ${project_name}.ServerLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS + "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${project_server_launcher_additional_args}") endif() # Associate the Servers Gem Variant with each projects ServerLauncher From 78ed8baf36fcc05e9d3c3f1a01a9042bdf0b5b14 Mon Sep 17 00:00:00 2001 From: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> Date: Mon, 14 Feb 2022 10:27:45 -0600 Subject: [PATCH 27/42] Refactored from global to target property Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> --- Code/LauncherUnified/launcher_generator.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake index fe0f5e1f85..b35493e55f 100644 --- a/Code/LauncherUnified/launcher_generator.cmake +++ b/Code/LauncherUnified/launcher_generator.cmake @@ -124,7 +124,7 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC # After ensuring that we correctly support DPI scaling, this should be switched to "PerMonitor" set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DPI_AWARE "OFF") if(LY_DEFAULT_PROJECT_PATH) - get_property(project_game_launcher_additional_args GLOBAL PROPERTY ${project_name}_GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) + get_target_property(project_game_launcher_additional_args ${project_name} GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${project_game_launcher_additional_args}") endif() @@ -175,7 +175,7 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC ) if(LY_DEFAULT_PROJECT_PATH) - get_property(project_server_launcher_additional_args GLOBAL PROPERTY ${project_name}_SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) + get_target_property(project_server_launcher_additional_args ${project_name} SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) set_property(TARGET ${project_name}.ServerLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${project_server_launcher_additional_args}") endif() From db999dda6f3c8480180d1c368ce1aa9547fc32b8 Mon Sep 17 00:00:00 2001 From: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> Date: Mon, 14 Feb 2022 11:01:09 -0600 Subject: [PATCH 28/42] Additional checks for presence of vs debugger command argumnets property Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> --- Code/LauncherUnified/launcher_generator.cmake | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake index b35493e55f..9078f9a3c5 100644 --- a/Code/LauncherUnified/launcher_generator.cmake +++ b/Code/LauncherUnified/launcher_generator.cmake @@ -124,9 +124,17 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC # After ensuring that we correctly support DPI scaling, this should be switched to "PerMonitor" set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DPI_AWARE "OFF") if(LY_DEFAULT_PROJECT_PATH) + if (TARGET ${project_name}) + get_target_property(project_game_launcher_additional_args ${project_name} GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) + if (project_game_launcher_additional_args) + # Avoid pushing param-NOTFOUND into the argument in case this property wasn't found + set(additional_game_vs_debugger_args "${project_game_launcher_additional_args}") + endif() + endif() + get_target_property(project_game_launcher_additional_args ${project_name} GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS - "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${project_game_launcher_additional_args}") + "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${additional_game_vs_debugger_args}") endif() # Associate the Clients Gem Variant with each projects GameLauncher @@ -175,9 +183,16 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC ) if(LY_DEFAULT_PROJECT_PATH) - get_target_property(project_server_launcher_additional_args ${project_name} SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) + if (TARGET ${project_name}) + get_target_property(project_server_launcher_additional_args ${project_name} SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) + if (project_server_launcher_additional_args) + # Avoid pushing param-NOTFOUND into the argument in case this property wasn't found + set(additional_server_vs_debugger_args "${project_server_launcher_additional_args}") + endif() + endif() + set_property(TARGET ${project_name}.ServerLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS - "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${project_server_launcher_additional_args}") + "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${additional_server_vs_debugger_args}") endif() # Associate the Servers Gem Variant with each projects ServerLauncher From da421b7056eeeaeb1869d3c22c5acf5c6bcd3096 Mon Sep 17 00:00:00 2001 From: Roman <69218254+amzn-rhhong@users.noreply.github.com> Date: Mon, 14 Feb 2022 13:27:37 -0800 Subject: [PATCH 29/42] Change actorRenderFlag to use AZ ENUM CLASS instead of azstd::bitset (#7542) * Fixes the problem with using actor render flags in actor component Signed-off-by: rhhong * In progress work for actor render flag rework Signed-off-by: rhhong * add an utlity function to check bit Signed-off-by: rhhong * code cleanup Signed-off-by: rhhong * More CR cleanup Signed-off-by: rhhong * build fix Signed-off-by: rhhong * CR feedback Signed-off-by: rhhong --- .../Code/Source/AtomActorDebugDraw.cpp | 30 ++--- .../Code/Source/AtomActorDebugDraw.h | 2 +- .../Code/Source/AtomActorInstance.cpp | 2 +- .../Code/Source/AtomActorInstance.h | 2 +- .../Tools/EMStudio/AnimViewportRenderer.cpp | 2 +- .../Tools/EMStudio/AnimViewportRenderer.h | 2 +- .../Tools/EMStudio/AnimViewportRequestBus.h | 2 +- .../Tools/EMStudio/AnimViewportToolBar.cpp | 46 ++++---- .../Code/Tools/EMStudio/AnimViewportToolBar.h | 4 +- .../Tools/EMStudio/AnimViewportWidget.cpp | 2 +- .../Code/Tools/EMStudio/AnimViewportWidget.h | 2 +- .../Code/Tools/EMStudio/AtomRenderPlugin.cpp | 2 +- .../Code/Tools/EMStudio/AtomRenderPlugin.h | 2 +- .../EMStudioSDK/Source/EMStudioPlugin.h | 2 +- .../Source/RenderPlugin/RenderOptions.cpp | 25 ++--- .../Source/RenderPlugin/RenderOptions.h | 8 +- .../Cloth/ClothJointInspectorPlugin.cpp | 5 +- .../Plugins/Cloth/ClothJointInspectorPlugin.h | 2 +- .../HitDetectionJointInspectorPlugin.cpp | 5 +- .../HitDetectionJointInspectorPlugin.h | 2 +- .../Ragdoll/RagdollNodeInspectorPlugin.cpp | 6 +- .../Ragdoll/RagdollNodeInspectorPlugin.h | 2 +- .../SimulatedObject/SimulatedObjectWidget.cpp | 8 +- .../SimulatedObject/SimulatedObjectWidget.h | 2 +- .../Integration/Components/ActorComponent.cpp | 50 +++++---- .../Integration/Components/ActorComponent.h | 7 +- .../Components/EditorActorComponent.cpp | 45 +++++--- .../Editor/Components/EditorActorComponent.h | 7 +- .../Rendering/RenderActorInstance.h | 2 +- .../Source/Integration/Rendering/RenderFlag.h | 105 +++++++++++++----- .../Code/Tests/RenderBackendManagerTests.cpp | 2 +- 31 files changed, 217 insertions(+), 168 deletions(-) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp index deb668d12a..24134b2d17 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.cpp @@ -33,7 +33,7 @@ namespace AZ::Render m_auxGeomFeatureProcessor = RPI::Scene::GetFeatureProcessorForEntity(entityId); } - void AtomActorDebugDraw::DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags, EMotionFX::ActorInstance* instance) + void AtomActorDebugDraw::DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags, EMotionFX::ActorInstance* instance) { if (!m_auxGeomFeatureProcessor || !instance) { @@ -46,10 +46,12 @@ namespace AZ::Render return; } + using AZ::RHI::CheckBitsAny; + // Update the mesh deformers (perform cpu skinning and morphing) when needed. - if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_AABB] || renderFlags[EMotionFX::ActorRenderFlag::RENDER_FACENORMALS] || - renderFlags[EMotionFX::ActorRenderFlag::RENDER_TANGENTS] || renderFlags[EMotionFX::ActorRenderFlag::RENDER_VERTEXNORMALS] || - renderFlags[EMotionFX::ActorRenderFlag::RENDER_WIREFRAME]) + if (CheckBitsAny(renderFlags, + EMotionFX::ActorRenderFlags::AABB | EMotionFX::ActorRenderFlags::FaceNormals | EMotionFX::ActorRenderFlags::Tangents | + EMotionFX::ActorRenderFlags::VertexNormals | EMotionFX::ActorRenderFlags::Wireframe)) { instance->UpdateMeshDeformers(0.0f, true); } @@ -61,7 +63,7 @@ namespace AZ::Render const float scaleMultiplier = CalculateScaleMultiplier(instance); // Render aabb - if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_AABB]) + if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::AABB)) { RenderAABB(instance, renderActorSettings.m_enabledNodeBasedAabb, renderActorSettings.m_nodeAABBColor, @@ -70,39 +72,39 @@ namespace AZ::Render } // Render simple line skeleton - if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_LINESKELETON]) + if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::LineSkeleton)) { RenderLineSkeleton(instance, renderActorSettings.m_lineSkeletonColor); } // Render advanced skeleton - if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_SKELETON]) + if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::Skeleton)) { RenderSkeleton(instance, renderActorSettings.m_skeletonColor); } - if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_NODENAMES]) + if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::NodeNames)) { RenderJointNames(instance, viewport, renderActorSettings.m_jointNameColor); } // Render internal EMFX debug lines. - if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_EMFX_DEBUG]) + if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::EmfxDebug)) { RenderEMFXDebugDraw(instance); } // Render - if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_NODEORIENTATION]) + if (CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::NodeOrientation)) { RenderNodeOrientations(instance, debugDisplay, renderActorSettings.m_nodeOrientationScale * scaleMultiplier); } // Render vertex normal, face normal, tagent and wireframe. - const bool renderVertexNormals = renderFlags[EMotionFX::ActorRenderFlag::RENDER_VERTEXNORMALS]; - const bool renderFaceNormals = renderFlags[EMotionFX::ActorRenderFlag::RENDER_FACENORMALS]; - const bool renderTangents = renderFlags[EMotionFX::ActorRenderFlag::RENDER_TANGENTS]; - const bool renderWireframe = renderFlags[EMotionFX::ActorRenderFlag::RENDER_WIREFRAME]; + const bool renderVertexNormals = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::VertexNormals); + const bool renderFaceNormals = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::FaceNormals); + const bool renderTangents = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::Tangents); + const bool renderWireframe = CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::Wireframe); if (renderVertexNormals || renderFaceNormals || renderTangents || renderWireframe) { diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h index 8e985fdbc6..53086801c7 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorDebugDraw.h @@ -40,7 +40,7 @@ namespace AZ::Render public: AtomActorDebugDraw(AZ::EntityId entityId); - void DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags, EMotionFX::ActorInstance* instance); + void DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags, EMotionFX::ActorInstance* instance); private: diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp index 35aea57702..f0b46255fe 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp @@ -79,7 +79,7 @@ namespace AZ::Render UpdateBounds(); } - void AtomActorInstance::DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags) + void AtomActorInstance::DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags) { m_atomActorDebugDraw->DebugDraw(renderFlags, m_actorInstance); } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h index 73d428216c..2eeb61c812 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h @@ -86,7 +86,7 @@ namespace AZ // RenderActorInstance overrides ... void OnTick(float timeDelta) override; - void DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags); + void DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags); void UpdateBounds() override; void SetMaterials(const EMotionFX::Integration::ActorAsset::MaterialList& materialPerLOD) override { AZ_UNUSED(materialPerLOD); }; void SetSkinningMethod(EMotionFX::Integration::SkinningMethod emfxSkinningMethod) override; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp index 6ac2a66261..63a0554e37 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp @@ -191,7 +191,7 @@ namespace EMStudio return result; } - void AnimViewportRenderer::UpdateActorRenderFlag(EMotionFX::ActorRenderFlagBitset renderFlags) + void AnimViewportRenderer::UpdateActorRenderFlag(EMotionFX::ActorRenderFlags renderFlags) { for (AZ::Entity* entity : m_actorEntities) { diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h index 0066c222db..3f34d2f26e 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h @@ -54,7 +54,7 @@ namespace EMStudio //! Return the center position of the existing objects. AZ::Vector3 GetCharacterCenter() const; - void UpdateActorRenderFlag(EMotionFX::ActorRenderFlagBitset renderFlags); + void UpdateActorRenderFlag(EMotionFX::ActorRenderFlags renderFlags); AZStd::shared_ptr GetFrameworkScene() const; AZ::EntityId GetEntityId() const; AzFramework::EntityContextId GetEntityContextId() const; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRequestBus.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRequestBus.h index 9b2fc0b212..91de0882bc 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRequestBus.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRequestBus.h @@ -26,7 +26,7 @@ namespace EMStudio virtual void UpdateCameraFollowUp(bool followUp) = 0; //! Update render flags - virtual void UpdateRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags) = 0; + virtual void UpdateRenderFlags(EMotionFX::ActorRenderFlags renderFlags) = 0; }; using AnimViewportRequestBus = AZ::EBus; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp index d9de41f54b..e2c011fcde 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp @@ -61,35 +61,35 @@ namespace EMStudio renderOptionsButton->setIcon(QIcon(":/EMotionFXAtom/Visualization.svg")); addWidget(renderOptionsButton); - CreateViewOptionEntry(contextMenu, "Solid", EMotionFX::ActorRenderFlag::RENDER_SOLID); - CreateViewOptionEntry(contextMenu, "Wireframe", EMotionFX::ActorRenderFlag::RENDER_WIREFRAME); + CreateViewOptionEntry(contextMenu, "Solid", EMotionFX::ActorRenderFlagIndex::SOLID); + CreateViewOptionEntry(contextMenu, "Wireframe", EMotionFX::ActorRenderFlagIndex::WIREFRAME); // [EMFX-TODO] Add those option once implemented. - // CreateViewOptionEntry(contextMenu, "Lighting", EMotionFX::ActorRenderFlag::RENDER_LIGHTING); - // CreateViewOptionEntry(contextMenu, "Backface Culling", EMotionFX::ActorRenderFlag::RENDER_BACKFACECULLING); + // CreateViewOptionEntry(contextMenu, "Lighting", EMotionFX::ActorRenderFlagIndex::RENDER_LIGHTING); + // CreateViewOptionEntry(contextMenu, "Backface Culling", EMotionFX::ActorRenderFlagIndex::RENDER_BACKFACECULLING); contextMenu->addSeparator(); - CreateViewOptionEntry(contextMenu, "Vertex Normals", EMotionFX::ActorRenderFlag::RENDER_VERTEXNORMALS); - CreateViewOptionEntry(contextMenu, "Face Normals", EMotionFX::ActorRenderFlag::RENDER_FACENORMALS); - CreateViewOptionEntry(contextMenu, "Tangents", EMotionFX::ActorRenderFlag::RENDER_TANGENTS); - CreateViewOptionEntry(contextMenu, "Actor Bounding Boxes", EMotionFX::ActorRenderFlag::RENDER_AABB); + CreateViewOptionEntry(contextMenu, "Vertex Normals", EMotionFX::ActorRenderFlagIndex::VERTEXNORMALS); + CreateViewOptionEntry(contextMenu, "Face Normals", EMotionFX::ActorRenderFlagIndex::FACENORMALS); + CreateViewOptionEntry(contextMenu, "Tangents", EMotionFX::ActorRenderFlagIndex::TANGENTS); + CreateViewOptionEntry(contextMenu, "Actor Bounding Boxes", EMotionFX::ActorRenderFlagIndex::AABB); contextMenu->addSeparator(); - CreateViewOptionEntry(contextMenu, "Line Skeleton", EMotionFX::ActorRenderFlag::RENDER_LINESKELETON); - CreateViewOptionEntry(contextMenu, "Solid Skeleton", EMotionFX::ActorRenderFlag::RENDER_SKELETON); - CreateViewOptionEntry(contextMenu, "Joint Names", EMotionFX::ActorRenderFlag::RENDER_NODENAMES); - CreateViewOptionEntry(contextMenu, "Joint Orientations", EMotionFX::ActorRenderFlag::RENDER_NODEORIENTATION); + CreateViewOptionEntry(contextMenu, "Line Skeleton", EMotionFX::ActorRenderFlagIndex::LINESKELETON); + CreateViewOptionEntry(contextMenu, "Solid Skeleton", EMotionFX::ActorRenderFlagIndex::SKELETON); + CreateViewOptionEntry(contextMenu, "Joint Names", EMotionFX::ActorRenderFlagIndex::NODENAMES); + CreateViewOptionEntry(contextMenu, "Joint Orientations", EMotionFX::ActorRenderFlagIndex::NODEORIENTATION); // [EMFX-TODO] Add those option once implemented. - // CreateViewOptionEntry(contextMenu, "Actor Bind Pose", EMotionFX::ActorRenderFlag::RENDER_ACTORBINDPOSE); + // CreateViewOptionEntry(contextMenu, "Actor Bind Pose", EMotionFX::ActorRenderFlagIndex::RENDER_ACTORBINDPOSE); contextMenu->addSeparator(); - CreateViewOptionEntry(contextMenu, "Hit Detection Colliders", EMotionFX::ActorRenderFlag::RENDER_HITDETECTION_COLLIDERS, true, + CreateViewOptionEntry(contextMenu, "Hit Detection Colliders", EMotionFX::ActorRenderFlagIndex::HITDETECTION_COLLIDERS, true, ":/EMotionFXAtom/HitDetection.svg"); - CreateViewOptionEntry(contextMenu, "Ragdoll Colliders", EMotionFX::ActorRenderFlag::RENDER_RAGDOLL_COLLIDERS, true, + CreateViewOptionEntry(contextMenu, "Ragdoll Colliders", EMotionFX::ActorRenderFlagIndex::RAGDOLL_COLLIDERS, true, ":/EMotionFXAtom/RagdollCollider.svg"); - CreateViewOptionEntry(contextMenu, "Ragdoll Joint Limits", EMotionFX::ActorRenderFlag::RENDER_RAGDOLL_JOINTLIMITS, true, + CreateViewOptionEntry(contextMenu, "Ragdoll Joint Limits", EMotionFX::ActorRenderFlagIndex::RAGDOLL_JOINTLIMITS, true, ":/EMotionFXAtom/RagdollJointLimit.svg"); - CreateViewOptionEntry(contextMenu, "Cloth Colliders", EMotionFX::ActorRenderFlag::RENDER_CLOTH_COLLIDERS, true, + CreateViewOptionEntry(contextMenu, "Cloth Colliders", EMotionFX::ActorRenderFlagIndex::CLOTH_COLLIDERS, true, ":/EMotionFXAtom/Cloth.svg"); - CreateViewOptionEntry(contextMenu, "Simulated Object Colliders", EMotionFX::ActorRenderFlag::RENDER_SIMULATEDOBJECT_COLLIDERS, true, + CreateViewOptionEntry(contextMenu, "Simulated Object Colliders", EMotionFX::ActorRenderFlagIndex::SIMULATEDOBJECT_COLLIDERS, true, ":/EMotionFXAtom/SimulatedObjectCollider.svg"); - CreateViewOptionEntry(contextMenu, "Simulated Joints", EMotionFX::ActorRenderFlag::RENDER_SIMULATEJOINTS); + CreateViewOptionEntry(contextMenu, "Simulated Joints", EMotionFX::ActorRenderFlagIndex::SIMULATEJOINTS); } // Add the camera button @@ -158,7 +158,7 @@ namespace EMStudio } void AnimViewportToolBar::CreateViewOptionEntry( - QMenu* menu, const char* menuEntryName, uint32_t actionIndex, bool visible, const char* iconFileName) + QMenu* menu, const char* menuEntryName, AZ::u8 actionIndex, bool visible, const char* iconFileName) { QAction* action = menu->addAction( menuEntryName, @@ -194,13 +194,13 @@ namespace EMStudio m_manipulatorActions[mode]->setChecked(true); } - const EMotionFX::ActorRenderFlagBitset renderFlags = renderOptions->GetRenderFlags(); - for (size_t i = 0; i < renderFlags.size(); ++i) + const EMotionFX::ActorRenderFlags renderFlags = renderOptions->GetRenderFlags(); + for (uint8 i = 0; i < EMotionFX::ActorRenderFlagIndex::NUM_RENDERFLAGINDEXES; ++i) { QAction* action = m_renderActions[i]; if (action) { - action->setChecked(renderFlags[i]); + action->setChecked(EMotionFX::ActorRenderFlagUtil::CheckBit(renderFlags, i)); } } } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h index f516b9df28..08c32429e9 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h @@ -30,11 +30,11 @@ namespace EMStudio private: void CreateViewOptionEntry( - QMenu* menu, const char* menuEntryName, uint32_t actionIndex, bool visible = true, const char* iconFileName = nullptr); + QMenu* menu, const char* menuEntryName, AZ::u8 actionIndex, bool visible = true, const char* iconFileName = nullptr); AtomRenderPlugin* m_plugin = nullptr; QAction* m_manipulatorActions[RenderOptions::ManipulatorMode::NUM_MODES] = { nullptr }; - QAction* m_renderActions[EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS] = { nullptr }; + QAction* m_renderActions[EMotionFX::ActorRenderFlagIndex::NUM_RENDERFLAGINDEXES] = { nullptr }; QAction* m_followCharacterAction = nullptr; }; } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp index 90fbb81e47..c1c891ad97 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp @@ -229,7 +229,7 @@ namespace EMStudio } } - void AnimViewportWidget::UpdateRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags) + void AnimViewportWidget::UpdateRenderFlags(EMotionFX::ActorRenderFlags renderFlags) { m_renderer->UpdateActorRenderFlag(renderFlags); } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h index 9e4a7c5fa7..261c78c755 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.h @@ -45,7 +45,7 @@ namespace EMStudio // AnimViewportRequestBus::Handler overrides void UpdateCameraViewMode(RenderOptions::CameraViewMode mode); void UpdateCameraFollowUp(bool follow); - void UpdateRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags); + void UpdateRenderFlags(EMotionFX::ActorRenderFlags renderFlags); // ViewportPluginRequestBus::Handler overrides AZ::s32 GetViewportId() const; diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp index 5b3f305cd0..32298d740f 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.cpp @@ -300,7 +300,7 @@ namespace EMStudio return &m_renderOptions; } - void AtomRenderPlugin::Render([[maybe_unused]]EMotionFX::ActorRenderFlagBitset renderFlags) + void AtomRenderPlugin::Render([[maybe_unused]]EMotionFX::ActorRenderFlags renderFlags) { if (!m_animViewportWidget) { diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h index 2207690628..66e89dfc45 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AtomRenderPlugin.h @@ -61,7 +61,7 @@ namespace EMStudio void SaveRenderOptions(); RenderOptions* GetRenderOptions(); - void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override; + void Render(EMotionFX::ActorRenderFlags renderFlags) override; void SetManipulatorMode(RenderOptions::ManipulatorMode mode); private: diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h index 2dc86ba01b..1d6bd55290 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h @@ -96,7 +96,7 @@ namespace EMStudio virtual void LegacyRender(RenderPlugin* renderPlugin, RenderInfo* renderInfo) { MCORE_UNUSED(renderPlugin); MCORE_UNUSED(renderInfo); } //! Render function will call atom auxGeom internally to render. This is the replacement for LegacyRender function. - virtual void Render(EMotionFX::ActorRenderFlagBitset renderFlags) + virtual void Render(EMotionFX::ActorRenderFlags renderFlags) { AZ_UNUSED(renderFlags); }; diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp index 7adea15a99..4c3b9d1a93 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.cpp @@ -255,12 +255,7 @@ namespace EMStudio settings->setValue("cameraFollowUp", m_cameraFollowUp); // Save render flags - settings->beginGroup("renderFlags"); - for (uint32 i = 0; i < EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS; ++i) - { - settings->setValue(QString(i), (bool)m_renderFlags[i]); - } - settings->endGroup(); + settings->setValue("renderFlags", static_cast(m_renderFlags)); } RenderOptions RenderOptions::Load(QSettings* settings) @@ -333,14 +328,8 @@ namespace EMStudio options.m_cameraFollowUp = settings->value("CameraFollowUp", options.m_cameraFollowUp).toBool(); // Read render flags - settings->beginGroup("renderFlags"); - for (uint32 i = 0; i < EMotionFX::ActorRenderFlag::NUM_RENDERFLAGS; ++i) - { - const bool defaultValue = (i == EMotionFX::ActorRenderFlag::RENDER_SOLID); - const bool isEnabled = settings->value(QString(i), defaultValue).toBool(); - options.m_renderFlags[i] = isEnabled; - } - settings->endGroup(); + options.m_renderFlags = + EMotionFX::ActorRenderFlags(settings->value("RenderFlags", static_cast(EMotionFX::ActorRenderFlags::Default)).toInt()); options.CopyToRenderActorSettings(EMotionFX::GetRenderActorSettings()); @@ -1104,17 +1093,17 @@ namespace EMStudio return m_cameraFollowUp; } - void RenderOptions::ToggerRenderFlag(int index) + void RenderOptions::ToggerRenderFlag(uint8 index) { - m_renderFlags[index] = !m_renderFlags[index]; + m_renderFlags ^= EMotionFX::ActorRenderFlags(AZ_BIT(index)); } - void RenderOptions::SetRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags) + void RenderOptions::SetRenderFlags(EMotionFX::ActorRenderFlags renderFlags) { m_renderFlags = renderFlags; } - EMotionFX::ActorRenderFlagBitset RenderOptions::GetRenderFlags() const + EMotionFX::ActorRenderFlags RenderOptions::GetRenderFlags() const { return m_renderFlags; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h index 3c5dbcaba1..09b23cab08 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderOptions.h @@ -284,9 +284,9 @@ namespace EMStudio void SetCameraFollowUp(bool followUp); bool GetCameraFollowUp() const; - void ToggerRenderFlag(int index); - void SetRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags); - EMotionFX::ActorRenderFlagBitset GetRenderFlags() const; + void ToggerRenderFlag(uint8 index); + void SetRenderFlags(EMotionFX::ActorRenderFlags renderFlags); + EMotionFX::ActorRenderFlags GetRenderFlags() const; private: void OnGridUnitSizeChangedCallback() const; @@ -406,7 +406,7 @@ namespace EMStudio ManipulatorMode m_manipulatorMode = ManipulatorMode::SELECT; CameraViewMode m_cameraViewMode = CameraViewMode::DEFAULT; bool m_cameraFollowUp = false; - EMotionFX::ActorRenderFlagBitset m_renderFlags; + EMotionFX::ActorRenderFlags m_renderFlags; }; } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.cpp b/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.cpp index 161cc2ac95..a89f9fdb85 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.cpp +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.cpp @@ -196,10 +196,9 @@ namespace EMotionFX renderInfo); } - void ClothJointInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags) + void ClothJointInspectorPlugin::Render(EMotionFX::ActorRenderFlags renderFlags) { - const bool renderColliders = renderFlags[RENDER_CLOTH_COLLIDERS]; - if (!renderColliders) + if (!AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::ClothColliders)) { return; } diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.h b/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.h index c1b3e9ad13..d220d4ca44 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.h +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/Cloth/ClothJointInspectorPlugin.h @@ -48,7 +48,7 @@ namespace EMotionFX void OnContextMenu(QMenu* menu, const QModelIndexList& selectedRowIndices) override; void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override; - void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override; + void Render(EMotionFX::ActorRenderFlags renderFlags) override; static bool IsJointInCloth(const QModelIndex& index); public slots: diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.cpp b/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.cpp index 0f0eb89bfc..74534927c3 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.cpp +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.cpp @@ -181,10 +181,9 @@ namespace EMotionFX renderInfo); } - void HitDetectionJointInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags) + void HitDetectionJointInspectorPlugin::Render(EMotionFX::ActorRenderFlags renderFlags) { - const bool renderColliders = renderFlags[EMotionFX::ActorRenderFlag::RENDER_HITDETECTION_COLLIDERS]; - if (!renderColliders) + if (!AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::HitDetectionColliders)) { return; } diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.h b/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.h index 4dc61f9b9e..2b3daeb7db 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.h +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/HitDetection/HitDetectionJointInspectorPlugin.h @@ -44,7 +44,7 @@ namespace EMotionFX void OnContextMenu(QMenu* menu, const QModelIndexList& selectedRowIndices) override; void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override; - void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override; + void Render(EMotionFX::ActorRenderFlags renderFlags) override; public slots: void OnAddCollider(); diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.cpp b/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.cpp index e76cf42c44..eb8a22021b 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.cpp +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.cpp @@ -595,10 +595,10 @@ namespace EMotionFX renderInfo->m_renderUtil->RenderArrow(0.1f, jointChildWorldSpaceTransformNoScale.m_position, MCore::GetRight(jointChildWorldSpaceTransformNoScale.ToAZTransform()), color); } - void RagdollNodeInspectorPlugin::Render(EMotionFX::ActorRenderFlagBitset renderFlags) + void RagdollNodeInspectorPlugin::Render(EMotionFX::ActorRenderFlags renderFlags) { - const bool renderColliders = renderFlags[RENDER_RAGDOLL_COLLIDERS]; - const bool renderJointLimits = renderFlags[RENDER_RAGDOLL_JOINTLIMITS]; + const bool renderColliders = AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::RagdollColliders); + const bool renderJointLimits = AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::RagdollJointLimits); if (!renderColliders && !renderJointLimits) { return; diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.h b/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.h index d3b27da5ce..4742bfb889 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.h +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/Ragdoll/RagdollNodeInspectorPlugin.h @@ -74,7 +74,7 @@ namespace EMotionFX const MCore::RGBAColor& color); //! Those function replaces legacyRender function and calls atom auxGeom render internally. - void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override; + void Render(EMotionFX::ActorRenderFlags renderFlags) override; void RenderRagdoll( ActorInstance* actorInstance, bool renderColliders, diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.cpp b/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.cpp index 695603cecb..7a11402611 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.cpp +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.cpp @@ -570,7 +570,7 @@ namespace EMotionFX drawData->Unlock(); } - void SimulatedObjectWidget::Render(EMotionFX::ActorRenderFlagBitset renderFlags) + void SimulatedObjectWidget::Render(EMotionFX::ActorRenderFlags renderFlags) { if (!m_actor || !m_actorInstance) { @@ -578,9 +578,8 @@ namespace EMotionFX } const AZ::Render::RenderActorSettings& settings = EMotionFX::GetRenderActorSettings(); - const bool renderSimulatedJoints = renderFlags[RENDER_SIMULATEJOINTS]; const AZStd::unordered_set& selectedJointIndices = EMStudio::GetManager()->GetSelectedJointIndices(); - if (renderSimulatedJoints && !selectedJointIndices.empty()) + if (AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::SimulatedJoints) && !selectedJointIndices.empty()) { // Render the joint radius. const size_t actorInstanceCount = GetActorManager().GetNumActorInstances(); @@ -613,8 +612,7 @@ namespace EMotionFX } } - const bool renderColliders = renderFlags[RENDER_SIMULATEDOBJECT_COLLIDERS]; - if (renderColliders) + if (AZ::RHI::CheckBitsAny(renderFlags, EMotionFX::ActorRenderFlags::SimulatedObjectColliders)) { ColliderContainerWidget::RenderColliders(PhysicsSetup::SimulatedObjectCollider, settings.m_simulatedObjectColliderColor, settings.m_selectedSimulatedObjectColliderColor); diff --git a/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.h b/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.h index 9662fbc150..a3a6344a09 100644 --- a/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.h +++ b/Gems/EMotionFX/Code/Source/Editor/Plugins/SimulatedObject/SimulatedObjectWidget.h @@ -61,7 +61,7 @@ namespace EMotionFX void LegacyRender(EMStudio::RenderPlugin* renderPlugin, RenderInfo* renderInfo) override; void LegacyRenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color); - void Render(EMotionFX::ActorRenderFlagBitset renderFlags) override; + void Render(EMotionFX::ActorRenderFlags renderFlags) override; void RenderJointRadius(const SimulatedJoint* joint, ActorInstance* actorInstance, const AZ::Color& color); SimulatedObjectModel* GetSimulatedObjectModel() const; diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp index e38e15d124..a44882694f 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -131,7 +132,10 @@ namespace EMotionFX return AZ::Edit::PropertyVisibility::Show; } + ////////////////////////////////////////////////////////////////////////// + AZ_ENUM_DEFINE_REFLECT_UTILITIES(ActorRenderFlags); + void ActorComponent::Configuration::Reflect(AZ::ReflectContext* context) { BoundingBoxConfiguration::Reflect(context); @@ -139,19 +143,19 @@ namespace EMotionFX auto* serializeContext = azrtti_cast(context); if (serializeContext) { + ActorRenderFlagsReflect(*serializeContext); + serializeContext->Class() - ->Version(4) + ->Version(5) ->Field("ActorAsset", &Configuration::m_actorAsset) ->Field("MaterialPerLOD", &Configuration::m_materialPerLOD) - ->Field("RenderSkeleton", &Configuration::m_renderSkeleton) - ->Field("RenderCharacter", &Configuration::m_renderCharacter) - ->Field("RenderBounds", &Configuration::m_renderBounds) ->Field("AttachmentType", &Configuration::m_attachmentType) ->Field("AttachmentTarget", &Configuration::m_attachmentTarget) ->Field("SkinningMethod", &Configuration::m_skinningMethod) ->Field("LODLevel", &Configuration::m_lodLevel) ->Field("BoundingBoxConfig", &Configuration::m_bboxConfig) ->Field("ForceJointsUpdateOOV", &Configuration::m_forceUpdateJointsOOV) + ->Field("RenderFlags", &Configuration::m_renderFlags) ; } } @@ -250,8 +254,6 @@ namespace EMotionFX { m_configuration = *configuration; } - - m_debugRenderFlags[RENDER_SOLID] = true; } ////////////////////////////////////////////////////////////////////////// @@ -344,20 +346,24 @@ namespace EMotionFX ////////////////////////////////////////////////////////////////////////// bool ActorComponent::GetRenderCharacter() const { - return m_configuration.m_renderCharacter; + return AZ::RHI::CheckBitsAny(m_configuration.m_renderFlags, ActorRenderFlags::Solid); } ////////////////////////////////////////////////////////////////////////// void ActorComponent::SetRenderCharacter(bool enable) { - if (m_configuration.m_renderCharacter != enable) + if (enable) + { + m_configuration.m_renderFlags |= ActorRenderFlags::Solid; + } + else { - m_configuration.m_renderCharacter = enable; + m_configuration.m_renderFlags &= ~ActorRenderFlags::Solid; + } - if (m_renderActorInstance) - { - m_renderActorInstance->SetIsVisible(m_configuration.m_renderCharacter); - } + if (m_renderActorInstance) + { + m_renderActorInstance->SetIsVisible(enable); } } @@ -394,9 +400,9 @@ namespace EMotionFX return m_sceneFinishSimHandler.IsConnected(); } - void ActorComponent::SetRenderFlag(ActorRenderFlagBitset renderFlags) + void ActorComponent::SetRenderFlag(ActorRenderFlags renderFlags) { - m_debugRenderFlags = renderFlags; + m_configuration.m_renderFlags = renderFlags; } void ActorComponent::CheckActorCreation() @@ -456,7 +462,7 @@ namespace EMotionFX if (m_renderActorInstance) { - m_renderActorInstance->SetIsVisible(m_configuration.m_renderCharacter); + m_renderActorInstance->SetIsVisible(AZ::RHI::CheckBitsAny(m_configuration.m_renderFlags, ActorRenderFlags::Solid)); } } @@ -563,22 +569,18 @@ namespace EMotionFX m_renderActorInstance->OnTick(deltaTime); m_renderActorInstance->UpdateBounds(); AZ::Interface::Get()->RefreshEntityLocalBoundsUnion(GetEntityId()); + const bool renderActorSolid = AZ::RHI::CheckBitsAny(m_configuration.m_renderFlags, ActorRenderFlags::Solid); // Optimization: Set the actor instance invisible when character is out of camera view. This will stop the joint transforms update, except the root joint. // Calling it after the bounds on the render actor updated. if (!m_configuration.m_forceUpdateJointsOOV) { const bool isInCameraFrustum = m_renderActorInstance->IsInCameraFrustum(); - m_actorInstance->SetIsVisible(isInCameraFrustum && m_configuration.m_renderCharacter); + m_actorInstance->SetIsVisible(isInCameraFrustum && renderActorSolid); } - m_renderActorInstance->SetIsVisible(m_debugRenderFlags[RENDER_SOLID]); - - // The configuration stores some debug option. When that is enabled, we override it on top of the render flags. - m_debugRenderFlags[RENDER_AABB] = m_debugRenderFlags[RENDER_AABB] || m_configuration.m_renderBounds; - m_debugRenderFlags[RENDER_LINESKELETON] = m_debugRenderFlags[RENDER_LINESKELETON] || m_configuration.m_renderSkeleton; - m_debugRenderFlags[RENDER_EMFX_DEBUG] = true; - m_renderActorInstance->DebugDraw(m_debugRenderFlags); + m_renderActorInstance->SetIsVisible(renderActorSolid); + m_renderActorInstance->DebugDraw(m_configuration.m_renderFlags); } } diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h index 9eecea2f54..9bf2b88325 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.h @@ -82,11 +82,9 @@ namespace EMotionFX AZ::EntityId m_attachmentTarget{}; ///< Target entity this actor should attach to. size_t m_attachmentJointIndex = InvalidIndex; ///< Index of joint on target skeleton for actor attachments. AttachmentType m_attachmentType = AttachmentType::None; ///< Type of attachment. - bool m_renderSkeleton = false; ///< Toggles debug rendering of the skeleton. - bool m_renderCharacter = true; ///< Toggles rendering of the character. - bool m_renderBounds = false; ///< Toggles rendering of the character bounds used for visibility testing. SkinningMethod m_skinningMethod = SkinningMethod::DualQuat; ///< The skinning method for this actor size_t m_lodLevel = 0; + ActorRenderFlags m_renderFlags = ActorRenderFlags::Default; ///< Actor render flag // Force updating the joints when it is out of camera view. By // default, joints level update (beside the root joint) on @@ -180,7 +178,7 @@ namespace EMotionFX bool IsPhysicsSceneSimulationFinishEventConnected() const; AZ::Data::Asset GetActorAsset() const { return m_configuration.m_actorAsset; } - void SetRenderFlag(ActorRenderFlagBitset renderFlags); + void SetRenderFlag(ActorRenderFlags renderFlags); private: // AZ::TransformNotificationBus::MultiHandler @@ -202,7 +200,6 @@ namespace EMotionFX AZStd::vector m_attachments; AZStd::unique_ptr m_renderActorInstance; - ActorRenderFlagBitset m_debugRenderFlags; ///< Actor debug render flag AzPhysics::SceneEvents::OnSceneSimulationFinishHandler m_sceneFinishSimHandler; }; diff --git a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp index 4292f04a08..3139e97b16 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp @@ -124,12 +124,12 @@ namespace EMotionFX ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(0, &EditorActorComponent::m_renderCharacter, "Draw character", "Toggles rendering of character mesh.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnDebugDrawFlagChanged) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnRenderFlagChanged) ->DataElement(0, &EditorActorComponent::m_renderSkeleton, "Draw skeleton", "Toggles rendering of skeleton.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnDebugDrawFlagChanged) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnRenderFlagChanged) ->DataElement(0, &EditorActorComponent::m_renderBounds, "Draw bounds", "Toggles rendering of world space bounding boxes.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnDebugDrawFlagChanged) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnRenderFlagChanged) ->DataElement(AZ::Edit::UIHandlers::ComboBox, &EditorActorComponent::m_skinningMethod, "Skinning method", "Choose the skinning method this actor is using") ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorActorComponent::OnSkinningMethodChanged) @@ -180,7 +180,6 @@ namespace EMotionFX , m_lodLevel(0) , m_actorAsset(AZ::Data::AssetLoadBehavior::NoLoad) { - m_debugRenderFlags[RENDER_SOLID] = true; } ////////////////////////////////////////////////////////////////////////// @@ -198,6 +197,7 @@ namespace EMotionFX { AzToolsFramework::Components::EditorComponentBase::Activate(); + UpdateRenderFlags(); LoadActorAsset(); const AZ::EntityId entityId = GetEntityId(); @@ -363,8 +363,9 @@ namespace EMotionFX } ////////////////////////////////////////////////////////////////////////// - void EditorActorComponent::OnDebugDrawFlagChanged() + void EditorActorComponent::OnRenderFlagChanged() { + UpdateRenderFlags(); if (m_renderSkeleton || m_renderBounds || m_renderCharacter) { AZ::TickBus::Handler::BusConnect(); @@ -573,6 +574,23 @@ namespace EMotionFX ToolsApplicationEvents::Bus::Broadcast(&ToolsApplicationEvents::InvalidatePropertyDisplay, Refresh_EntireTree); } + void EditorActorComponent::UpdateRenderFlags() + { + m_renderFlags = ActorRenderFlags::None; + if (m_renderCharacter) + { + m_renderFlags |= ActorRenderFlags::Solid; + } + if (m_renderBounds) + { + m_renderFlags |= ActorRenderFlags::AABB; + } + if (m_renderSkeleton) + { + m_renderFlags |= ActorRenderFlags::LineSkeleton; + } + } + ////////////////////////////////////////////////////////////////////////// void EditorActorComponent::OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) { @@ -616,22 +634,16 @@ namespace EMotionFX { m_renderActorInstance->OnTick(deltaTime); m_renderActorInstance->UpdateBounds(); - - m_debugRenderFlags[RENDER_AABB] = m_renderBounds; - m_debugRenderFlags[RENDER_LINESKELETON] = m_renderSkeleton; - m_debugRenderFlags[RENDER_EMFX_DEBUG] = true; - m_renderActorInstance->DebugDraw(m_debugRenderFlags); + m_renderActorInstance->DebugDraw(m_renderFlags); } } void EditorActorComponent::BuildGameEntity(AZ::Entity* gameEntity) { + UpdateRenderFlags(); ActorComponent::Configuration cfg; cfg.m_actorAsset = m_actorAsset; cfg.m_materialPerLOD = m_materialPerLOD; - cfg.m_renderSkeleton = m_renderSkeleton; - cfg.m_renderCharacter = m_renderCharacter; - cfg.m_renderBounds = m_renderBounds; cfg.m_attachmentType = m_attachmentType; cfg.m_attachmentTarget = m_attachmentTarget; cfg.m_attachmentJointIndex = m_attachmentJointIndex; @@ -639,6 +651,7 @@ namespace EMotionFX cfg.m_skinningMethod = m_skinningMethod; cfg.m_bboxConfig = m_bboxConfig; cfg.m_forceUpdateJointsOOV = m_forceUpdateJointsOOV; + cfg.m_renderFlags = m_renderFlags; gameEntity->AddComponent(aznew ActorComponent(&cfg)); } @@ -861,7 +874,7 @@ namespace EMotionFX void EditorActorComponent::CheckActorCreation() { // Enable/disable debug drawing. - OnDebugDrawFlagChanged(); + OnRenderFlagChanged(); // Create actor instance. auto* actorAsset = m_actorAsset.GetAs(); @@ -964,9 +977,9 @@ namespace EMotionFX } } - void EditorActorComponent::SetRenderFlag(ActorRenderFlagBitset renderFlags) + void EditorActorComponent::SetRenderFlag(ActorRenderFlags renderFlags) { - m_debugRenderFlags = renderFlags; + m_renderFlags = renderFlags; } } //namespace Integration } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h index f4c663a92f..0336a0844d 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h +++ b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.h @@ -104,7 +104,7 @@ namespace EMotionFX ActorComponent::GetRequiredServices(required); } - void SetRenderFlag(ActorRenderFlagBitset renderFlags); + void SetRenderFlag(ActorRenderFlags renderFlags); static void Reflect(AZ::ReflectContext* context); @@ -114,7 +114,7 @@ namespace EMotionFX void OnMaterialChanged(); void OnMaterialPerActorChanged(); void OnLODLevelChanged(); - void OnDebugDrawFlagChanged(); + void OnRenderFlagChanged(); void OnSkinningMethodChanged(); AZ::Crc32 OnAttachmentTypeChanged(); AZ::Crc32 OnAttachmentTargetChanged(); @@ -124,6 +124,7 @@ namespace EMotionFX bool AttachmentTargetJointVisibility(); AZStd::string AttachmentJointButtonText(); void InitializeMaterial(ActorAsset& actorAsset); + void UpdateRenderFlags(); void LaunchAnimationEditor(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType&); @@ -164,7 +165,7 @@ namespace EMotionFX size_t m_lodLevel; ActorComponent::BoundingBoxConfiguration m_bboxConfig; bool m_forceUpdateJointsOOV = false; - ActorRenderFlagBitset m_debugRenderFlags; ///< Actor debug render flag + ActorRenderFlags m_renderFlags; ///< Actor render flag // \todo attachmentTarget node nr // Note: LOD work in progress. For now we use one material instead of a list of material, because we don't have the support for LOD with multiple scene files. diff --git a/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorInstance.h b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorInstance.h index 8afb2a2f9a..f124f352c6 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorInstance.h +++ b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderActorInstance.h @@ -34,7 +34,7 @@ namespace EMotionFX virtual ~RenderActorInstance() = default; virtual void OnTick(float timeDelta) = 0; - virtual void DebugDraw(const EMotionFX::ActorRenderFlagBitset& renderFlags) = 0; + virtual void DebugDraw(const EMotionFX::ActorRenderFlags& renderFlags) = 0; SkinningMethod GetSkinningMethod() const; virtual void SetSkinningMethod(SkinningMethod skinningMethod); diff --git a/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderFlag.h b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderFlag.h index e053eae6d5..4640fdfcb1 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderFlag.h +++ b/Gems/EMotionFX/Code/Source/Integration/Rendering/RenderFlag.h @@ -7,38 +7,87 @@ */ #pragma once -#include +#include +#include namespace EMotionFX { - enum ActorRenderFlag + // The index of the render flag which is 0, 1, 2, 3.. based. + // Do not confuse this with the actual ActorRenderFlags::Type which is 1, 2, 4, 8.. based. + enum ActorRenderFlagIndex : AZ::u8 { - RENDER_SOLID = 0, - RENDER_WIREFRAME = 1, - RENDER_LIGHTING = 2, - RENDER_SHADOWS = 3, - RENDER_FACENORMALS = 4, - RENDER_VERTEXNORMALS = 5, - RENDER_TANGENTS = 6, - RENDER_AABB = 7, - RENDER_SKELETON = 8, - RENDER_LINESKELETON = 9, - RENDER_NODEORIENTATION = 10, - RENDER_NODENAMES = 11, - RENDER_GRID = 12, - RENDER_BACKFACECULLING = 13, - RENDER_ACTORBINDPOSE = 14, - RENDER_RAGDOLL_COLLIDERS = 15, - RENDER_RAGDOLL_JOINTLIMITS = 16, - RENDER_HITDETECTION_COLLIDERS = 17, - RENDER_USE_GRADIENTBACKGROUND = 18, - RENDER_MOTIONEXTRACTION = 19, - RENDER_CLOTH_COLLIDERS = 20, - RENDER_SIMULATEDOBJECT_COLLIDERS = 21, - RENDER_SIMULATEJOINTS = 22, - RENDER_EMFX_DEBUG = 23, - NUM_RENDERFLAGS = 24 + SOLID = 0, + WIREFRAME = 1, + LIGHTING = 2, + SHADOWS = 3, + FACENORMALS = 4, + VERTEXNORMALS = 5, + TANGENTS = 6, + AABB = 7, + SKELETON = 8, + LINESKELETON = 9, + NODEORIENTATION = 10, + NODENAMES = 11, + GRID = 12, + BACKFACECULLING = 13, + ACTORBINDPOSE = 14, + RAGDOLL_COLLIDERS = 15, + RAGDOLL_JOINTLIMITS = 16, + HITDETECTION_COLLIDERS = 17, + USE_GRADIENTBACKGROUND = 18, + MOTIONEXTRACTION = 19, + CLOTH_COLLIDERS = 20, + SIMULATEDOBJECT_COLLIDERS = 21, + SIMULATEJOINTS = 22, + EMFX_DEBUG = 23, + NUM_RENDERFLAGINDEXES = 24 }; - using ActorRenderFlagBitset = AZStd::bitset; + //! A set of combinable flags which indicate which render option in turned on for the actor. + AZ_ENUM_CLASS_WITH_UNDERLYING_TYPE(ActorRenderFlags, AZ::u32, + (None, 0), + (Solid, AZ_BIT(ActorRenderFlagIndex::SOLID)), + (Wireframe, AZ_BIT(ActorRenderFlagIndex::WIREFRAME)), + (Lighting, AZ_BIT(ActorRenderFlagIndex::LIGHTING)), + (Default, Solid | Lighting), + (Shadows, AZ_BIT(ActorRenderFlagIndex::SHADOWS)), + (FaceNormals, AZ_BIT(ActorRenderFlagIndex::FACENORMALS)), + (VertexNormals, AZ_BIT(ActorRenderFlagIndex::VERTEXNORMALS)), + (Tangents, AZ_BIT(ActorRenderFlagIndex::TANGENTS)), + (AABB, AZ_BIT(ActorRenderFlagIndex::AABB)), + (Skeleton, AZ_BIT(ActorRenderFlagIndex::SKELETON)), + (LineSkeleton, AZ_BIT(ActorRenderFlagIndex::LINESKELETON)), + (NodeOrientation, AZ_BIT(ActorRenderFlagIndex::NODEORIENTATION)), + (NodeNames, AZ_BIT(ActorRenderFlagIndex::NODENAMES)), + (Grid, AZ_BIT(ActorRenderFlagIndex::GRID)), + (BackfaceCulling, AZ_BIT(ActorRenderFlagIndex::BACKFACECULLING)), + (ActorBindPose, AZ_BIT(ActorRenderFlagIndex::ACTORBINDPOSE)), + (RagdollColliders, AZ_BIT(ActorRenderFlagIndex::RAGDOLL_COLLIDERS)), + (RagdollJointLimits, AZ_BIT(ActorRenderFlagIndex::RAGDOLL_JOINTLIMITS)), + (HitDetectionColliders, AZ_BIT(ActorRenderFlagIndex::HITDETECTION_COLLIDERS)), + (UseGradientBackground, AZ_BIT(ActorRenderFlagIndex::USE_GRADIENTBACKGROUND)), + (MotionExtraction, AZ_BIT(ActorRenderFlagIndex::MOTIONEXTRACTION)), + (ClothColliders, AZ_BIT(ActorRenderFlagIndex::CLOTH_COLLIDERS)), + (SimulatedObjectColliders, AZ_BIT(ActorRenderFlagIndex::SIMULATEDOBJECT_COLLIDERS)), + (SimulatedJoints, AZ_BIT(ActorRenderFlagIndex::SIMULATEJOINTS)), + (EmfxDebug, AZ_BIT(ActorRenderFlagIndex::EMFX_DEBUG)) + ); + + AZ_DEFINE_ENUM_BITWISE_OPERATORS(ActorRenderFlags); + + class ActorRenderFlagUtil + { + public: + // Check the bit value with the offset start at 0 from the right. + // CheckBit(flags, 0) means check the last digit of the flags, CheckBit(flags, 1) means the second digit from right, etc. + static bool CheckBit(ActorRenderFlags flags, AZ::u8 offset) + { + return (flags & ActorRenderFlags(AZ_BIT(offset))) != ActorRenderFlags(0); + } + }; +} + +namespace AZ +{ + AZ_TYPE_INFO_SPECIALIZE(EMotionFX::ActorRenderFlags, "{2D2187FA-2C1A-4485-AF7C-AD34C0514105}"); } diff --git a/Gems/EMotionFX/Code/Tests/RenderBackendManagerTests.cpp b/Gems/EMotionFX/Code/Tests/RenderBackendManagerTests.cpp index be990f444c..e1e092cf3d 100644 --- a/Gems/EMotionFX/Code/Tests/RenderBackendManagerTests.cpp +++ b/Gems/EMotionFX/Code/Tests/RenderBackendManagerTests.cpp @@ -65,7 +65,7 @@ namespace EMotionFX } MOCK_METHOD1(OnTick, void(float)); - MOCK_METHOD1(DebugDraw, void(const EMotionFX::ActorRenderFlagBitset&)); + MOCK_METHOD1(DebugDraw, void(const EMotionFX::ActorRenderFlags&)); MOCK_CONST_METHOD0(IsVisible, bool()); MOCK_METHOD1(SetIsVisible, void(bool)); MOCK_METHOD1(SetMaterials, void(const ActorAsset::MaterialList&)); From 3bdb0f5d9b2cd837f2a71566293b2575334ade31 Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Mon, 14 Feb 2022 15:29:42 -0600 Subject: [PATCH 30/42] Atom Tools: Restoring idle behavior for viewport input behavior controller Signed-off-by: Guthrie Adams --- .../IdleBehavior.h | 21 +++++++++++++++++++ .../IdleBehavior.cpp | 18 ++++++++++++++++ .../ViewportInputBehaviorController.cpp | 6 ++++++ .../Code/atomtoolsframework_files.cmake | 2 ++ .../Viewport/MaterialViewportWidget.cpp | 3 +++ 5 files changed, 50 insertions(+) create mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/IdleBehavior.h create mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/IdleBehavior.cpp diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/IdleBehavior.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/IdleBehavior.h new file mode 100644 index 0000000000..c762927336 --- /dev/null +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/IdleBehavior.h @@ -0,0 +1,21 @@ +/* + * 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 + +namespace AtomToolsFramework +{ + class IdleBehavior final : public ViewportInputBehavior + { + public: + IdleBehavior(ViewportInputBehaviorControllerInterface* controller); + virtual ~IdleBehavior() = default; + }; +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/IdleBehavior.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/IdleBehavior.cpp new file mode 100644 index 0000000000..7bf2f378ce --- /dev/null +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/IdleBehavior.cpp @@ -0,0 +1,18 @@ +/* + * 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 + * + */ + +#include +#include + +namespace AtomToolsFramework +{ + IdleBehavior::IdleBehavior(ViewportInputBehaviorControllerInterface* controller) + : ViewportInputBehavior(controller) + { + } +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/ViewportInputBehaviorController.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/ViewportInputBehaviorController.cpp index fd06427622..3e0398f08e 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/ViewportInputBehaviorController.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInputBehaviorController/ViewportInputBehaviorController.cpp @@ -280,8 +280,14 @@ namespace AtomToolsFramework void ViewportInputBehaviorController::EvaluateControlBehavior() { auto it = m_behaviorMap.find(m_keys); + if (it == m_behaviorMap.end()) + { + it = m_behaviorMap.find(None); + } + AZStd::shared_ptr nextBehavior = it != m_behaviorMap.end() ? it->second : AZStd::shared_ptr(); + if (m_behavior != nextBehavior) { if (m_behavior) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake index 008eb5fe96..5046e28145 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake @@ -95,6 +95,8 @@ set(FILES Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/ViewportInputBehavior.h Source/Viewport/ViewportInputBehaviorController/DollyCameraBehavior.cpp Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/DollyCameraBehavior.h + Source/Viewport/ViewportInputBehaviorController/IdleBehavior.cpp + Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/IdleBehavior.h Source/Viewport/ViewportInputBehaviorController/MoveCameraBehavior.cpp Include/AtomToolsFramework/Viewport/ViewportInputBehaviorController/MoveCameraBehavior.h Source/Viewport/ViewportInputBehaviorController/PanCameraBehavior.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportWidget.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportWidget.cpp index 89aecd67a2..06e0945fa3 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportWidget.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportWidget.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -312,6 +313,8 @@ namespace MaterialEditor // Create viewport input controller and regioster its behaviors m_viewportController.reset( aznew ViewportInputBehaviorController(m_cameraEntity->GetId(), m_modelEntity->GetId(), m_iblEntity->GetId())); + m_viewportController->AddBehavior( + ViewportInputBehaviorController::None, AZStd::make_shared(m_viewportController.get())); m_viewportController->AddBehavior( ViewportInputBehaviorController::Lmb, AZStd::make_shared(m_viewportController.get())); m_viewportController->AddBehavior( From f5dff748d98fdaf67e7ab4605be2f3ff55b0ba25 Mon Sep 17 00:00:00 2001 From: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> Date: Mon, 14 Feb 2022 15:47:56 -0600 Subject: [PATCH 31/42] Cleanup Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> --- Code/LauncherUnified/launcher_generator.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake index 9078f9a3c5..c1cc7e81a1 100644 --- a/Code/LauncherUnified/launcher_generator.cmake +++ b/Code/LauncherUnified/launcher_generator.cmake @@ -132,7 +132,6 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC endif() endif() - get_target_property(project_game_launcher_additional_args ${project_name} GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS) set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${additional_game_vs_debugger_args}") endif() From d2cdb511d0d4e439c5a89f747086ff5baca2b046 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Mon, 14 Feb 2022 14:22:07 -0800 Subject: [PATCH 32/42] Improve the framerate of Editor widgets that update in the TickBus (#7408) Previously, with no level loaded in the main editor, and no assets loaded in the EMotionFX editor, the AnimGraph viewport would only update at 15fps, even on a 64 core machine. Digging into this with Pix, I found that EMotionFX's UI would only get updated for every other call to the ComponentApplication tick. The Editor's QApplication instance controls how the `ComponentApplication::OnTick` method is called. This is done in the `maybeProcessIdle()` method. Generally, I found callstacks like this: ``` EditorQtApplication::maybeProcessIdle() CCryEditApp::OnIdle() CCryEditApp::IdleProcessing() CGameEngine::Update() # ~2.2ms PhysX::Update() # ~1.8ms EMotionFX::Update() # ~0.2ms calls QWidget::update() on all the widgets that change per frame, only puts update events on the event queue, doesn't paint anything AZ::ComponentApplication::TickSystem() # ~25ms renders the frame with Atom # ~24ms ``` The `maybeProcessIdle()` method is invoked by a QTimer, with a timeout that changes depending on the application state. If the Editor is in game mode, it used a timeout of 0, which essentially forced the game to run at as high an fps as possible. If the Editor application has focus, it used a timeout of 1ms, asking for the idle processing to happen at 1000 fps. Otherwise, it used a timeout of 10ms, asking for idle processing at 100 fps. Those fps targets are not realistic. What happened in this case is that while the PhysX system was being updated, while the previous `maybeProcessIdle()` call was still processing, the idle processing timer would timeout again, and place a timer event on Qt's event queue, before anything else had a chance to do anything. Only afterward would EMotionFX's MainWindow::OnTick would be invoked, placing paint events on Qt's event queue. The fix for this is to use a single shot timer at the end of each `maybeProcessIdle()` call. This ensures that any events that are enqueued during the `maybeProcessIdle()` call are processed prior to the next call to `maybeProcessIdle()`. Signed-off-by: Chris Burel --- Code/Editor/Core/QtEditorApplication.cpp | 72 +++--------------------- Code/Editor/Core/QtEditorApplication.h | 9 +-- 2 files changed, 8 insertions(+), 73 deletions(-) diff --git a/Code/Editor/Core/QtEditorApplication.cpp b/Code/Editor/Core/QtEditorApplication.cpp index 2439228476..8f7db74125 100644 --- a/Code/Editor/Core/QtEditorApplication.cpp +++ b/Code/Editor/Core/QtEditorApplication.cpp @@ -32,15 +32,6 @@ #include "Settings.h" #include "CryEdit.h" -enum -{ - // in milliseconds - GameModeIdleFrequency = 0, - EditorModeIdleFrequency = 1, - InactiveModeFrequency = 10, - UninitializedFrequency = 9999, -}; - Q_LOGGING_CATEGORY(InputDebugging, "o3de.editor.input") // internal, private namespace: @@ -234,18 +225,12 @@ namespace Editor EditorQtApplication::EditorQtApplication(int& argc, char** argv) : AzQtApplication(argc, argv) , m_stylesheet(new AzQtComponents::O3DEStylesheet(this)) - , m_idleTimer(new QTimer(this)) { - m_idleTimer->setInterval(UninitializedFrequency); - setWindowIcon(QIcon(":/Application/res/o3de_editor.ico")); // set the default key store for our preferences: setApplicationName("O3DE Editor"); - connect(m_idleTimer, &QTimer::timeout, this, &EditorQtApplication::maybeProcessIdle); - - connect(this, &QGuiApplication::applicationStateChanged, this, [this] { ResetIdleTimerInterval(PollState); }); installEventFilter(this); // Disable our debugging input helpers by default @@ -324,6 +309,10 @@ namespace Editor winapp->OnIdle(0); } } + if (m_applicationActive) + { + QTimer::singleShot(1, this, &EditorQtApplication::maybeProcessIdle); + } } void EditorQtApplication::InstallQtLogHandler() @@ -376,14 +365,6 @@ namespace Editor case eNotify_OnQuit: GetIEditor()->UnregisterNotifyListener(this); break; - - case eNotify_OnBeginGameMode: - // GetIEditor()->IsInGameMode() Isn't reliable when called from within the notification handler - ResetIdleTimerInterval(GameMode); - break; - case eNotify_OnEndGameMode: - ResetIdleTimerInterval(EditorMode); - break; } } @@ -456,55 +437,16 @@ namespace Editor void EditorQtApplication::EnableOnIdle(bool enable) { + m_applicationActive = enable; if (enable) { - if (m_idleTimer->interval() == UninitializedFrequency) - { - ResetIdleTimerInterval(); - } - - m_idleTimer->start(); - } - else - { - m_idleTimer->stop(); + QTimer::singleShot(0, this, &EditorQtApplication::maybeProcessIdle); } } bool EditorQtApplication::OnIdleEnabled() const { - if (m_idleTimer->interval() == UninitializedFrequency) - { - return false; - } - - return m_idleTimer->isActive(); - } - - void EditorQtApplication::ResetIdleTimerInterval(TimerResetFlag flag) - { - bool isInGameMode = flag == GameMode; - if (flag == PollState) - { - isInGameMode = GetIEditor() ? GetIEditor()->IsInGameMode() : false; - } - - // Game mode takes precedence over anything else - if (isInGameMode) - { - m_idleTimer->setInterval(GameModeIdleFrequency); - } - else - { - if (applicationState() & Qt::ApplicationActive) - { - m_idleTimer->setInterval(EditorModeIdleFrequency); - } - else - { - m_idleTimer->setInterval(InactiveModeFrequency); - } - } + return m_applicationActive; } bool EditorQtApplication::eventFilter(QObject* object, QEvent* event) diff --git a/Code/Editor/Core/QtEditorApplication.h b/Code/Editor/Core/QtEditorApplication.h index 28ee8ac14b..9cb03ec644 100644 --- a/Code/Editor/Core/QtEditorApplication.h +++ b/Code/Editor/Core/QtEditorApplication.h @@ -102,13 +102,6 @@ namespace Editor bool m_isMovingOrResizing = false; private: - enum TimerResetFlag - { - PollState, - GameMode, - EditorMode - }; - void ResetIdleTimerInterval(TimerResetFlag = PollState); static QColor InterpolateColors(QColor a, QColor b, float factor); void RefreshStyleSheet(); void InstallFilters(); @@ -125,7 +118,6 @@ namespace Editor QTranslator* m_editorTranslator = nullptr; QTranslator* m_assetBrowserTranslator = nullptr; - QTimer* const m_idleTimer = nullptr; AZ::UserSettingsProvider m_localUserSettings; @@ -133,5 +125,6 @@ namespace Editor QSet m_pressedKeys; bool m_activatedLocalUserSettings = false; + bool m_applicationActive = false; }; } // namespace editor From 8b8204136154bad58259b8d0aa1075b3a06f3ece Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Mon, 14 Feb 2022 16:27:53 -0600 Subject: [PATCH 33/42] Optimize SurfaceData bulk queries (#7593) * Add comparison operators to SurfaceTagWeight. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed AddSurfaceTagWeight to always combine weights. This simplifies the API a bit and defines the behavior if someone ever tries to add a duplicate tag. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added benchmarks for measuring the performance-critical APIs. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed SurfaceTagWeights to a fixed_vector. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add inPosition to AddSurfacePoint. This will be used to detect which input the surface point is associated with. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add inPositionIndex to the appropriate APIs. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched Gradient Surface benchmarks to use actual surface components. The gradient unit tests and benchmarks were previously using a mock surface data system, which led to misleading benchmark results. Now, the actual SurfaceData system gets constructed, and the tests use a mock provider, but the benchmarks use actual shape providers for more realistic benchmarking. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed unit tests to have better query ranges. Half of each previous range was querying outside the surface provider's data. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * First attempt at removing SurfacePointLists. This currently runs significantly slower than the previous code but passes the unit tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Another attempt at optimization. This one runs faster than the previous, but still slow. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fix the cmake dependency so that the gradient tests rebuild SurfaceData.dll when run. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switch SurfaceAltitudeGradient over to the new bulk API. Also, optimized the non-bulk API by having it reuse the SurfacePointList to avoid the repeated allocation / deallocation cost. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched to using an indirect index so that all allocations are consecutive in our reserved buffer. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched back to SurfaceTagWeight again. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added runtime dependency to LmbrCentral for unit tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched code over to use the full EnumeratePoints in most cases. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added knowledge of max surface point creation into the system. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add generic GetSurfacePointsFromList API implementation for surface providers. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed implementation to use the correct maximum number of input points based on the surface providers being queried. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fix out-of-bounds references on empty lists. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fix memory allocation that caused benchmark runs to crash. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Starting to clean up the API. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Move SurfacePointList into separate files for easier maintainability. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed bug where too many points were filtered out due to using the position Z as a part of the AABB check. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Made FilterPoints an internal part of SurfacePointList so we can choose when and how to perform the filtering. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Final cleanup / comments. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added includes for non-unity builds. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed how unit tests initialize the mock lists to try and fix the linux errors. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed compile error. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../SurfaceData/SurfaceDataMeshComponent.cpp | 3 +- .../SurfaceAltitudeGradientComponent.h | 12 +- .../Components/SurfaceMaskGradientComponent.h | 6 +- .../SurfaceSlopeGradientComponent.h | 9 +- .../SurfaceAltitudeGradientComponent.cpp | 43 +-- .../EditorGradientSurfaceDataComponent.cpp | 7 +- .../Tests/GradientSignalReferencesTests.cpp | 64 +++- .../Code/Tests/GradientSignalSurfaceTests.cpp | 9 +- .../Code/Tests/GradientSignalTestMocks.h | 22 +- .../Components/SurfaceDataSystemComponent.h | 10 +- .../SurfaceDataModifierRequestBus.h | 1 + .../SurfaceDataProviderRequestBus.h | 16 +- .../SurfaceData/SurfaceDataSystemRequestBus.h | 5 +- .../Include/SurfaceData/SurfaceDataTypes.h | 81 +--- .../Include/SurfaceData/SurfacePointList.h | 229 +++++++++++ .../SurfaceData/Tests/SurfaceDataTestMocks.h | 4 +- .../SurfaceDataColliderComponent.cpp | 5 +- .../Components/SurfaceDataShapeComponent.cpp | 6 +- .../Source/SurfaceDataSystemComponent.cpp | 176 ++++----- .../Code/Source/SurfaceDataTypes.cpp | 152 +------- .../Code/Source/SurfacePointList.cpp | 361 ++++++++++++++++++ .../Code/Tests/SurfaceDataBenchmarks.cpp | 4 +- .../SurfaceDataColliderComponentTest.cpp | 19 +- .../Code/Tests/SurfaceDataTest.cpp | 182 ++++----- Gems/SurfaceData/Code/surfacedata_files.cmake | 2 + .../TerrainSurfaceDataSystemComponent.cpp | 3 +- .../Code/Source/AreaSystemComponent.cpp | 35 +- .../Components/PositionModifierComponent.cpp | 3 +- .../SurfaceMaskDepthFilterComponent.cpp | 2 +- .../SurfaceMaskDepthFilterComponent.h | 1 + .../Code/Source/Debugger/DebugComponent.cpp | 3 +- Gems/Vegetation/Code/Tests/VegetationMocks.h | 9 +- 32 files changed, 970 insertions(+), 514 deletions(-) create mode 100644 Gems/SurfaceData/Code/Include/SurfaceData/SurfacePointList.h create mode 100644 Gems/SurfaceData/Code/Source/SurfacePointList.cpp diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SurfaceData/SurfaceDataMeshComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SurfaceData/SurfaceDataMeshComponent.cpp index 2686ca8a16..117af76325 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SurfaceData/SurfaceDataMeshComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SurfaceData/SurfaceDataMeshComponent.cpp @@ -178,7 +178,7 @@ namespace SurfaceData AZ::Vector3 hitNormal; if (DoRayTrace(inPosition, hitPosition, hitNormal)) { - surfacePointList.AddSurfacePoint(GetEntityId(), hitPosition, hitNormal, m_newPointWeights); + surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, hitPosition, hitNormal, m_newPointWeights); } } @@ -255,6 +255,7 @@ namespace SurfaceData registryEntry.m_entityId = GetEntityId(); registryEntry.m_bounds = GetSurfaceAabb(); registryEntry.m_tags = GetSurfaceTags(); + registryEntry.m_maxPointsCreatedPerInput = 1; if (!meshValidBeforeUpdate && !meshValidAfterUpdate) { diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h index d8e902a0d5..2984495979 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -107,16 +108,16 @@ namespace GradientSignal void AddTag(AZStd::string tag) override; private: - static float CalculateAltitudeRatio(const SurfaceData::SurfacePointList& points, float altitudeMin, float altitudeMax) + static float CalculateAltitudeRatio(const SurfaceData::SurfacePointList& points, size_t inPositionIndex, float altitudeMin, float altitudeMax) { - if (points.IsEmpty()) + if (points.IsEmpty(inPositionIndex)) { return 0.0f; } // GetSurfacePoints (which was used to populate the points list) always returns points in decreasing height order, so the // first point in the list contains the highest altitude. - const float highestAltitude = points.GetHighestSurfacePoint().m_position.GetZ(); + const float highestAltitude = points.GetHighestSurfacePoint(inPositionIndex).m_position.GetZ(); // Turn the absolute altitude value into a 0-1 value by returning the % of the given altitude range that it falls at. return GetRatio(altitudeMin, altitudeMax, highestAltitude); @@ -126,5 +127,10 @@ namespace GradientSignal SurfaceAltitudeGradientConfig m_configuration; LmbrCentral::DependencyMonitor m_dependencyMonitor; AZStd::atomic_bool m_dirty{ false }; + + // m_surfacePointList exists here because it will more efficiently reuse memory across GetValue() calls if it stays constructed. + // The mutex exists to ensure that we don't try to use it from GetValue() in multiple threads at once. + mutable AZStd::recursive_mutex m_surfacePointListMutex; + mutable SurfaceData::SurfacePointList m_surfacePointList; }; } diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h index eb009e6b92..bfb5767a1a 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceMaskGradientComponent.h @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace LmbrCentral @@ -84,10 +85,9 @@ namespace GradientSignal static float GetMaxSurfaceWeight(const SurfaceData::SurfacePointList& points) { float result = 0.0f; - points.EnumeratePoints([&result]( - [[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal, - const SurfaceData::SurfaceTagWeights& masks) -> bool + [[maybe_unused]] size_t inPositionIndex, [[maybe_unused]] const AZ::Vector3& position, + [[maybe_unused]] const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool { masks.EnumerateWeights( [&result]([[maybe_unused]] AZ::Crc32 surfaceType, float weight) -> bool diff --git a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h index e7a55a2bbc..f54e58d0fc 100644 --- a/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h +++ b/Gems/GradientSignal/Code/Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -125,17 +126,19 @@ namespace GradientSignal private: float GetSlopeRatio(const SurfaceData::SurfacePointList& points, float angleMin, float angleMax) const { - if (points.IsEmpty()) + constexpr size_t inPositionIndex = 0; + if (points.IsEmpty(inPositionIndex)) { return 0.0f; } // Assuming our surface normal vector is actually normalized, we can get the slope // by just grabbing the Z value. It's the same thing as normal.Dot(AZ::Vector3::CreateAxisZ()). + auto highestSurfacePoint = points.GetHighestSurfacePoint(inPositionIndex); AZ_Assert( - points.GetHighestSurfacePoint().m_normal.GetNormalized().IsClose(points.GetHighestSurfacePoint().m_normal), + highestSurfacePoint.m_normal.GetNormalized().IsClose(highestSurfacePoint.m_normal), "Surface normals are expected to be normalized"); - const float slope = points.GetHighestSurfacePoint().m_normal.GetZ(); + const float slope = highestSurfacePoint.m_normal.GetZ(); // Convert slope back to an angle so that we can lerp in "angular space", not "slope value space". // (We want our 0-1 range to be linear across the range of angles) const float slopeAngle = acosf(slope); diff --git a/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp b/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp index b79606818b..41ccbafc7a 100644 --- a/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Components/SurfaceAltitudeGradientComponent.cpp @@ -202,13 +202,18 @@ namespace GradientSignal float SurfaceAltitudeGradientComponent::GetValue(const GradientSampleParams& sampleParams) const { + // For GetValue(), we reuse our SurfacePointList for the GetSurfacePoints query to avoid the repeated cost of memory allocation + // and deallocation across GetValue() calls. However, this also means we can only use it from one thread at a time, so lock a + // mutex to ensure no other threads call GetValue() at the same time. + AZStd::unique_lock surfacePointLock(m_surfacePointListMutex); + AZStd::shared_lock lock(m_cacheMutex); - SurfaceData::SurfacePointList points; SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints, - sampleParams.m_position, m_configuration.m_surfaceTagsToSample, points); + sampleParams.m_position, m_configuration.m_surfaceTagsToSample, m_surfacePointList); - return CalculateAltitudeRatio(points, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax); + constexpr size_t inPositionIndex = 0; + return CalculateAltitudeRatio(m_surfacePointList, inPositionIndex, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax); } void SurfaceAltitudeGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const @@ -220,31 +225,25 @@ namespace GradientSignal } AZStd::shared_lock lock(m_cacheMutex); - bool valuesFound = false; - // Rather than calling GetSurfacePoints on the EBus repeatedly in a loop, we instead pass a lambda into the EBus that contains - // the loop within it so that we can avoid the repeated EBus-calling overhead. + SurfaceData::SurfacePointList points; SurfaceData::SurfaceDataSystemRequestBus::Broadcast( - [this, positions, &outValues, &valuesFound](SurfaceData::SurfaceDataSystemRequestBus::Events* surfaceDataRequests) - { - // It's possible that there's nothing connected to the EBus, so keep track of the fact that we have valid results. - valuesFound = true; - SurfaceData::SurfacePointList points; - - // For each position, call GetSurfacePoints() and turn the height into a 0-1 value based on our min/max altitudes. - for (size_t index = 0; index < positions.size(); index++) - { - points.Clear(); - surfaceDataRequests->GetSurfacePoints(positions[index], m_configuration.m_surfaceTagsToSample, points); - outValues[index] = CalculateAltitudeRatio(points, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax); - } - }); - - if (!valuesFound) + &SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePointsFromList, positions, m_configuration.m_surfaceTagsToSample, + points); + + if (points.IsEmpty()) { // No surface data, so no output values. AZStd::fill(outValues.begin(), outValues.end(), 0.0f); } + else + { + // For each position, turn the height into a 0-1 value based on our min/max altitudes. + for (size_t index = 0; index < positions.size(); index++) + { + outValues[index] = CalculateAltitudeRatio(points, index, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax); + } + } } void SurfaceAltitudeGradientComponent::OnCompositionChanged() diff --git a/Gems/GradientSignal/Code/Source/Editor/EditorGradientSurfaceDataComponent.cpp b/Gems/GradientSignal/Code/Source/Editor/EditorGradientSurfaceDataComponent.cpp index 692576b3b3..91f1a1b661 100644 --- a/Gems/GradientSignal/Code/Source/Editor/EditorGradientSurfaceDataComponent.cpp +++ b/Gems/GradientSignal/Code/Source/Editor/EditorGradientSurfaceDataComponent.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace GradientSignal { @@ -107,7 +108,7 @@ namespace GradientSignal // Create a fake surface point with the position we're sampling. AzFramework::SurfaceData::SurfacePoint point; point.m_position = params.m_position; - SurfaceData::SurfacePointList pointList = { { point } }; + SurfaceData::SurfacePointList pointList = AZStd::span(&point, 1); // Send it into the component, see what emerges m_component.ModifySurfacePoints(pointList); @@ -117,8 +118,8 @@ namespace GradientSignal // the underlying logic ever changes to allow separate ranges per tag. float result = 0.0f; pointList.EnumeratePoints([&result]( - [[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal, - const SurfaceData::SurfaceTagWeights& masks) -> bool + [[maybe_unused]] size_t inPositionIndex, [[maybe_unused]] const AZ::Vector3& position, + [[maybe_unused]] const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool { masks.EnumerateWeights( [&result]([[maybe_unused]] AZ::Crc32 surfaceType, float weight) -> bool diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp index 2e602e8c80..3eef714518 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalReferencesTests.cpp @@ -79,7 +79,8 @@ namespace UnitTest { float angle = AZ::DegToRad(inputAngles[(y * dataSize) + x]); point.m_normal = AZ::Vector3(sinf(angle), 0.0f, cosf(angle)); - mockSurface->m_surfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = { { point } }; + mockSurface->m_surfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = + AZStd::span(&point, 1); } } ActivateEntity(surfaceEntity.get()); @@ -546,10 +547,22 @@ namespace UnitTest auto surfaceEntity = CreateEntity(); auto mockSurface = surfaceEntity->CreateComponent(); mockSurface->m_bounds = mockShapeComponentHandler.m_GetEncompassingAabb; - mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() } }; - mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() } }; - mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() } }; - mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() } }; + AzFramework::SurfaceData::SurfacePoint mockOutputs[] = + { + { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() }, + }; + + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = + AZStd::span(&mockOutputs[0], 1); + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = + AZStd::span(&mockOutputs[1], 1); + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = + AZStd::span(&mockOutputs[2], 1); + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = + AZStd::span(&mockOutputs[3], 1); ActivateEntity(surfaceEntity.get()); // We set the min/max to values other than 0-10 to help validate that they aren't used in the case of the pinned shape. @@ -583,10 +596,21 @@ namespace UnitTest auto surfaceEntity = CreateEntity(); auto mockSurface = surfaceEntity->CreateComponent(); mockSurface->m_bounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(1.0f)); - mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() } }; - mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() } }; - mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() } }; - mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() } }; + AzFramework::SurfaceData::SurfacePoint mockOutputs[] = { + { AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 2.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 5.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 10.0f), AZ::Vector3::CreateZero() }, + }; + + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = + AZStd::span(&mockOutputs[0], 1); + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = + AZStd::span(&mockOutputs[1], 1); + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = + AZStd::span(&mockOutputs[2], 1); + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = + AZStd::span(&mockOutputs[3], 1); ActivateEntity(surfaceEntity.get()); // We set the min/max to 0-10, but don't set a shape. @@ -642,14 +666,25 @@ namespace UnitTest auto surfaceEntity = CreateEntity(); auto mockSurface = surfaceEntity->CreateComponent(); mockSurface->m_bounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(1.0f)); + AzFramework::SurfaceData::SurfacePoint mockOutputs[] = { + { AZ::Vector3(0.0f, 0.0f, -10.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, -5.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 15.0f), AZ::Vector3::CreateZero() }, + { AZ::Vector3(0.0f, 0.0f, 20.0f), AZ::Vector3::CreateZero() }, + }; + // Altitude value below min - should result in 0.0f. - mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, -10.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 0.0f)] = + AZStd::span(&mockOutputs[0], 1); // Altitude value at exactly min - should result in 0.0f. - mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = { { AZ::Vector3(0.0f, 0.0f, -5.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 0.0f)] = + AZStd::span(&mockOutputs[1], 1); // Altitude value at exactly max - should result in 1.0f. - mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 15.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(0.0f, 1.0f)] = + AZStd::span(&mockOutputs[2], 1); // Altitude value above max - should result in 1.0f. - mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = { { AZ::Vector3(0.0f, 0.0f, 20.0f), AZ::Vector3::CreateZero() } }; + mockSurface->m_surfacePoints[AZStd::make_pair(1.0f, 1.0f)] = + AZStd::span(&mockOutputs[3], 1); ActivateEntity(surfaceEntity.get()); // We set the min/max to -5 - 15. By using a range without 0 at either end, and not having 0 as the midpoint, @@ -691,7 +726,8 @@ namespace UnitTest { point.m_surfaceTags.clear(); point.m_surfaceTags.emplace_back(AZ_CRC_CE("test_mask"), expectedOutput[(y * dataSize) + x]); - mockSurface->m_surfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = { { point } }; + mockSurface->m_surfacePoints[AZStd::make_pair(static_cast(x), static_cast(y))] = + AZStd::span(&point, 1); } } ActivateEntity(surfaceEntity.get()); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp index 4ab4c76d56..45bf818c71 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalSurfaceTests.cpp @@ -108,12 +108,13 @@ namespace UnitTest EXPECT_TRUE(modifierHandle != SurfaceData::InvalidSurfaceDataRegistryHandle); // Call ModifySurfacePoints and verify the results - SurfaceData::SurfacePointList pointList = { { input } }; + SurfaceData::SurfacePointList pointList; + pointList.StartListConstruction(AZStd::span(&input, 1)); SurfaceData::SurfaceDataModifierRequestBus::Event(modifierHandle, &SurfaceData::SurfaceDataModifierRequestBus::Events::ModifySurfacePoints, pointList); + pointList.EndListConstruction(); ASSERT_EQ(pointList.GetSize(), 1); - pointList.EnumeratePoints( - [this, expectedOutput]( - const AZ::Vector3& position, const AZ::Vector3& normal, + pointList.EnumeratePoints([this, expectedOutput]( + [[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) { EXPECT_TRUE(SurfacePointsAreEqual(position, normal, masks, expectedOutput)); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h index c8e69e0d51..466eca2a07 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestMocks.h @@ -132,6 +132,18 @@ namespace UnitTest providerRegistryEntry.m_bounds = m_bounds; providerRegistryEntry.m_tags = m_tags; + // Run through the set of surface points that have been set on this component to find out the maximum number + // that we'll return for any given input point. + providerRegistryEntry.m_maxPointsCreatedPerInput = 1; + for (auto& pointEntry : m_surfacePoints) + { + for (size_t index = 0; index < pointEntry.second.GetInputPositionSize(); index++) + { + providerRegistryEntry.m_maxPointsCreatedPerInput = + AZ::GetMax(providerRegistryEntry.m_maxPointsCreatedPerInput, pointEntry.second.GetSize(index)); + } + } + SurfaceData::SurfaceDataSystemRequestBus::BroadcastResult( m_providerHandle, &SurfaceData::SurfaceDataSystemRequestBus::Events::RegisterSurfaceDataProvider, providerRegistryEntry); SurfaceData::SurfaceDataProviderRequestBus::Handler::BusConnect(m_providerHandle); @@ -160,7 +172,15 @@ namespace UnitTest if (surfacePoints != m_surfacePoints.end()) { - surfacePointList = surfacePoints->second; + // If we have an entry for this input position, run through all of its points and add them to the passed-in list. + surfacePoints->second.EnumeratePoints( + [inPosition, &surfacePointList]( + [[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, const AZ::Vector3& normal, + const SurfaceData::SurfaceTagWeights& weights) -> bool + { + surfacePointList.AddSurfacePoint(AZ::EntityId(), inPosition, position, normal, weights); + return true; + }); } } diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataSystemComponent.h b/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataSystemComponent.h index 3e1291e524..820a1296c5 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataSystemComponent.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/Components/SurfaceDataSystemComponent.h @@ -42,11 +42,17 @@ namespace SurfaceData void GetSurfacePoints(const AZ::Vector3& inPosition, const SurfaceTagVector& desiredTags, SurfacePointList& surfacePointList) const override; void GetSurfacePointsFromRegion( const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, const SurfaceTagVector& desiredTags, - SurfacePointLists& surfacePointListPerPosition) const override; + SurfacePointList& surfacePointListPerPosition) const override; void GetSurfacePointsFromList( AZStd::span inPositions, const SurfaceTagVector& desiredTags, - SurfacePointLists& surfacePointLists) const override; + SurfacePointList& surfacePointLists) const override; + + void GetSurfacePointsFromListInternal( + AZStd::span inPositions, + const AZ::Aabb& inBounds, + const SurfaceTagVector& desiredTags, + SurfacePointList& surfacePointLists) const; SurfaceDataRegistryHandle RegisterSurfaceDataProvider(const SurfaceDataRegistryEntry& entry) override; void UnregisterSurfaceDataProvider(const SurfaceDataRegistryHandle& handle) override; diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataModifierRequestBus.h b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataModifierRequestBus.h index 19cc84fae2..6fc6766f5c 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataModifierRequestBus.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataModifierRequestBus.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace SurfaceData { diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataProviderRequestBus.h b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataProviderRequestBus.h index b3c8667679..3d42f6061b 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataProviderRequestBus.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataProviderRequestBus.h @@ -9,7 +9,9 @@ #pragma once #include +#include #include +#include namespace SurfaceData { @@ -32,9 +34,19 @@ namespace SurfaceData //! Get all of the surface points that this provider has at the given input position. //! @param inPosition - The input position to query. Only XY are guaranteed to be valid, Z should be ignored. - //! @param surfacePointList - The output list of surface points generated, if any. Each provider is expected to - //! append to this list, not overwrite it. + //! @param surfacePointList - The input/output SurfacePointList to add any generated surface points to. virtual void GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const = 0; + + //! Get all of the surface points that this provider has at the given input positions. + //! @param inPositions - The input positions to query. Only XY are guaranteed to be valid, Z should be ignored. + //! @param surfacePointList - The input/output SurfacePointList to add any generated surface points to. + virtual void GetSurfacePointsFromList(AZStd::span inPositions, SurfacePointList& surfacePointList) const + { + for (auto& inPosition : inPositions) + { + GetSurfacePoints(inPosition, surfacePointList); + } + } }; typedef AZ::EBus SurfaceDataProviderRequestBus; diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h index d4e84c5974..c3309707b6 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataSystemRequestBus.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace SurfaceData { @@ -40,13 +41,13 @@ namespace SurfaceData // The input positions are chosen by starting at the min sides of inRegion and incrementing by stepSize. This method is inclusive // on the min sides of the AABB, and exclusive on the max sides (i.e. for a box of (0,0) - (4,4), the point (0,0) is included but (4,4) isn't). virtual void GetSurfacePointsFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, const SurfaceTagVector& desiredTags, - SurfacePointLists& surfacePointLists) const = 0; + SurfacePointList& surfacePointLists) const = 0; // Get all surface points for every passed-in input position. Only the XY dimensions of each position are used. virtual void GetSurfacePointsFromList( AZStd::span inPositions, const SurfaceTagVector& desiredTags, - SurfacePointLists& surfacePointLists) const = 0; + SurfacePointList& surfacePointLists) const = 0; virtual SurfaceDataRegistryHandle RegisterSurfaceDataProvider(const SurfaceDataRegistryEntry& entry) = 0; virtual void UnregisterSurfaceDataProvider(const SurfaceDataRegistryHandle& handle) = 0; diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataTypes.h b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataTypes.h index 1d49fff3dc..95f64bcae3 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataTypes.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/SurfaceDataTypes.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -166,7 +167,7 @@ namespace SurfaceData //! Check to see if the collection contains any of the given tags. //! @param sampleTags - The tags to look for. //! @return True if any of the tags is found, false if none are found. - bool HasAnyMatchingTags(const SurfaceTagVector& sampleTags) const; + bool HasAnyMatchingTags(AZStd::span sampleTags) const; //! Check to see if the collection contains the given tag with the given weight range. //! The range check is inclusive on both sides of the range: [weightMin, weightMax] @@ -174,7 +175,7 @@ namespace SurfaceData //! @param weightMin - The minimum weight for this tag. //! @param weightMax - The maximum weight for this tag. //! @return True if any of the tags is found, false if none are found. - bool HasAnyMatchingTags(const SurfaceTagVector& sampleTags, float weightMin, float weightMax) const; + bool HasAnyMatchingTags(AZStd::span sampleTags, float weightMin, float weightMax) const; private: //! Search for the given tag entry. @@ -185,79 +186,21 @@ namespace SurfaceData AZStd::fixed_vector m_weights; }; - //! SurfacePointList stores a collection of surface point data, which consists of positions, normals, and surface tag weights. - class SurfacePointList - { - public: - AZ_CLASS_ALLOCATOR(SurfacePointList, AZ::SystemAllocator, 0); - AZ_TYPE_INFO(SurfacePointList, "{DBA02848-2131-4279-BDEF-3581B76AB736}"); - - SurfacePointList() = default; - ~SurfacePointList() = default; - - //! Constructor for creating a SurfacePointList from a list of SurfacePoint data. - //! Primarily used as a convenience for unit tests. - //! @param surfacePoints - An initial set of SurfacePoint points to store in the SurfacePointList. - SurfacePointList(AZStd::initializer_list surfacePoints); - - //! Add a surface point to the list. - //! @param entityId - The entity creating the surface point. - //! @param position - The position of the surface point. - //! @param normal - The normal for the surface point. - //! @param weights - The surface tags and weights for this surface point. - void AddSurfacePoint(const AZ::EntityId& entityId, - const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceTagWeights& weights); - - //! Clear the surface point list. - void Clear(); - - //! Preallocate space in the list based on the maximum number of output points per input point we can generate. - //! @param maxPointsPerInput - The maximum number of output points per input point. - void ReserveSpace(size_t maxPointsPerInput); - - //! Check if the surface point list is empty. - //! @return - true if empty, false if it contains points. - bool IsEmpty() const; - - //! Get the size of the surface point list. - //! @return - The number of valid points in the list. - size_t GetSize() const; - - //! Enumerate every surface point and call a callback for each point found. - void EnumeratePoints(AZStd::function< - bool(const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceTagWeights& surfaceWeights)> pointCallback) const; - - //! Modify the surface weights for each surface point in the list. - void ModifySurfaceWeights( - const AZ::EntityId& currentEntityId, - AZStd::function modificationWeightCallback); - - //! Get the surface point with the highest Z value. - AzFramework::SurfaceData::SurfacePoint GetHighestSurfacePoint() const; - - //! Remove any points that don't contain any of the provided surface tags. - void FilterPoints(const SurfaceTagVector& desiredTags); - - protected: - // These are kept in separate parallel vectors instead of a single struct so that it's possible to pass just specific data - // "channels" into other methods as span<> without having to pass the full struct into the span<>. Specifically, we want to be - // able to pass spans of the positions down through nesting gradient/surface calls. - // A side benefit is that profiling showed the data access to be faster than packing all the fields into a single struct. - AZStd::vector m_surfaceCreatorIdList; - AZStd::vector m_surfacePositionList; - AZStd::vector m_surfaceNormalList; - AZStd::vector m_surfaceWeightsList; - - AZ::Aabb m_pointBounds = AZ::Aabb::CreateNull(); - }; - - using SurfacePointLists = AZStd::vector; struct SurfaceDataRegistryEntry { + //! The entity ID of the surface provider / modifier AZ::EntityId m_entityId; + + //! The AABB bounds that this surface provider / modifier can affect, or null if it has infinite bounds. AZ::Aabb m_bounds = AZ::Aabb::CreateNull(); + + //! The set of surface tags that this surface provider / modifier can create or add to a point. SurfaceTagVector m_tags; + + //! The maximum number of surface points that this will create per input position. + //! For surface modifiers, this is always expected to be 0, and for surface providers it's expected to be > 0. + size_t m_maxPointsCreatedPerInput = 0; }; using SurfaceDataRegistryHandle = AZ::u32; diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/SurfacePointList.h b/Gems/SurfaceData/Code/Include/SurfaceData/SurfacePointList.h new file mode 100644 index 0000000000..83fb02c30a --- /dev/null +++ b/Gems/SurfaceData/Code/Include/SurfaceData/SurfacePointList.h @@ -0,0 +1,229 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace SurfaceData +{ + //! SurfacePointList stores a collection of surface point data, which consists of positions, normals, and surface tag weights. + //! This class is specifically designed to be used in the following ways. + //! + //! List construction: + //! StartListConstruction() - This clears the structure, temporarily holds on to the list of input positions, and preallocates the data. + //! AddSurfacePoint() - Add surface points to the list. They're expected to get added in input position order. + //! ModifySurfaceWeights() - Modify the surface weights for the set of input points. + //! FilterPoints() - Remove any generated surface points that don't fit the filter criteria + //! EndListConstruction() - "Freeze" and compact the data. + //! + //! List usage: + //! Any of the query APIs can be used in any order after the list has finished being constructed. + //! + //! This class is specifically designed around the usage patterns described above to minimize the amount of allocations and data + //! shifting that needs to occur. There are some tricky bits that need to be accounted for: + //! * Tracking which input positions each output point belongs to. + //! * Support for merging similar surface points together, which causes us to keep them sorted for easier comparisons. + //! * Each surface provider will add points in input position order, but we call each provider separately, so the added points will + //! show up like (0, 1, 2, 3), (0, 1, 3), (0, 0, 1, 2, 3), etc. We don't want to call each surface provider per-point, because that + //! incurs a lot of avoidable overhead in each provider. + //! * Output points get optionally filtered out at the very end if they don't match any of the filter tags passed in. + //! + //! The solution is that we always add new surface point data to the end of their respective vectors, but we also keep a helper + //! structure that's a list of lists of sorted indices. We can incrementally re-sort the indices quickly without having to shift + //! all the surface point data around. + class SurfacePointList + { + public: + AZ_CLASS_ALLOCATOR(SurfacePointList, AZ::SystemAllocator, 0); + AZ_TYPE_INFO(SurfacePointList, "{DBA02848-2131-4279-BDEF-3581B76AB736}"); + + SurfacePointList() = default; + ~SurfacePointList() = default; + + // ---------- List Construction APIs ------------- + + //! Clear the surface point list. + void Clear(); + + //! Constructor for creating a SurfacePointList from a list of SurfacePoint data. + //! Primarily used as a convenience for unit tests. + //! @param surfacePoints - A set of SurfacePoint points to store in the SurfacePointList. + //! Each point that's passed in will be treated as both the input and output position. + //! The list will be fully constructed and queryable after this runs. + SurfacePointList(AZStd::span surfacePoints); + + //! Start construction of a SurfacePointList from a list of SurfacePoint data. + //! Primarily used as a convenience for unit tests. + //! @param surfacePoints - A set of SurfacePoint points to store in the SurfacePointList. + //! The list will remain in the "constructing" state after this is called, so it will still be possible to add/modify + //! points, and EndListConstruction() will still need to be called. + void StartListConstruction(AZStd::span surfacePoints); + + //! Start construction of a SurfacePointList. + //! @param inPositions - the list of input positions that will be used to generate this list. This list is expected to remain + //! valid until EndListConstruction() is called. + //! @param maxPointsPerInput - the maximum number of potential surface points that will be generated for each input. This is used + //! for allocating internal structures during list construction and is enforced to be correct. + //! @param filterTags - optional list of tags to filter the generated surface points by. If this list is provided, every surface + //! point remaining in the list after construction will contain at least one of these tags. If the list is empty, all generated + //! points will remain in the list. The filterTags list is expected to remain valid until EndListConstruction() is called. + void StartListConstruction(AZStd::span inPositions, size_t maxPointsPerInput, + AZStd::span filterTags); + + //! Add a surface point to the list. + //! To use this method optimally, the points should get added in increasing inPosition index order. + //! @param entityId - The entity creating the surface point. + //! @param inPosition - The input position that produced this surface point. + //! @param position - The position of the surface point. + //! @param normal - The normal for the surface point. + //! @param weights - The surface tags and weights for this surface point. + void AddSurfacePoint(const AZ::EntityId& entityId, const AZ::Vector3& inPosition, + const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceTagWeights& weights); + + //! Modify the surface weights for each surface point in the list. + //! @param currentEntityId - The entity currently modifying the surface weights. This is used to prevent entities from modifying + //! any points they created. + //! @param modificationWeightCallback - The function to call for each surface point to process. + void ModifySurfaceWeights( + const AZ::EntityId& currentEntityId, + AZStd::function modificationWeightCallback); + + //! End construction of the SurfacePointList. + //! After this is called, surface points can no longer be added or modified, and all of the query APIs can start getting used. + void EndListConstruction(); + + // ---------- List Query APIs ------------- + + //! Return whether or not the entire surface point list is empty. + //! @return True if empty, false if it contains any points. + bool IsEmpty() const; + + //! Return whether or not a given input position index has any output points associated with it. + //! @param inputPositionIndex - The input position to look for output points for. + //! @return True if empty, false if there is at least one output point associated with the input position. + bool IsEmpty(size_t inputPositionIndex) const; + + //! Return the total number of output points generated. + //! @return The total number of output points generated. + size_t GetSize() const; + + //! Return the total number of output points generated from a specific input position index. + //! @param inputPositionIndex - The input position to look for output points for. + //! @return The total number of output points generated from a specific input position index. + size_t GetSize(size_t inputPositionIndex) const; + + //! Return the total number of input positions. + //! Normally the caller would already be expected to know this, but in the case of using region-based queries, the number of + //! input positions might not be entirely obvious. + //! @return The total number of input positions used to generate the outputs. + size_t GetInputPositionSize() const + { + return m_inputPositionSize; + } + + //! Enumerate every surface point and call a callback for each point found. + //! Note: There is no guaranteed order to which the points will be enumerated. + //! @pointCallback - The method to call with each surface point. + void EnumeratePoints( + AZStd::function + pointCallback) const; + + //! Enumerate every surface point for a given input position and call a callback for each point found. + //! Note: There is no guaranteed order to which the points will be enumerated. + //! @inputPositionIndex - The input position to get the outputs for. + //! @pointCallback - The method to call with each surface point. + void EnumeratePoints( + size_t inputPositionIndex, + AZStd::function pointCallback) const; + + //! Get the surface point with the highest Z value for a given input position. + //! @inputPositionIndex - The input position to get the highest surface point for. + //! @return The surface point with the highest Z value for the given input position. + AzFramework::SurfaceData::SurfacePoint GetHighestSurfacePoint(size_t inputPositionIndex) const; + + //! Get the AABB that encapsulates all of the generated output surface points. + //! @return The AABB surrounding all the output surface points. + AZ::Aabb GetSurfacePointAabb() const + { + return m_surfacePointBounds; + } + + protected: + // Remove any output surface points that don't contain any of the provided surface tags. + void FilterPoints(AZStd::span desiredTags); + + // Get the input position index associated with a specific input position. + size_t GetInPositionIndexFromPosition(const AZ::Vector3& inPosition) const; + + // Get the first entry in the sortedSurfacePointIndices list for the given input position index. + size_t GetSurfacePointStartIndexFromInPositionIndex(size_t inPositionIndex) const; + + // During list construction, keep track of the tags to filter the output points to. + // These will be used at the end of list construction to remove any output points that don't contain any of these tags. + // (If the list is empty, all output points will be retained) + AZStd::span m_filterTags; + + // During list construction, keep track of all the input positions that we'll generate outputs for. + // Note that after construction is complete, we'll only know how *many* input positions, but not their values. + // This keeps us from copying data that the caller should already have. We can't assume the lifetime of that data though, + // so we won't hold on to the span<> after construction. + AZStd::span m_inputPositions; + + // The total number of input positions that we have. We keep this value separately so that we can still know the quantity + // after list construction when our m_inputPositions span<> has become invalid. + size_t m_inputPositionSize = 0; + + // The last input position index that we used when adding points. + // This is used by GetInPositionIndexFromPosition() as an optimization to reduce search times for converting input positions + // to indices without needing to construct a separate search structure. + // Because we know surface points will get added in input position order, we'll always start looking for our next input position + // with the last one we used. + mutable size_t m_lastInputPositionIndex = 0; + + // This list is the size of m_inputPositions.size() and contains the number of output surface points that we've generated for + // each input point. + AZStd::vector m_numSurfacePointsPerInput; + + // The AABB surrounding all the surface points. We build this up incrementally as we add each surface point into the list. + AZ::Aabb m_surfacePointBounds = AZ::Aabb::CreateNull(); + + // The maximum number of output points that can be generated for each input. + size_t m_maxSurfacePointsPerInput = 0; + + // State tracker to determine whether or not the list is currently under construction. + // This is used to verify that the construction APIs are only used during construction, and the query APIs are only used + // after construction is complete. + bool m_listIsBeingConstructed = false; + + // List of lists that's used to index into our storage vectors for all the surface point data. + // The surface points are stored sequentially in creation order in the storage vectors. + // This should be thought of as a nested array - m_sortedSurfacePointIndices[m_inputPositionSize][m_maxSurfacePointsPerInput]. + // For each input position, the list of indices are kept sorted in decreasing Z order. + AZStd::vector m_sortedSurfacePointIndices; + + // Storage vectors for keeping track of all the created surface point data. + // These are kept in separate parallel vectors instead of a single struct so that it's possible to pass just specific data + // "channels" into other methods as span<> without having to pass the full struct into the span<>. Specifically, we want to be + // able to pass spans of the positions down through nesting gradient/surface calls. + AZStd::vector m_surfacePositionList; + AZStd::vector m_surfaceNormalList; + AZStd::vector m_surfaceWeightsList; + AZStd::vector m_surfaceCreatorIdList; + }; +} diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h b/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h index bafe215402..e07fad98e8 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h @@ -205,14 +205,14 @@ namespace UnitTest } void GetSurfacePointsFromRegion([[maybe_unused]] const AZ::Aabb& inRegion, [[maybe_unused]] const AZ::Vector2 stepSize, [[maybe_unused]] const SurfaceData::SurfaceTagVector& desiredTags, - [[maybe_unused]] SurfaceData::SurfacePointLists& surfacePointListPerPosition) const override + [[maybe_unused]] SurfaceData::SurfacePointList& surfacePointListPerPosition) const override { } void GetSurfacePointsFromList( [[maybe_unused]] AZStd::span inPositions, [[maybe_unused]] const SurfaceData::SurfaceTagVector& desiredTags, - [[maybe_unused]] SurfaceData::SurfacePointLists& surfacePointLists) const override + [[maybe_unused]] SurfaceData::SurfacePointList& surfacePointLists) const override { } diff --git a/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp b/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp index 35f377bfe0..5506d7640b 100644 --- a/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp +++ b/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp @@ -237,7 +237,7 @@ namespace SurfaceData if (DoRayTrace(inPosition, queryPointOnly, hitPosition, hitNormal)) { - surfacePointList.AddSurfacePoint(GetEntityId(), hitPosition, hitNormal, m_newPointWeights); + surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, hitPosition, hitNormal, m_newPointWeights); } } @@ -317,10 +317,11 @@ namespace SurfaceData providerRegistryEntry.m_entityId = GetEntityId(); providerRegistryEntry.m_bounds = m_colliderBounds; providerRegistryEntry.m_tags = m_configuration.m_providerTags; + providerRegistryEntry.m_maxPointsCreatedPerInput = 1; SurfaceDataRegistryEntry modifierRegistryEntry(providerRegistryEntry); modifierRegistryEntry.m_tags = m_configuration.m_modifierTags; - + modifierRegistryEntry.m_maxPointsCreatedPerInput = 0; if (!colliderValidBeforeUpdate && !colliderValidAfterUpdate) { diff --git a/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp b/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp index 973fca232a..ec81f06134 100644 --- a/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp +++ b/Gems/SurfaceData/Code/Source/Components/SurfaceDataShapeComponent.cpp @@ -146,7 +146,7 @@ namespace SurfaceData { AZStd::shared_lock lock(m_cacheMutex); - if (m_shapeBoundsIsValid) + if (m_shapeBoundsIsValid && SurfaceData::AabbContains2D(m_shapeBounds, inPosition)) { const AZ::Vector3 rayOrigin = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_shapeBounds.GetMax().GetZ()); const AZ::Vector3 rayDirection = -AZ::Vector3::CreateAxisZ(); @@ -156,7 +156,7 @@ namespace SurfaceData if (hitShape) { AZ::Vector3 position = rayOrigin + intersectionDistance * rayDirection; - surfacePointList.AddSurfacePoint(GetEntityId(), position, AZ::Vector3::CreateAxisZ(), m_newPointWeights); + surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, position, AZ::Vector3::CreateAxisZ(), m_newPointWeights); } } } @@ -238,9 +238,11 @@ namespace SurfaceData providerRegistryEntry.m_entityId = GetEntityId(); providerRegistryEntry.m_bounds = m_shapeBounds; providerRegistryEntry.m_tags = m_configuration.m_providerTags; + providerRegistryEntry.m_maxPointsCreatedPerInput = 1; SurfaceDataRegistryEntry modifierRegistryEntry(providerRegistryEntry); modifierRegistryEntry.m_tags = m_configuration.m_modifierTags; + modifierRegistryEntry.m_maxPointsCreatedPerInput = 0; if (shapeValidBeforeUpdate && shapeValidAfterUpdate) { diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp b/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp index 7dc6711b72..572b330579 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp +++ b/Gems/SurfaceData/Code/Source/SurfaceDataSystemComponent.cpp @@ -205,54 +205,12 @@ namespace SurfaceData void SurfaceDataSystemComponent::GetSurfacePoints(const AZ::Vector3& inPosition, const SurfaceTagVector& desiredTags, SurfacePointList& surfacePointList) const { - const bool useTagFilters = HasValidTags(desiredTags); - const bool hasModifierTags = useTagFilters && HasAnyMatchingTags(desiredTags, m_registeredModifierTags); - - AZStd::shared_lock registrationLock(m_registrationMutex); - - surfacePointList.Clear(); - surfacePointList.ReserveSpace(m_registeredSurfaceDataProviders.size()); - - //gather all intersecting points - for (const auto& entryPair : m_registeredSurfaceDataProviders) - { - const AZ::u32 entryAddress = entryPair.first; - const SurfaceDataRegistryEntry& entry = entryPair.second; - if (!entry.m_bounds.IsValid() || AabbContains2D(entry.m_bounds, inPosition)) - { - if (!useTagFilters || hasModifierTags || HasAnyMatchingTags(desiredTags, entry.m_tags)) - { - SurfaceDataProviderRequestBus::Event(entryAddress, &SurfaceDataProviderRequestBus::Events::GetSurfacePoints, inPosition, surfacePointList); - } - } - } - - if (!surfacePointList.IsEmpty()) - { - //modify or annotate reported points - for (const auto& entryPair : m_registeredSurfaceDataModifiers) - { - const AZ::u32 entryAddress = entryPair.first; - const SurfaceDataRegistryEntry& entry = entryPair.second; - if (!entry.m_bounds.IsValid() || AabbContains2D(entry.m_bounds, inPosition)) - { - SurfaceDataModifierRequestBus::Event(entryAddress, &SurfaceDataModifierRequestBus::Events::ModifySurfacePoints, surfacePointList); - } - } - - // After we've finished creating and annotating all the surface points, combine any points together that have effectively the - // same XY coordinates and extremely similar Z values. This produces results that are sorted in decreasing Z order. - // Also, this filters out any remaining points that don't match the desired tag list. This can happen when a surface provider - // doesn't add a desired tag, and a surface modifier has the *potential* to add it, but then doesn't. - if (useTagFilters) - { - surfacePointList.FilterPoints(desiredTags); - } - } + GetSurfacePointsFromListInternal( + AZStd::span(&inPosition, 1), AZ::Aabb::CreateFromPoint(inPosition), desiredTags, surfacePointList); } void SurfaceDataSystemComponent::GetSurfacePointsFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, - const SurfaceTagVector& desiredTags, SurfacePointLists& surfacePointLists) const + const SurfaceTagVector& desiredTags, SurfacePointList& surfacePointLists) const { const size_t totalQueryPositions = aznumeric_cast(ceil(inRegion.GetXExtent() / stepSize.GetX())) * aznumeric_cast(ceil(inRegion.GetYExtent() / stepSize.GetY())); @@ -270,47 +228,89 @@ namespace SurfaceData } } - GetSurfacePointsFromList(inPositions, desiredTags, surfacePointLists); + GetSurfacePointsFromListInternal(inPositions, inRegion, desiredTags, surfacePointLists); } void SurfaceDataSystemComponent::GetSurfacePointsFromList( - AZStd::span inPositions, const SurfaceTagVector& desiredTags, SurfacePointLists& surfacePointLists) const + AZStd::span inPositions, + const SurfaceTagVector& desiredTags, + SurfacePointList& surfacePointLists) const { - AZStd::shared_lock registrationLock(m_registrationMutex); - - const size_t totalQueryPositions = inPositions.size(); - - surfacePointLists.clear(); - surfacePointLists.resize(totalQueryPositions); - - for (auto& surfacePointList : surfacePointLists) + AZ::Aabb inBounds = AZ::Aabb::CreateNull(); + for (auto& position : inPositions) { - surfacePointList.ReserveSpace(m_registeredSurfaceDataProviders.size()); + inBounds.AddPoint(position); } + GetSurfacePointsFromListInternal(inPositions, inBounds, desiredTags, surfacePointLists); + } + + void SurfaceDataSystemComponent::GetSurfacePointsFromListInternal( + AZStd::span inPositions, const AZ::Aabb& inPositionBounds, + const SurfaceTagVector& desiredTags, SurfacePointList& surfacePointLists) const + { + AZStd::shared_lock registrationLock(m_registrationMutex); + const bool useTagFilters = HasValidTags(desiredTags); const bool hasModifierTags = useTagFilters && HasAnyMatchingTags(desiredTags, m_registeredModifierTags); - // Loop through each data provider, and query all the points for each one. This allows us to check the tags and the overall - // AABB bounds just once per provider, instead of once per point. It also allows for an eventual optimization in which we could - // send the list of points directly into each SurfaceDataProvider. - for (const auto& [providerHandle, provider] : m_registeredSurfaceDataProviders) + // Clear our output structure. + surfacePointLists.Clear(); + + auto ProviderIsApplicable = [useTagFilters, hasModifierTags, &desiredTags, &inPositionBounds] + (const SurfaceDataRegistryEntry& provider) -> bool { bool hasInfiniteBounds = !provider.m_bounds.IsValid(); + // Only allow surface providers that match our tag filters. However, if we aren't using tag filters, + // or if there's at least one surface modifier that can *add* a filtered tag to a created point, then + // allow all the surface providers. if (!useTagFilters || hasModifierTags || HasAnyMatchingTags(desiredTags, provider.m_tags)) { - for (size_t index = 0; index < totalQueryPositions; index++) + // Only allow surface providers that overlap the input position area. + if (hasInfiniteBounds || AabbOverlaps2D(provider.m_bounds, inPositionBounds)) { - bool inBounds = hasInfiniteBounds || AabbContains2D(provider.m_bounds, inPositions[index]); - if (inBounds) - { - SurfaceDataProviderRequestBus::Event( - providerHandle, &SurfaceDataProviderRequestBus::Events::GetSurfacePoints, - inPositions[index], surfacePointLists[index]); - } + return true; } } + + return false; + }; + + // Gather up the subset of surface providers that overlap the input positions. + size_t maxPointsCreatedPerInput = 0; + for (const auto& [providerHandle, provider] : m_registeredSurfaceDataProviders) + { + if (ProviderIsApplicable(provider)) + { + maxPointsCreatedPerInput += provider.m_maxPointsCreatedPerInput; + } + } + + // If we don't have any surface providers that will create any new surface points, then there's nothing more to do. + if (maxPointsCreatedPerInput == 0) + { + return; + } + + // Notify our output structure that we're starting to build up the list of output points. + // This will reserve memory and allocate temporary structures to help build up the list efficiently. + AZStd::span tagFilters; + if (useTagFilters) + { + tagFilters = desiredTags; + } + surfacePointLists.StartListConstruction(inPositions, maxPointsCreatedPerInput, tagFilters); + + // Loop through each data provider and generate surface points from the set of input positions. + // Any generated points that have the same XY coordinates and extremely similar Z values will get combined together. + for (const auto& [providerHandle, provider] : m_registeredSurfaceDataProviders) + { + if (ProviderIsApplicable(provider)) + { + SurfaceDataProviderRequestBus::Event( + providerHandle, &SurfaceDataProviderRequestBus::Events::GetSurfacePointsFromList, inPositions, surfacePointLists); + } } // Once we have our list of surface points created, run through the list of surface data modifiers to potentially add @@ -318,43 +318,28 @@ namespace SurfaceData // create new surface points, but surface data *modifiers* simply annotate points that have already been created. The modifiers // are used to annotate points that occur within a volume. A common example is marking points as "underwater" for points that occur // within a water volume. - for (const auto& entryPair : m_registeredSurfaceDataModifiers) + for (const auto& [modifierHandle, modifier] : m_registeredSurfaceDataModifiers) { - const SurfaceDataRegistryEntry& entry = entryPair.second; - bool hasInfiniteBounds = !entry.m_bounds.IsValid(); + bool hasInfiniteBounds = !modifier.m_bounds.IsValid(); - for (size_t index = 0; index < totalQueryPositions; index++) + if (hasInfiniteBounds || AabbOverlaps2D(modifier.m_bounds, surfacePointLists.GetSurfacePointAabb())) { - const auto& inPosition = inPositions[index]; - SurfacePointList& surfacePointList = surfacePointLists[index]; - if (!surfacePointList.IsEmpty()) - { - if (hasInfiniteBounds || AabbContains2D(entry.m_bounds, inPosition)) - { - SurfaceDataModifierRequestBus::Event( - entryPair.first, &SurfaceDataModifierRequestBus::Events::ModifySurfacePoints, - surfacePointList); - } - } + SurfaceDataModifierRequestBus::Event( + modifierHandle, &SurfaceDataModifierRequestBus::Events::ModifySurfacePoints, + surfacePointLists); } } - // After we've finished creating and annotating all the surface points, combine any points together that have effectively the - // same XY coordinates and extremely similar Z values. This produces results that are sorted in decreasing Z order. - // Also, this filters out any remaining points that don't match the desired tag list. This can happen when a surface provider + // Notify the output structure that we're done building up the list. + // This will filter out any remaining points that don't match the desired tag list. This can happen when a surface provider // doesn't add a desired tag, and a surface modifier has the *potential* to add it, but then doesn't. - if (useTagFilters) - { - for (auto& surfacePointList : surfacePointLists) - { - surfacePointList.FilterPoints(desiredTags); - } - } - + // It may also compact the memory and free any temporary structures. + surfacePointLists.EndListConstruction(); } SurfaceDataRegistryHandle SurfaceDataSystemComponent::RegisterSurfaceDataProviderInternal(const SurfaceDataRegistryEntry& entry) { + AZ_Assert(entry.m_maxPointsCreatedPerInput > 0, "Surface data providers should always create at least 1 point."); AZStd::unique_lock registrationLock(m_registrationMutex); SurfaceDataRegistryHandle handle = ++m_registeredSurfaceDataProviderHandleCounter; m_registeredSurfaceDataProviders[handle] = entry; @@ -376,6 +361,7 @@ namespace SurfaceData bool SurfaceDataSystemComponent::UpdateSurfaceDataProviderInternal(const SurfaceDataRegistryHandle& handle, const SurfaceDataRegistryEntry& entry, AZ::Aabb& oldBounds) { + AZ_Assert(entry.m_maxPointsCreatedPerInput > 0, "Surface data providers should always create at least 1 point."); AZStd::unique_lock registrationLock(m_registrationMutex); auto entryItr = m_registeredSurfaceDataProviders.find(handle); if (entryItr != m_registeredSurfaceDataProviders.end()) @@ -389,6 +375,7 @@ namespace SurfaceData SurfaceDataRegistryHandle SurfaceDataSystemComponent::RegisterSurfaceDataModifierInternal(const SurfaceDataRegistryEntry& entry) { + AZ_Assert(entry.m_maxPointsCreatedPerInput == 0, "Surface data modifiers cannot create any points."); AZStd::unique_lock registrationLock(m_registrationMutex); SurfaceDataRegistryHandle handle = ++m_registeredSurfaceDataModifierHandleCounter; m_registeredSurfaceDataModifiers[handle] = entry; @@ -411,6 +398,7 @@ namespace SurfaceData bool SurfaceDataSystemComponent::UpdateSurfaceDataModifierInternal(const SurfaceDataRegistryHandle& handle, const SurfaceDataRegistryEntry& entry, AZ::Aabb& oldBounds) { + AZ_Assert(entry.m_maxPointsCreatedPerInput == 0, "Surface data modifiers cannot create any points."); AZStd::unique_lock registrationLock(m_registrationMutex); auto entryItr = m_registeredSurfaceDataModifiers.find(handle); if (entryItr != m_registeredSurfaceDataModifiers.end()) diff --git a/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp b/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp index 3d6378aa7c..06dda90992 100644 --- a/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp +++ b/Gems/SurfaceData/Code/Source/SurfaceDataTypes.cpp @@ -7,7 +7,6 @@ */ #include -#include namespace SurfaceData { @@ -118,7 +117,7 @@ namespace SurfaceData return FindTag(sampleTag) != m_weights.end(); } - bool SurfaceTagWeights::HasAnyMatchingTags(const SurfaceTagVector& sampleTags) const + bool SurfaceTagWeights::HasAnyMatchingTags(AZStd::span sampleTags) const { for (const auto& sampleTag : sampleTags) { @@ -137,7 +136,7 @@ namespace SurfaceData return weightEntry != m_weights.end() && weightMin <= weightEntry->m_weight && weightMax >= weightEntry->m_weight; } - bool SurfaceTagWeights::HasAnyMatchingTags(const SurfaceTagVector& sampleTags, float weightMin, float weightMax) const + bool SurfaceTagWeights::HasAnyMatchingTags(AZStd::span sampleTags, float weightMin, float weightMax) const { for (const auto& sampleTag : sampleTags) { @@ -169,151 +168,4 @@ namespace SurfaceData // The tag wasn't found, so return end(). return m_weights.end(); } - - - SurfacePointList::SurfacePointList(AZStd::initializer_list surfacePoints) - { - ReserveSpace(surfacePoints.size()); - - for (auto& point : surfacePoints) - { - SurfaceTagWeights weights(point.m_surfaceTags); - AddSurfacePoint(AZ::EntityId(), point.m_position, point.m_normal, weights); - } - } - - void SurfacePointList::AddSurfacePoint(const AZ::EntityId& entityId, - const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceTagWeights& masks) - { - // When adding a surface point, we'll either merge it with a similar existing point, or else add it in order of - // decreasing Z, so that our final results are sorted. - - for (size_t index = 0; index < m_surfacePositionList.size(); ++index) - { - // (Someday we should add a configurable tolerance for comparison) - if (m_surfacePositionList[index].IsClose(position) && m_surfaceNormalList[index].IsClose(normal)) - { - // consolidate points with similar attributes by adding masks/weights to the similar point instead of adding a new one. - m_surfaceWeightsList[index].AddSurfaceTagWeights(masks); - return; - } - else if (m_surfacePositionList[index].GetZ() < position.GetZ()) - { - m_pointBounds.AddPoint(position); - m_surfacePositionList.insert(m_surfacePositionList.begin() + index, position); - m_surfaceNormalList.insert(m_surfaceNormalList.begin() + index, normal); - m_surfaceWeightsList.insert(m_surfaceWeightsList.begin() + index, masks); - m_surfaceCreatorIdList.insert(m_surfaceCreatorIdList.begin() + index, entityId); - return; - } - } - - // The point wasn't merged and the sort puts it at the end, so just add the point to the end of the list. - m_pointBounds.AddPoint(position); - m_surfacePositionList.emplace_back(position); - m_surfaceNormalList.emplace_back(normal); - m_surfaceWeightsList.emplace_back(masks); - m_surfaceCreatorIdList.emplace_back(entityId); - } - - void SurfacePointList::Clear() - { - m_surfacePositionList.clear(); - m_surfaceNormalList.clear(); - m_surfaceWeightsList.clear(); - m_surfaceCreatorIdList.clear(); - } - - void SurfacePointList::ReserveSpace(size_t maxPointsPerInput) - { - AZ_Assert(m_surfacePositionList.empty(), "Trying to reserve space on a list that is already being used."); - - m_surfaceCreatorIdList.reserve(maxPointsPerInput); - m_surfacePositionList.reserve(maxPointsPerInput); - m_surfaceNormalList.reserve(maxPointsPerInput); - m_surfaceWeightsList.reserve(maxPointsPerInput); - } - - bool SurfacePointList::IsEmpty() const - { - return m_surfacePositionList.empty(); - } - - size_t SurfacePointList::GetSize() const - { - return m_surfacePositionList.size(); - } - - void SurfacePointList::EnumeratePoints( - AZStd::function - pointCallback) const - { - for (size_t index = 0; index < m_surfacePositionList.size(); index++) - { - if (!pointCallback(m_surfacePositionList[index], m_surfaceNormalList[index], m_surfaceWeightsList[index])) - { - break; - } - } - } - - void SurfacePointList::ModifySurfaceWeights( - const AZ::EntityId& currentEntityId, - AZStd::function modificationWeightCallback) - { - for (size_t index = 0; index < m_surfacePositionList.size(); index++) - { - if (m_surfaceCreatorIdList[index] != currentEntityId) - { - modificationWeightCallback(m_surfacePositionList[index], m_surfaceWeightsList[index]); - } - } - } - - AzFramework::SurfaceData::SurfacePoint SurfacePointList::GetHighestSurfacePoint() const - { - AzFramework::SurfaceData::SurfacePoint point; - point.m_position = m_surfacePositionList.front(); - point.m_normal = m_surfaceNormalList.front(); - point.m_surfaceTags = m_surfaceWeightsList.front().GetSurfaceTagWeightList(); - - return point; - } - - void SurfacePointList::FilterPoints(const SurfaceTagVector& desiredTags) - { - // Filter out any points that don't match our search tags. - // This has to be done after the Surface Modifiers have processed the points, not at point insertion time, because - // Surface Modifiers add tags to existing points. - size_t listSize = m_surfacePositionList.size(); - size_t index = 0; - for (; index < listSize; index++) - { - if (!m_surfaceWeightsList[index].HasAnyMatchingTags(desiredTags)) - { - break; - } - } - - if (index != listSize) - { - size_t next = index + 1; - for (; next < listSize; ++next) - { - if (m_surfaceWeightsList[index].HasAnyMatchingTags(desiredTags)) - { - m_surfaceCreatorIdList[index] = m_surfaceCreatorIdList[next]; - m_surfacePositionList[index] = m_surfacePositionList[next]; - m_surfaceNormalList[index] = m_surfaceNormalList[next]; - m_surfaceWeightsList[index] = m_surfaceWeightsList[next]; - ++index; - } - } - - m_surfaceCreatorIdList.resize(index); - m_surfacePositionList.resize(index); - m_surfaceNormalList.resize(index); - m_surfaceWeightsList.resize(index); - } - } } diff --git a/Gems/SurfaceData/Code/Source/SurfacePointList.cpp b/Gems/SurfaceData/Code/Source/SurfacePointList.cpp new file mode 100644 index 0000000000..4e9d618ba4 --- /dev/null +++ b/Gems/SurfaceData/Code/Source/SurfacePointList.cpp @@ -0,0 +1,361 @@ +/* + * 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 + * + */ + +#include +#include + +namespace SurfaceData +{ + size_t SurfacePointList::GetInPositionIndexFromPosition(const AZ::Vector3& inPosition) const + { + // Given an input position, find the input position index that's associated with it. + // We'll bias towards always having a position that's the same or further in our input list than before, + // so we'll do a linear search that starts with the last input position we used, and goes forward (and wraps around) + // until we've searched them all. + // Our expectation is that most of the time, we'll only have to compare 0-1 input positions. + + size_t inPositionIndex = m_lastInputPositionIndex; + bool foundMatch = false; + for (size_t indexCounter = 0; indexCounter < m_inputPositions.size(); indexCounter++) + { + if (m_inputPositions[inPositionIndex] == inPosition) + { + foundMatch = true; + break; + } + + inPositionIndex = (inPositionIndex + 1) % m_inputPositions.size(); + } + + AZ_Assert(foundMatch, "Couldn't find input position!"); + m_lastInputPositionIndex = inPositionIndex; + return inPositionIndex; + } + + size_t SurfacePointList::GetSurfacePointStartIndexFromInPositionIndex(size_t inPositionIndex) const + { + // Index to the first output surface point for this input position. + return inPositionIndex * m_maxSurfacePointsPerInput; + } + + SurfacePointList::SurfacePointList(AZStd::span surfacePoints) + { + // Construct and finalize the list with the set of passed-in surface points. + // This is primarily a convenience for unit tests. + StartListConstruction(surfacePoints); + EndListConstruction(); + } + + void SurfacePointList::StartListConstruction(AZStd::span surfacePoints) + { + // Construct the list with the set of passed-in surface points but don't finalize it. + // This is primarily a convenience for unit tests that want to test surface modifiers with specific inputs. + + surfacePoints.begin(); + StartListConstruction(AZStd::span(&(surfacePoints.begin()->m_position), 1), surfacePoints.size(), {}); + + for (auto& point : surfacePoints) + { + SurfaceTagWeights weights(point.m_surfaceTags); + AddSurfacePoint(AZ::EntityId(), point.m_position, point.m_position, point.m_normal, weights); + } + } + + void SurfacePointList::StartListConstruction( + AZStd::span inPositions, size_t maxPointsPerInput, AZStd::span filterTags) + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to start list construction on a list currently under construction."); + AZ_Assert(m_surfacePositionList.empty(), "Trying to reserve space on a list that is already being used."); + + Clear(); + + m_listIsBeingConstructed = true; + + // Save off working references to the data we'll need during list construction. + // These references need to remain valid during construction, but not afterwards. + m_filterTags = filterTags; + m_inputPositions = inPositions; + m_inputPositionSize = inPositions.size(); + m_maxSurfacePointsPerInput = maxPointsPerInput; + + size_t outputReserveSize = inPositions.size() * m_maxSurfacePointsPerInput; + + // Reserve enough space to have one value per input position, and initialize it to 0. + m_numSurfacePointsPerInput.resize(m_inputPositionSize); + + // Reserve enough space to have maxSurfacePointsPerInput entries per input position, and initialize them all to 0. + m_sortedSurfacePointIndices.resize(outputReserveSize); + + // Reserve enough space for all our possible output surface points, but don't initialize them. + m_surfaceCreatorIdList.reserve(outputReserveSize); + m_surfacePositionList.reserve(outputReserveSize); + m_surfaceNormalList.reserve(outputReserveSize); + m_surfaceWeightsList.reserve(outputReserveSize); + } + + void SurfacePointList::Clear() + { + m_listIsBeingConstructed = false; + + m_lastInputPositionIndex = 0; + m_inputPositionSize = 0; + m_maxSurfacePointsPerInput = 0; + + m_filterTags = {}; + m_inputPositions = {}; + + m_sortedSurfacePointIndices.clear(); + m_numSurfacePointsPerInput.clear(); + m_surfacePositionList.clear(); + m_surfaceNormalList.clear(); + m_surfaceWeightsList.clear(); + m_surfaceCreatorIdList.clear(); + + m_surfacePointBounds = AZ::Aabb::CreateNull(); + } + + void SurfacePointList::AddSurfacePoint( + const AZ::EntityId& entityId, const AZ::Vector3& inPosition, + const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceTagWeights& masks) + { + AZ_Assert(m_listIsBeingConstructed, "Trying to add surface points to a SurfacePointList that isn't under construction."); + + // Find the inPositionIndex that matches the inPosition. + size_t inPositionIndex = GetInPositionIndexFromPosition(inPosition); + + // Find the first SurfacePoint that either matches the inPosition, or that starts the range for the next inPosition after this one. + size_t surfacePointStartIndex = GetSurfacePointStartIndexFromInPositionIndex(inPositionIndex); + + // When adding a surface point, we'll either merge it with a similar existing point, or else add it in order of + // decreasing Z, so that our final results are sorted. + size_t surfacePointInsertIndex = surfacePointStartIndex; + + for (; surfacePointInsertIndex < (surfacePointStartIndex + m_numSurfacePointsPerInput[inPositionIndex]); ++surfacePointInsertIndex) + { + // (Someday we should add a configurable tolerance for comparison) + if (m_surfacePositionList[m_sortedSurfacePointIndices[surfacePointInsertIndex]].IsClose(position) && + m_surfaceNormalList[m_sortedSurfacePointIndices[surfacePointInsertIndex]].IsClose(normal)) + { + // consolidate points with similar attributes by adding masks/weights to the similar point instead of adding a new one. + m_surfaceWeightsList[m_sortedSurfacePointIndices[surfacePointInsertIndex]].AddSurfaceTagWeights(masks); + return; + } + else if (m_surfacePositionList[m_sortedSurfacePointIndices[surfacePointInsertIndex]].GetZ() < position.GetZ()) + { + break; + } + } + + // If we've made it here, we're adding the point, not merging it. + + // Verify we aren't adding more points than expected. + AZ_Assert(m_numSurfacePointsPerInput[inPositionIndex] < m_maxSurfacePointsPerInput, "Adding too many surface points."); + + // Expand our output AABB to include this point. + m_surfacePointBounds.AddPoint(position); + + // If this isn't the first output for this input position, shift our sorted indices for this input position to make room for + // the new entry. + if (m_numSurfacePointsPerInput[inPositionIndex] > 0) + { + size_t startIndex = surfacePointInsertIndex; + size_t endIndex = surfacePointStartIndex + m_numSurfacePointsPerInput[inPositionIndex]; + + AZStd::move_backward( + m_sortedSurfacePointIndices.begin() + startIndex, m_sortedSurfacePointIndices.begin() + endIndex, + m_sortedSurfacePointIndices.begin() + endIndex + 1); + } + + m_numSurfacePointsPerInput[inPositionIndex]++; + + // Insert the new sorted index that references into our storage vectors. + m_sortedSurfacePointIndices[surfacePointInsertIndex] = m_surfacePositionList.size(); + + // Add the new point to the back of our storage vectors. + m_surfacePositionList.emplace_back(position); + m_surfaceNormalList.emplace_back(normal); + m_surfaceWeightsList.emplace_back(masks); + m_surfaceCreatorIdList.emplace_back(entityId); + } + + void SurfacePointList::ModifySurfaceWeights( + const AZ::EntityId& currentEntityId, + AZStd::function modificationWeightCallback) + { + AZ_Assert(m_listIsBeingConstructed, "Trying to modify surface weights on a SurfacePointList that isn't under construction."); + + // For every valid output point, call the modification callback only if it doesn't match the entity that created the point. + for (size_t inputIndex = 0; (inputIndex < m_inputPositionSize); inputIndex++) + { + size_t surfacePointStartIndex = GetSurfacePointStartIndexFromInPositionIndex(inputIndex); + for (size_t index = surfacePointStartIndex; (index < (surfacePointStartIndex + m_numSurfacePointsPerInput[inputIndex])); + index++) + { + if (m_surfaceCreatorIdList[m_sortedSurfacePointIndices[index]] != currentEntityId) + { + modificationWeightCallback( + m_surfacePositionList[m_sortedSurfacePointIndices[index]], + m_surfaceWeightsList[m_sortedSurfacePointIndices[index]]); + } + } + } + } + + void SurfacePointList::FilterPoints(AZStd::span desiredTags) + { + AZ_Assert(m_listIsBeingConstructed, "Trying to filter a SurfacePointList that isn't under construction."); + + // Filter out any points that don't match our search tags. + // This has to be done after the Surface Modifiers have processed the points, not at point insertion time, because + // Surface Modifiers add tags to existing points. + // The algorithm below is basically an "erase_if" that's operating across multiple storage vectors and using one level of + // indirection to keep our sorted indices valid. + // At some point we might want to consider modifying this to compact the final storage to the minimum needed. + for (size_t inputIndex = 0; (inputIndex < m_inputPositionSize); inputIndex++) + { + size_t surfacePointStartIndex = GetSurfacePointStartIndexFromInPositionIndex(inputIndex); + size_t listSize = (surfacePointStartIndex + m_numSurfacePointsPerInput[inputIndex]); + size_t index = surfacePointStartIndex; + for (; index < listSize; index++) + { + if (!m_surfaceWeightsList[m_sortedSurfacePointIndices[index]].HasAnyMatchingTags(desiredTags)) + { + break; + } + } + + if (index != listSize) + { + size_t next = index + 1; + for (; next < listSize; ++next) + { + if (m_surfaceWeightsList[m_sortedSurfacePointIndices[index]].HasAnyMatchingTags(desiredTags)) + { + m_sortedSurfacePointIndices[index] = AZStd::move(m_sortedSurfacePointIndices[next]); + m_surfaceCreatorIdList[m_sortedSurfacePointIndices[index]] = + AZStd::move(m_surfaceCreatorIdList[m_sortedSurfacePointIndices[next]]); + m_surfacePositionList[m_sortedSurfacePointIndices[index]] = + AZStd::move(m_surfacePositionList[m_sortedSurfacePointIndices[next]]); + m_surfaceNormalList[m_sortedSurfacePointIndices[index]] = + AZStd::move(m_surfaceNormalList[m_sortedSurfacePointIndices[next]]); + m_surfaceWeightsList[m_sortedSurfacePointIndices[index]] = + AZStd::move(m_surfaceWeightsList[m_sortedSurfacePointIndices[next]]); + + m_numSurfacePointsPerInput[inputIndex]--; + + ++index; + } + } + } + } + } + + void SurfacePointList::EndListConstruction() + { + AZ_Assert(m_listIsBeingConstructed, "Trying to end list construction on a SurfacePointList that isn't under construction."); + + // Now that we've finished adding and modifying points, filter out any points that don't match the filterTags list, if we have one. + if (!m_filterTags.empty()) + { + FilterPoints(m_filterTags); + } + + m_listIsBeingConstructed = false; + m_inputPositions = {}; + m_filterTags = {}; + } + + bool SurfacePointList::IsEmpty() const + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to query a SurfacePointList that's still under construction."); + + return m_surfacePositionList.empty(); + } + + bool SurfacePointList::IsEmpty(size_t inputPositionIndex) const + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to query a SurfacePointList that's still under construction."); + + return (m_inputPositionSize == 0) || (m_numSurfacePointsPerInput[inputPositionIndex] == 0); + } + + size_t SurfacePointList::GetSize() const + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to query a SurfacePointList that's still under construction."); + + return m_surfacePositionList.size(); + } + + size_t SurfacePointList::GetSize(size_t inputPositionIndex) const + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to query a SurfacePointList that's still under construction."); + + return (m_inputPositionSize == 0) ? 0 : (m_numSurfacePointsPerInput[inputPositionIndex]); + } + + void SurfacePointList::EnumeratePoints( + size_t inputPositionIndex, + AZStd::function + pointCallback) const + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to query a SurfacePointList that's still under construction."); + + size_t surfacePointStartIndex = GetSurfacePointStartIndexFromInPositionIndex(inputPositionIndex); + for (size_t index = surfacePointStartIndex; + (index < (surfacePointStartIndex + m_numSurfacePointsPerInput[inputPositionIndex])); index++) + { + if (!pointCallback( + m_surfacePositionList[m_sortedSurfacePointIndices[index]], m_surfaceNormalList[m_sortedSurfacePointIndices[index]], + m_surfaceWeightsList[m_sortedSurfacePointIndices[index]])) + { + break; + } + } + } + + void SurfacePointList::EnumeratePoints( + AZStd::function + pointCallback) const + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to query a SurfacePointList that's still under construction."); + + for (size_t inputIndex = 0; (inputIndex < m_inputPositionSize); inputIndex++) + { + size_t surfacePointStartIndex = GetSurfacePointStartIndexFromInPositionIndex(inputIndex); + for (size_t index = surfacePointStartIndex; (index < (surfacePointStartIndex + m_numSurfacePointsPerInput[inputIndex])); + index++) + { + if (!pointCallback( + inputIndex, m_surfacePositionList[m_sortedSurfacePointIndices[index]], + m_surfaceNormalList[m_sortedSurfacePointIndices[index]], m_surfaceWeightsList[m_sortedSurfacePointIndices[index]])) + { + break; + } + } + } + } + + AzFramework::SurfaceData::SurfacePoint SurfacePointList::GetHighestSurfacePoint([[maybe_unused]] size_t inputPositionIndex) const + { + AZ_Assert(!m_listIsBeingConstructed, "Trying to query a SurfacePointList that's still under construction."); + + if (m_numSurfacePointsPerInput[inputPositionIndex] == 0) + { + return {}; + } + + size_t surfacePointStartIndex = GetSurfacePointStartIndexFromInPositionIndex(inputPositionIndex); + AzFramework::SurfaceData::SurfacePoint point; + point.m_position = m_surfacePositionList[m_sortedSurfacePointIndices[surfacePointStartIndex]]; + point.m_normal = m_surfaceNormalList[m_sortedSurfacePointIndices[surfacePointStartIndex]]; + point.m_surfaceTags = m_surfaceWeightsList[m_sortedSurfacePointIndices[surfacePointStartIndex]].GetSurfaceTagWeightList(); + + return point; + } + +} diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp index a507391ae6..187ace1cdb 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp @@ -213,7 +213,7 @@ namespace UnitTest // Query every point in our world at 1 meter intervals. for ([[maybe_unused]] auto _ : state) { - SurfaceData::SurfacePointLists points; + SurfaceData::SurfacePointList points; AZ::Aabb inRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(worldSize)); AZ::Vector2 stepSize(1.0f); @@ -248,7 +248,7 @@ namespace UnitTest } } - SurfaceData::SurfacePointLists points; + SurfaceData::SurfacePointList points; SurfaceData::SurfaceDataSystemRequestBus::Broadcast( &SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePointsFromList, queryPositions, filterTags, points); diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp index aca5a53f4d..8724227960 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp @@ -135,14 +135,17 @@ namespace UnitTest // Call GetSurfacePoints and verify the results SurfaceData::SurfacePointList pointList; + pointList.StartListConstruction(AZStd::span(&queryPoint, 1), 1, {}); SurfaceData::SurfaceDataProviderRequestBus::Event(providerHandle, &SurfaceData::SurfaceDataProviderRequestBus::Events::GetSurfacePoints, queryPoint, pointList); + pointList.EndListConstruction(); + if (pointOnProvider) { ASSERT_EQ(pointList.GetSize(), 1); - pointList.EnumeratePoints( - [this, expectedOutput]( - const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + pointList.EnumeratePoints([this, expectedOutput]( + [[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, + const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool { EXPECT_TRUE(SurfacePointsAreEqual(position, normal, masks, expectedOutput)); return true; @@ -185,12 +188,14 @@ namespace UnitTest // Call ModifySurfacePoints and verify the results // Add the surface point with a different entity ID than the entity doing the modification, so that the point doesn't get // filtered out. - SurfaceData::SurfacePointList pointList = { input }; + SurfaceData::SurfacePointList pointList; + pointList.StartListConstruction(AZStd::span(&input, 1)); SurfaceData::SurfaceDataModifierRequestBus::Event(modifierHandle, &SurfaceData::SurfaceDataModifierRequestBus::Events::ModifySurfacePoints, pointList); + pointList.EndListConstruction(); ASSERT_EQ(pointList.GetSize(), 1); - pointList.EnumeratePoints( - [this, expectedOutput]( - const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + pointList.EnumeratePoints([this, expectedOutput]( + [[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, + const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool { EXPECT_TRUE(SurfacePointsAreEqual(position, normal, masks, expectedOutput)); return true; diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp index 8500e557bf..9f9a30e21d 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataTest.cpp @@ -114,6 +114,14 @@ class MockSurfaceProvider if (m_providerType == ProviderType::SURFACE_PROVIDER) { + // If the mock provider is generating points, examine the size of the points lists we've added to the mock provider + // to determine the maximum number of points that we will output from a single input position. + registryEntry.m_maxPointsCreatedPerInput = 1; + for (auto& entry : m_GetSurfacePoints) + { + registryEntry.m_maxPointsCreatedPerInput = AZ::GetMax(registryEntry.m_maxPointsCreatedPerInput, entry.second.size()); + } + SurfaceData::SurfaceDataSystemRequestBus::BroadcastResult(m_providerHandle, &SurfaceData::SurfaceDataSystemRequestBus::Events::RegisterSurfaceDataProvider, registryEntry); SurfaceData::SurfaceDataProviderRequestBus::Handler::BusConnect(m_providerHandle); } @@ -152,7 +160,7 @@ class MockSurfaceProvider for (auto& point : surfacePoints->second) { SurfaceData::SurfaceTagWeights weights(point.m_surfaceTags); - surfacePointList.AddSurfacePoint(m_id, point.m_position, point.m_normal, weights); + surfacePointList.AddSurfacePoint(m_id, inPosition, point.m_position, point.m_normal, weights); } } } @@ -208,19 +216,22 @@ public: } void CompareSurfacePointListWithGetSurfacePoints( - const AZStd::vector& queryPositions, SurfaceData::SurfacePointLists& surfacePointLists, + const AZStd::vector& queryPositions, SurfaceData::SurfacePointList& surfacePointLists, const SurfaceData::SurfaceTagVector& testTags) { AZStd::vector singleQueryResults; + SurfaceData::SurfacePointList tempSingleQueryPointList; - for (auto& queryPosition : queryPositions) + for (size_t inputIndex = 0; inputIndex < queryPositions.size(); inputIndex++) { - SurfaceData::SurfacePointList tempSingleQueryPointList; + tempSingleQueryPointList.Clear(); + singleQueryResults.clear(); + SurfaceData::SurfaceDataSystemRequestBus::Broadcast( - &SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints, queryPosition, testTags, tempSingleQueryPointList); - tempSingleQueryPointList.EnumeratePoints( - [&singleQueryResults]( - const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + &SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints, queryPositions[inputIndex], testTags, tempSingleQueryPointList); + tempSingleQueryPointList.EnumeratePoints([&singleQueryResults]( + [[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, + const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool { AzFramework::SurfaceData::SurfacePoint point; point.m_position = position; @@ -229,28 +240,23 @@ public: singleQueryResults.emplace_back(AZStd::move(point)); return true; }); - } - // Verify that each point in each list is equal. - AzFramework::SurfaceData::SurfacePoint* singleQueryPoint = singleQueryResults.begin(); - for (size_t listIndex = 0; listIndex < surfacePointLists.size(); listIndex++) - { - auto& surfacePointList = surfacePointLists[listIndex]; - surfacePointList.EnumeratePoints( - [&singleQueryPoint, singleQueryResults]( + size_t resultIndex = 0; + surfacePointLists.EnumeratePoints( + inputIndex, + [&resultIndex, singleQueryResults]( const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool { - EXPECT_NE(singleQueryPoint, singleQueryResults.end()); + EXPECT_NE(resultIndex, singleQueryResults.size()); - EXPECT_EQ(position, singleQueryPoint->m_position); - EXPECT_EQ(normal, singleQueryPoint->m_normal); - EXPECT_TRUE(masks.SurfaceWeightsAreEqual(singleQueryPoint->m_surfaceTags)); - ++singleQueryPoint; + EXPECT_EQ(position, singleQueryResults[resultIndex].m_position); + EXPECT_EQ(normal, singleQueryResults[resultIndex].m_normal); + EXPECT_TRUE(masks.SurfaceWeightsAreEqual(singleQueryResults[resultIndex].m_surfaceTags)); + ++resultIndex; return true; }); + EXPECT_EQ(resultIndex, singleQueryResults.size()); } - - EXPECT_EQ(singleQueryPoint, singleQueryResults.end()); } @@ -484,7 +490,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion) // Query for all the surface points from (0, 0, 16) - (4, 4, 16) with a step size of 1. // Note that the Z range is deliberately chosen to be outside the surface provider range to demonstrate // that it is ignored when selecting points. - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(1.0f, 1.0f); AZ::Aabb regionBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f, 0.0f, 16.0f), AZ::Vector3(4.0f, 4.0f, 16.0f)); SurfaceData::SurfaceTagVector testTags = providerTags; @@ -496,21 +502,17 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion) // We expect every entry in the output list to have two surface points, at heights 0 and 4, sorted in // decreasing height order. The masks list should be the same size as the set of masks the provider owns. // We *could* check every mask as well for completeness, but that seems like overkill. - for (auto& pointList : availablePointsPerPosition) - { - EXPECT_EQ(pointList.GetSize(), 2); - float expectedZ = 4.0f; - pointList.EnumeratePoints( - [providerTags, - &expectedZ](const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal, - const SurfaceData::SurfaceTagWeights& masks) -> bool - { - EXPECT_EQ(position.GetZ(), expectedZ); - EXPECT_EQ(masks.GetSize(), providerTags.size()); - expectedZ = (expectedZ == 4.0f) ? 0.0f : 4.0f; - return true; - }); - } + float expectedZ = 4.0f; + availablePointsPerPosition.EnumeratePoints( + [availablePointsPerPosition, providerTags, &expectedZ](size_t inPositionIndex, const AZ::Vector3& position, + [[maybe_unused]] const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + { + EXPECT_EQ(availablePointsPerPosition.GetSize(inPositionIndex), 2); + EXPECT_EQ(position.GetZ(), expectedZ); + EXPECT_EQ(masks.GetSize(), providerTags.size()); + expectedZ = (expectedZ == 4.0f) ? 0.0f : 4.0f; + return true; + }); } TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_NoMatchingMasks) @@ -525,7 +527,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_NoMatchingMas // Query for all the surface points from (0, 0, 0) - (4, 4, 4) with a step size of 1. // We only include a surface tag that does NOT exist in the surface provider. - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(1.0f, 1.0f); AZ::Aabb regionBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(4.0f)); SurfaceData::SurfaceTagVector testTags = { SurfaceData::SurfaceTag(m_testSurfaceNoMatchCrc) }; @@ -536,10 +538,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_NoMatchingMas // We expect every entry in the output list to have no surface points, since the requested mask doesn't match // any of the masks from our mock surface provider. - for (auto& queryPosition : availablePointsPerPosition) - { - EXPECT_TRUE(queryPosition.IsEmpty()); - } + EXPECT_TRUE(availablePointsPerPosition.IsEmpty()); } TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_NoMatchingRegion) @@ -553,7 +552,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_NoMatchingReg AZ::Vector3(0.0f), AZ::Vector3(8.0f), AZ::Vector3(0.25f, 0.25f, 4.0f)); // Query for all the surface points from (16, 16) - (20, 20) with a step size of 1. - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(1.0f, 1.0f); AZ::Aabb regionBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(16.0f), AZ::Vector3(20.0f)); SurfaceData::SurfaceTagVector testTags = providerTags; @@ -564,10 +563,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_NoMatchingReg // We expect every entry in the output list to have no surface points, since the input points don't overlap with // our surface provider. - for (auto& pointList : availablePointsPerPosition) - { - EXPECT_TRUE(pointList.IsEmpty()); - } + EXPECT_TRUE(availablePointsPerPosition.IsEmpty()); } TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_ProviderModifierMasksCombine) @@ -603,7 +599,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_ProviderModif for (auto& tagTest : tagTests) { - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(1.0f, 1.0f); AZ::Aabb regionBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(4.0f)); SurfaceData::SurfaceTagVector testTags = tagTest; @@ -614,20 +610,17 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_ProviderModif // We expect every entry in the output list to have two surface points (with heights 0 and 4), // and each point should have both the "test_surface1" and "test_surface2" tag. - for (auto& pointList : availablePointsPerPosition) - { - EXPECT_EQ(pointList.GetSize(), 2); - float expectedZ = 4.0f; - pointList.EnumeratePoints( - [&expectedZ](const AZ::Vector3& position, - [[maybe_unused]] const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool - { - EXPECT_EQ(position.GetZ(), expectedZ); - EXPECT_EQ(masks.GetSize(), 2); - expectedZ = (expectedZ == 4.0f) ? 0.0f : 4.0f; - return true; - }); - } + float expectedZ = 4.0f; + availablePointsPerPosition.EnumeratePoints( + [availablePointsPerPosition, &expectedZ](size_t inPositionIndex, const AZ::Vector3& position, + [[maybe_unused]] const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + { + EXPECT_EQ(availablePointsPerPosition.GetSize(inPositionIndex), 2); + EXPECT_EQ(position.GetZ(), expectedZ); + EXPECT_EQ(masks.GetSize(), 2); + expectedZ = (expectedZ == 4.0f) ? 0.0f : 4.0f; + return true; + }); } } @@ -653,7 +646,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_SimilarPoints // Query for all the surface points from (0, 0) - (4, 4) with a step size of 1. - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(1.0f, 1.0f); AZ::Aabb regionBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(4.0f)); SurfaceData::SurfaceTagVector testTags = { SurfaceData::SurfaceTag(m_testSurface1Crc), SurfaceData::SurfaceTag(m_testSurface2Crc) }; @@ -664,23 +657,21 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_SimilarPoints // We expect every entry in the output list to have two surface points, not four. The two points // should have both surface tags on them. - for (auto& pointList : availablePointsPerPosition) - { - EXPECT_EQ(pointList.GetSize(), 2); - float expectedZ = 4.0f; - pointList.EnumeratePoints( - [&expectedZ]( - const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal, - const SurfaceData::SurfaceTagWeights& masks) -> bool - { - // Similar points get merged, but there's no guarantee which value will be kept, so we set our comparison tolerance - // high enough to allow both x.0 and x.0005 to pass. - EXPECT_NEAR(position.GetZ(), expectedZ, 0.001f); - EXPECT_EQ(masks.GetSize(), 2); - expectedZ = (expectedZ == 4.0f) ? 0.0f : 4.0f; - return true; - }); - } + float expectedZ = 4.0f; + availablePointsPerPosition.EnumeratePoints( + [availablePointsPerPosition, &expectedZ]( + size_t inPositionIndex, const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal, + const SurfaceData::SurfaceTagWeights& masks) -> bool + { + EXPECT_EQ(availablePointsPerPosition.GetSize(inPositionIndex), 2); + + // Similar points get merged, but there's no guarantee which value will be kept, so we set our comparison tolerance + // high enough to allow both x.0 and x.0005 to pass. + EXPECT_NEAR(position.GetZ(), expectedZ, 0.001f); + EXPECT_EQ(masks.GetSize(), 2); + expectedZ = (expectedZ == 4.0f) ? 0.0f : 4.0f; + return true; + }); } TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_DissimilarPointsDoNotMergeTogether) @@ -704,7 +695,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_DissimilarPoi // Query for all the surface points from (0, 0) - (4, 4) with a step size of 1. - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(1.0f, 1.0f); AZ::Aabb regionBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f), AZ::Vector3(4.0f)); SurfaceData::SurfaceTagVector testTags = { SurfaceData::SurfaceTag(m_testSurface1Crc), SurfaceData::SurfaceTag(m_testSurface2Crc) }; @@ -715,17 +706,14 @@ TEST_F(SurfaceDataTestApp, SurfaceData_TestSurfacePointsFromRegion_DissimilarPoi // We expect every entry in the output list to have four surface points with one tag each, // because the points are far enough apart that they won't merge. - for (auto& pointList : availablePointsPerPosition) - { - EXPECT_EQ(pointList.GetSize(), 4); - pointList.EnumeratePoints( - []([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal, - const SurfaceData::SurfaceTagWeights& masks) -> bool - { - EXPECT_EQ(masks.GetSize(), 1); - return true; - }); - } + availablePointsPerPosition.EnumeratePoints( + [availablePointsPerPosition](size_t inPositionIndex, [[maybe_unused]] const AZ::Vector3& position, + [[maybe_unused]] const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + { + EXPECT_EQ(availablePointsPerPosition.GetSize(inPositionIndex), 4); + EXPECT_EQ(masks.GetSize(), 1); + return true; + }); } TEST_F(SurfaceDataTestApp, SurfaceData_VerifyGetSurfacePointsFromRegionAndGetSurfacePointsMatch) @@ -741,7 +729,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_VerifyGetSurfacePointsFromRegionAndGetSur AZ::Vector3(0.25f, 0.25f, 4.0f)); // Query for all the surface points from (0, 0, 16) - (4, 4, 16) with a step size of 1. - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(1.0f, 1.0f); AZ::Aabb regionBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f, 0.0f, 16.0f), AZ::Vector3(4.0f, 4.0f, 16.0f)); @@ -775,7 +763,7 @@ TEST_F(SurfaceDataTestApp, SurfaceData_VerifyGetSurfacePointsFromListAndGetSurfa AZ::Vector3(0.25f, 0.25f, 4.0f)); // Query for all the surface points from (0, 0, 16) - (4, 4, 16) with a step size of 1. - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZStd::vector queryPositions; for (float y = 0.0f; y < 4.0f; y += 1.0f) { @@ -789,8 +777,6 @@ TEST_F(SurfaceDataTestApp, SurfaceData_VerifyGetSurfacePointsFromListAndGetSurfa &SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePointsFromList, queryPositions, providerTags, availablePointsPerPosition); - EXPECT_EQ(availablePointsPerPosition.size(), 16); - // For each point entry returned from GetSurfacePointsFromList, call GetSurfacePoints and verify the results match. CompareSurfacePointListWithGetSurfacePoints(queryPositions, availablePointsPerPosition, providerTags); } diff --git a/Gems/SurfaceData/Code/surfacedata_files.cmake b/Gems/SurfaceData/Code/surfacedata_files.cmake index 8e7435abb3..7db0d869dd 100644 --- a/Gems/SurfaceData/Code/surfacedata_files.cmake +++ b/Gems/SurfaceData/Code/surfacedata_files.cmake @@ -18,10 +18,12 @@ set(FILES Include/SurfaceData/SurfaceDataTagProviderRequestBus.h Include/SurfaceData/SurfaceDataProviderRequestBus.h Include/SurfaceData/SurfaceDataModifierRequestBus.h + Include/SurfaceData/SurfacePointList.h Include/SurfaceData/SurfaceTag.h Include/SurfaceData/Utility/SurfaceDataUtility.h Source/SurfaceDataSystemComponent.cpp Source/SurfaceDataTypes.cpp + Source/SurfacePointList.cpp Source/SurfaceTag.cpp Source/Components/SurfaceDataColliderComponent.cpp Source/Components/SurfaceDataShapeComponent.cpp diff --git a/Gems/Terrain/Code/Source/Components/TerrainSurfaceDataSystemComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainSurfaceDataSystemComponent.cpp index 3092f7c000..cf149c0f3c 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainSurfaceDataSystemComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainSurfaceDataSystemComponent.cpp @@ -165,7 +165,7 @@ namespace Terrain const AZ::Crc32 terrainTag = isHole ? Constants::s_terrainHoleTagCrc : Constants::s_terrainTagCrc; weights.AddSurfaceTagWeight(terrainTag, 1.0f); - surfacePointList.AddSurfacePoint(GetEntityId(), terrainSurfacePoint.m_position, terrainSurfacePoint.m_normal, weights); + surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, terrainSurfacePoint.m_position, terrainSurfacePoint.m_normal, weights); } AZ::Aabb TerrainSurfaceDataSystemComponent::GetSurfaceAabb() const @@ -192,6 +192,7 @@ namespace Terrain registryEntry.m_entityId = GetEntityId(); registryEntry.m_bounds = GetSurfaceAabb(); registryEntry.m_tags = GetSurfaceTags(); + registryEntry.m_maxPointsCreatedPerInput = 1; m_terrainBounds = registryEntry.m_bounds; m_terrainBoundsIsValid = m_terrainBounds.IsValid(); diff --git a/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp b/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp index f4ef3bd6f1..a0982591a2 100644 --- a/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp @@ -1099,7 +1099,7 @@ namespace Vegetation // 0 = lower left corner, 0.5 = center const float texelOffset = (sectorPointSnapMode == SnapMode::Center) ? 0.5f : 0.0f; - SurfaceData::SurfacePointLists availablePointsPerPosition; + SurfaceData::SurfacePointList availablePointsPerPosition; AZ::Vector2 stepSize(vegStep, vegStep); AZ::Vector3 regionOffset(texelOffset * vegStep, texelOffset * vegStep, 0.0f); AZ::Aabb regionBounds = sectorInfo.m_bounds; @@ -1120,27 +1120,20 @@ namespace Vegetation SurfaceData::SurfaceTagVector(), availablePointsPerPosition); - AZ_Assert(availablePointsPerPosition.size() == (sectorDensity * sectorDensity), - "Veg sector ended up with unexpected density (%d points created, %d expected)", availablePointsPerPosition.size(), - (sectorDensity * sectorDensity)); - uint claimIndex = 0; - for (auto& availablePoints : availablePointsPerPosition) - { - availablePoints.EnumeratePoints( - [this, §orInfo, - &claimIndex](const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool - { - sectorInfo.m_baseContext.m_availablePoints.push_back(); - ClaimPoint& claimPoint = sectorInfo.m_baseContext.m_availablePoints.back(); - claimPoint.m_handle = CreateClaimHandle(sectorInfo, ++claimIndex); - claimPoint.m_position = position; - claimPoint.m_normal = normal; - claimPoint.m_masks = masks; - sectorInfo.m_baseContext.m_masks.AddSurfaceTagWeights(masks); - return true; - }); - } + availablePointsPerPosition.EnumeratePoints([this, §orInfo, &claimIndex] + ([[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, + const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + { + sectorInfo.m_baseContext.m_availablePoints.push_back(); + ClaimPoint& claimPoint = sectorInfo.m_baseContext.m_availablePoints.back(); + claimPoint.m_handle = CreateClaimHandle(sectorInfo, ++claimIndex); + claimPoint.m_position = position; + claimPoint.m_normal = normal; + claimPoint.m_masks = masks; + sectorInfo.m_baseContext.m_masks.AddSurfaceTagWeights(masks); + return true; + }); } void AreaSystemComponent::VegetationThreadTasks::UpdateSectorCallbacks(SectorInfo& sectorInfo) diff --git a/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp b/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp index ed81ebae87..efc8f0bdf9 100644 --- a/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp @@ -328,7 +328,8 @@ namespace Vegetation AZ::Vector3 originalInstanceDataPosition = instanceData.m_position; m_points.EnumeratePoints( [&instanceData, originalInstanceDataPosition, &closestPointDistanceSq]( - const AZ::Vector3& position, const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool + [[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, + const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool { float distanceSq = position.GetDistanceSq(originalInstanceDataPosition); if (distanceSq < closestPointDistanceSq) diff --git a/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp index aa6c3a8440..986506f573 100644 --- a/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp @@ -220,7 +220,7 @@ namespace Vegetation float instanceZ = instanceData.m_position.GetZ(); m_points.EnumeratePoints( [instanceZ, lowerZDistanceRange, upperZDistanceRange, &passesFilter]( - const AZ::Vector3& position, + [[maybe_unused]] size_t inPositionIndex, const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal, [[maybe_unused]] const SurfaceData::SurfaceTagWeights& masks) -> bool { float pointZ = position.GetZ(); diff --git a/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.h b/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.h index 0a83ddeea3..9c43c91c69 100644 --- a/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.h +++ b/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp index abb577acfc..0bb8c57c44 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp @@ -862,7 +862,8 @@ void DebugComponent::PrepareNextReport() SurfaceData::SurfacePointList points; SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints, pos, SurfaceData::SurfaceTagVector(), points); - timing.m_worldPosition = points.IsEmpty() ? pos : points.GetHighestSurfacePoint().m_position; + constexpr size_t inPositionIndex = 0; + timing.m_worldPosition = points.IsEmpty(inPositionIndex) ? pos : points.GetHighestSurfacePoint(inPositionIndex).m_position; return timing; }, [](const SectorTracker& sectorTracker, SectorTiming& sectorTiming) diff --git a/Gems/Vegetation/Code/Tests/VegetationMocks.h b/Gems/Vegetation/Code/Tests/VegetationMocks.h index 33a320b03e..dc09d13d92 100644 --- a/Gems/Vegetation/Code/Tests/VegetationMocks.h +++ b/Gems/Vegetation/Code/Tests/VegetationMocks.h @@ -333,18 +333,21 @@ namespace UnitTest void GetSurfacePoints([[maybe_unused]] const AZ::Vector3& inPosition, [[maybe_unused]] const SurfaceData::SurfaceTagVector& masks, SurfaceData::SurfacePointList& surfacePointList) const override { ++m_count; - surfacePointList.AddSurfacePoint(AZ::EntityId(), m_outPosition, m_outNormal, m_outMasks); + surfacePointList.Clear(); + surfacePointList.StartListConstruction(AZStd::span(&inPosition, 1), 1, {}); + surfacePointList.AddSurfacePoint(AZ::EntityId(), inPosition, m_outPosition, m_outNormal, m_outMasks); + surfacePointList.EndListConstruction(); } void GetSurfacePointsFromRegion([[maybe_unused]] const AZ::Aabb& inRegion, [[maybe_unused]] const AZ::Vector2 stepSize, [[maybe_unused]] const SurfaceData::SurfaceTagVector& desiredTags, - [[maybe_unused]] SurfaceData::SurfacePointLists& surfacePointListPerPosition) const override + [[maybe_unused]] SurfaceData::SurfacePointList& surfacePointListPerPosition) const override { } void GetSurfacePointsFromList( [[maybe_unused]] AZStd::span inPositions, [[maybe_unused]] const SurfaceData::SurfaceTagVector& desiredTags, - [[maybe_unused]] SurfaceData::SurfacePointLists& surfacePointLists) const override + [[maybe_unused]] SurfaceData::SurfacePointList& surfacePointLists) const override { } From 92cd457c256e1ec91eeabe04b56d1d4c61f8b1af Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Mon, 14 Feb 2022 17:18:43 -0600 Subject: [PATCH 34/42] MacOS build fix (#7627) * MacOS build fix Updated the HpAllocator::bucket to align upwards to the nearest power of 2. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Adding static assets to validate teh AlignUpToPowerOfTwo function. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../AzCore/AzCore/Memory/HphaSchema.cpp | 103 +++++++++++++++--- 1 file changed, 86 insertions(+), 17 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp index 9af99a05b9..fc900ca2f4 100644 --- a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp @@ -42,8 +42,8 @@ #define HPPA_ASSERT_PRINT_STACK(...) _EXPAND(_GET_MACRO23(__VA_ARGS__, _HPPA_ASSERT_PRINT_STACK3, _HPPA_ASSERT_PRINT_STACK2)(__VA_ARGS__)) -namespace AZ { - +namespace AZ +{ /// default windows virtual page size \todo Read this from the OS when we create the allocator) #define OS_VIRTUAL_PAGE_SIZE AZ_PAGE_SIZE ////////////////////////////////////////////////////////////////////////// @@ -57,6 +57,79 @@ namespace AZ { // Enabled mutex per bucket #define USE_MUTEX_PER_BUCKET + namespace HphaInternal + { + //! Rounds up a value to next power of 2. + //! For example to round 8388609((2^23) + 1) up to 16777216(2^24) the following occurs + //! Subtract one from the value in case it is already + //! equal to a power of 2 + //! 8388609 - 1 = 8388608 + //! Propagate the highest one bit in the value to all the lower bits + //! 8388608 = 0b100'0000'0000'0000'0000'0000 in binary + //! + //! 0b100'0000'0000'0000'0000'0000 + //! |0b010'0000'0000'0000'0000'0000 (>> 1) + //! ------------------------------- + //! 0b110'0000'0000'0000'0000'0000 (Now there are 2 consecutive 1-bits) + //! |0b001'1000'0000'0000'0000'0000 (>> 2) + //! ------------------------------- + //! 0b111'1000'0000'0000'0000'0000 (Now there are 4 consecutive 1-bits) + //! |0b000'0111'1000'0000'0000'0000 (>> 4) + //! ------------------------------- + //! 0b111'1111'1000'0000'0000'0000 (Now there are 8 consecutive 1-bits) + //! |0b000'0000'0111'1111'1000'0000 (>> 8) + //! ------------------------------- + //! 0b111'1111'1111'1111'1000'0000 (Now there are 16 consecutive 1-bits) + //! |0b000'0000'0000'0000'0111'1111 (>> 16) + //! ------------------------------- + //! 0b111'1111'1111'1111'1111'1111 (Now there are 23 consecutive 1-bits) + //! |0b000'0000'0000'0000'0000'0000 (>> 32) + //! ------------------------------- + //! 0b111'1111'1111'1111'1111'1111 + //! Finally since all the one bits are set in the value, adding one pushes it + //! to next power of 2 + //! 0b1000'0000'0000'0000'0000'0000 = 16777216 + static constexpr size_t AlignUpToPowerOfTwo(size_t value) + { + // If the value is <=2 it is already aligned + if (value <= 2) + { + return value; + } + + // Subtract one to make any values already + // aligned to a power of 2 less than that power of 2 + // so that algorithm doesn't push those values upwards + --value; + value |= value >> 0b1; + value |= value >> 0b10; + value |= value >> 0b100; + value |= value >> 0b1000; + value |= value >> 0b1'0000; + value |= value >> 0b10'0000; + ++value; + return value; + } + + static_assert(AlignUpToPowerOfTwo(0) == 0); + static_assert(AlignUpToPowerOfTwo(1) == 1); + static_assert(AlignUpToPowerOfTwo(2) == 2); + static_assert(AlignUpToPowerOfTwo(3) == 4); + static_assert(AlignUpToPowerOfTwo(4) == 4); + static_assert(AlignUpToPowerOfTwo(5) == 8); + static_assert(AlignUpToPowerOfTwo(8) == 8); + static_assert(AlignUpToPowerOfTwo(10) == 16); + static_assert(AlignUpToPowerOfTwo(16) == 16); + static_assert(AlignUpToPowerOfTwo(24) == 32); + static_assert(AlignUpToPowerOfTwo(32) == 32); + static_assert(AlignUpToPowerOfTwo(45) == 64); + static_assert(AlignUpToPowerOfTwo(64) == 64); + static_assert(AlignUpToPowerOfTwo(112) == 128); + static_assert(AlignUpToPowerOfTwo(128) == 128); + static_assert(AlignUpToPowerOfTwo(136) == 256); + static_assert(AlignUpToPowerOfTwo(256) == 256); + } + ////////////////////////////////////////////////////////////////////////// class HpAllocator { @@ -211,24 +284,21 @@ namespace AZ { bool check_marker(size_t marker) const { return mMarker == (marker ^ ((size_t)this)); } }; using page_list = AZStd::intrusive_list>; - class bucket + +#if defined(MULTITHREADED) && defined(USE_MUTEX_PER_BUCKET) + static constexpr size_t BucketAlignment = HphaInternal::AlignUpToPowerOfTwo(sizeof(page_list) + sizeof(AZStd::mutex) + sizeof(size_t)); +#else + static constexpr size_t BucketAlignment = HphaInternal::AlignUpToPowerOfTwo(sizeof(page_list) + sizeof(size_t)); +#endif + AZ_PUSH_DISABLE_WARNING_MSVC(4324) + class alignas(BucketAlignment) bucket { page_list mPageList; -#ifdef MULTITHREADED - #if defined (USE_MUTEX_PER_BUCKET) +#if defined(MULTITHREADED) && defined(USE_MUTEX_PER_BUCKET) mutable AZStd::mutex mLock; - #endif #endif size_t mMarker; -#ifdef MULTITHREADED - #if defined (USE_MUTEX_PER_BUCKET) - unsigned char _padding[sizeof(void*) * 16 - sizeof(page_list) - sizeof(AZStd::mutex) - sizeof(size_t)]; - #else - unsigned char _padding[sizeof(void*) * 16 - sizeof(page_list) - sizeof(size_t)]; - #endif -#else - unsigned char _padding[sizeof(void*) * 4 - sizeof(page_list) - sizeof(size_t)]; -#endif + public: bucket(); #ifdef MULTITHREADED @@ -249,6 +319,7 @@ namespace AZ { void free(page* p, void* ptr); void unlink(page* p); }; + AZ_POP_DISABLE_WARNING_MSVC void* bucket_system_alloc(); void bucket_system_free(void* ptr); page* bucket_grow(size_t elemSize, size_t marker); @@ -1033,8 +1104,6 @@ namespace AZ { // Thats why we use SimpleLcgRandom here AZ::SimpleLcgRandom randGenerator = AZ::SimpleLcgRandom(reinterpret_cast(static_cast(this))); mMarker = size_t(randGenerator.Getu64Random()); - - (void)_padding; } HpAllocator::page* HpAllocator::bucket::get_free_page() From 377da0ed0c346ca5c9e2381baf61215d5fb3db6a Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Mon, 14 Feb 2022 16:13:37 -0800 Subject: [PATCH 35/42] Ignore unused benchmark state variables Signed-off-by: Chris Burel --- Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp | 4 ++-- Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp | 2 +- Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp index e44ba3ce67..d67597255f 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPatchBenchmarks.cpp @@ -78,7 +78,7 @@ namespace AZ::Dom::Benchmark if (apply) { auto patchInfo = GenerateHierarchicalDeltaPatch(m_before, m_after); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { auto patchResult = patchInfo.m_forwardPatches.Apply(m_before); benchmark::DoNotOptimize(patchResult); @@ -86,7 +86,7 @@ namespace AZ::Dom::Benchmark } else { - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { auto patchInfo = GenerateHierarchicalDeltaPatch(m_before, m_after); benchmark::DoNotOptimize(patchInfo); diff --git a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp index 10c5fa1394..56d1e1f6ab 100644 --- a/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp +++ b/Code/Framework/AzCore/Tests/DOM/DomPathBenchmarks.cpp @@ -104,7 +104,7 @@ namespace AZ::Dom::Benchmark PathEntry endOfArray; endOfArray.SetEndOfArray(); - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { benchmark::DoNotOptimize(name == name); benchmark::DoNotOptimize(name == index); diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp index 187ace1cdb..549e8b8bea 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataBenchmarks.cpp @@ -289,7 +289,7 @@ namespace UnitTest tag = randomGenerator.GetRandom(); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { // We'll benchmark this two ways: // 1. We clear each time, which means each AddSurfaceWeightIfGreater call will search the whole list then add. @@ -340,7 +340,7 @@ namespace UnitTest comparisonTags.emplace_back(tag ^ 0x01); } - for (auto _ : state) + for ([[maybe_unused]] auto _ : state) { // Test to see if any of our tags match. // All of comparison tags should get compared against all of the added tags. From 8acda7d04de1515debf6a638aad6cead3fc20d4e Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Mon, 14 Feb 2022 16:23:27 -0800 Subject: [PATCH 36/42] Prefer CMake's built-in `-fPIC` and `-fpie` support CMake has a built-in property, `POSITION_INDEPENDENT_CODE`, that determines if code will be built with `-fPIC`. This property is `True` by default for `SHARED` and `MODULE` library targets and `False` otherwise. Previously, we were always passing the `-fPIC` flag manually. With this change, we set the appropriate CMake variable that will enable the property for all compile jobs. Furthermore, with CMake policy CMP0083 set to "new" (which happens by default when the `cmake_minimum_required` version is >=3.14), CMake has built-in support for passing the `-fpie` flag when building executables. It uses the same property, `POSITION_INDEPENDENT_CODE`, so setting this property (and enabling it with the CMake `CheckPIESupported` module) allows us to use CMake's built-in support for these flags. Signed-off-by: Chris Burel --- cmake/Platform/Common/Clang/Configurations_clang.cmake | 2 -- cmake/Platform/Common/Configurations_common.cmake | 5 +++++ cmake/Platform/Linux/Configurations_linux.cmake | 2 -- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Common/Clang/Configurations_clang.cmake b/cmake/Platform/Common/Clang/Configurations_clang.cmake index fee81f7132..88789ad0d2 100644 --- a/cmake/Platform/Common/Clang/Configurations_clang.cmake +++ b/cmake/Platform/Common/Clang/Configurations_clang.cmake @@ -20,8 +20,6 @@ ly_append_configurations_options( -Wall -Werror - -fpie # Position-Independent Executables - ################### # Disabled warnings (please do not disable any others without first consulting sig-build) ################### diff --git a/cmake/Platform/Common/Configurations_common.cmake b/cmake/Platform/Common/Configurations_common.cmake index d16dfa3eea..c2ba5477e7 100644 --- a/cmake/Platform/Common/Configurations_common.cmake +++ b/cmake/Platform/Common/Configurations_common.cmake @@ -62,3 +62,8 @@ if(CMAKE_GENERATOR MATCHES "Ninja") ly_set(CMAKE_JOB_POOL_LINK link_job_pool) endif() endif() + +set(CMAKE_POSITION_INDEPENDENT_CODE True) + +include(CheckPIESupported) +check_pie_supported() diff --git a/cmake/Platform/Linux/Configurations_linux.cmake b/cmake/Platform/Linux/Configurations_linux.cmake index 3c3ea5bf62..37ef2f8fc3 100644 --- a/cmake/Platform/Linux/Configurations_linux.cmake +++ b/cmake/Platform/Linux/Configurations_linux.cmake @@ -16,7 +16,6 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") __linux__ LINUX64 COMPILATION - -fPIC -msse4.1 LINK_NON_STATIC -Wl,-undefined,error @@ -47,7 +46,6 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") __linux__ LINUX64 COMPILATION - -fPIC -msse4.1 LINK_NON_STATIC ${LY_GCC_GCOV_LFLAGS} From c89376e9c3b501bd02fff2485f6450c4a3873c3e Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Mon, 14 Feb 2022 16:24:49 -0800 Subject: [PATCH 37/42] The flag is `--no-undefined`, not `-Wl,-undefined,error` Signed-off-by: Chris Burel --- cmake/Platform/Linux/Configurations_linux.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Linux/Configurations_linux.cmake b/cmake/Platform/Linux/Configurations_linux.cmake index 37ef2f8fc3..09a6feaf15 100644 --- a/cmake/Platform/Linux/Configurations_linux.cmake +++ b/cmake/Platform/Linux/Configurations_linux.cmake @@ -18,7 +18,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") COMPILATION -msse4.1 LINK_NON_STATIC - -Wl,-undefined,error + -Wl,--no-undefined -fpie -Wl,-z,relro,-z,now -Wl,-z,noexecstack From cf9825d37e694a114b5ff01fb40f9e56ccd99b45 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Mon, 14 Feb 2022 23:50:53 -0600 Subject: [PATCH 38/42] Mac Runtime Fix: Up the hard coded size for the HpAllocator buffer to 18KiB (#7634) * Up the hard coded size for the HpAllocator buffer to 18KiB Added a static assert in the HphaSchema.cpp file to validate that the HpAllocator aligned storage buffer is at least the size of the HpAllocator class. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed comment blocks with username from HphaSchema.h Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp | 2 +- Code/Framework/AzCore/AzCore/Memory/HphaSchema.h | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp index fc900ca2f4..1b5351cd79 100644 --- a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.cpp @@ -2440,7 +2440,7 @@ namespace AZ m_capacity = desc.m_capacity; } - AZ_Assert(sizeof(HpAllocator) <= sizeof(m_hpAllocatorBuffer), "Increase the m_hpAllocatorBuffer, we need %d bytes but we have %d bytes!", sizeof(HpAllocator), sizeof(m_hpAllocatorBuffer)); + static_assert(sizeof(HpAllocator) <= sizeof(m_hpAllocatorBuffer), "Increase the m_hpAllocatorBuffer, it needs to be at least the sizeof(HpAllocator)"); m_allocator = new (&m_hpAllocatorBuffer) HpAllocator(m_desc); } diff --git a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h index 27dbd321d2..fd746e4602 100644 --- a/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h +++ b/Code/Framework/AzCore/AzCore/Memory/HphaSchema.h @@ -73,18 +73,20 @@ namespace AZ void GarbageCollect() override; private: - // [LY-84974][sconel@][2018-08-10] SliceStrike integration up to CL 671758 // this must be at least the max size of HpAllocator (defined in the cpp) + any platform compiler padding - static const int hpAllocatorStructureSize = 16584; - // [LY][sconel@] end + // A static assert inside of HphaSchema.cpp validates that this is the case + // as of commit https://github.com/o3de/o3de/commit/92cd457c256e1ec91eeabe04b56d1d4c61f8b1af + // When MULTITHREADED and USE_MUTEX_PER_BUCKET is defined + // the largest sizeof for HpAllocator is 16640 on MacOS + // On Windows the sizeof HpAllocator is 8384 + // Up this value to 18 KiB to be safe + static constexpr size_t hpAllocatorStructureSize = 18 * 1024; Descriptor m_desc; int m_pad; // pad the Descriptor to avoid C4355 size_type m_capacity; ///< Capacity in bytes. HpAllocator* m_allocator; - // [LY-84974][sconel@][2018-08-10] SliceStrike integration up to CL 671758 - AZStd::aligned_storage::type m_hpAllocatorBuffer; ///< Memory buffer for HpAllocator - // [LY][sconel@] end + AZStd::aligned_storage_t m_hpAllocatorBuffer; ///< Memory buffer for HpAllocator bool m_ownMemoryBlock; }; } // namespace AZ From 1c72d799f1f8c736c638007d4d49e4592320d833 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Tue, 15 Feb 2022 10:04:40 -0800 Subject: [PATCH 39/42] Prefabs UI | Refactor PrefabIntegrationManager into a separate class for save/load dialog management. (#7630) * Split up the save/load handling functions from PrefabIntegrationManager to improve maintainability. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Turn WarnUserOfError into a widely available utility function. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Consolidate the definitions for AzToolsFramework Entity classes (List, IdList, IdSet) to avoid multiple redefinitions across the module. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fix usage of EntityIdList I missed in the tests. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fix EntityList def in SliceConverter Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- .../AzToolsFramework/API/EditorEntityAPI.h | 5 +- .../API/EntityCompositionNotificationBus.h | 9 +- .../API/ToolsApplicationAPI.h | 27 +- .../Entity/EditorEntityTransformBus.h | 4 +- .../AzToolsFramework/Entity/EntityTypes.h | 20 + .../PrefabEditorEntityOwnershipService.h | 2 +- .../SliceEditorEntityOwnershipService.h | 2 +- .../SliceEditorEntityOwnershipServiceBus.h | 6 +- .../FocusMode/FocusModeInterface.h | 6 +- .../Prefab/Instance/Instance.h | 2 +- .../Instance/InstanceEntityScrubber.cpp | 2 +- .../Prefab/Instance/InstanceEntityScrubber.h | 7 +- .../Instance/InstanceUpdateExecutor.cpp | 2 +- .../Prefab/PrefabDomUtils.cpp | 2 +- .../AzToolsFramework/Prefab/PrefabDomUtils.h | 2 +- .../Prefab/PrefabPublicHandler.h | 3 +- .../Prefab/PrefabPublicInterface.h | 4 +- .../Prefab/PrefabPublicRequestBus.h | 5 +- .../Prefab/PrefabSystemComponent.cpp | 2 +- .../Prefab/PrefabSystemComponent.h | 3 +- .../Prefab/Spawnable/EditorInfoRemover.h | 2 +- .../UI/Prefab/PrefabIntegrationManager.cpp | 813 ++---------------- .../UI/Prefab/PrefabIntegrationManager.h | 64 +- .../UI/Prefab/PrefabSaveLoadHandler.cpp | 722 ++++++++++++++++ .../UI/Prefab/PrefabSaveLoadHandler.h | 101 +++ .../UI/UICore/WidgetHelpers.h | 12 +- .../EditorTransformComponentSelection.h | 3 +- .../aztoolsframework_files.cmake | 3 + .../Tests/Prefab/PrefabAssetFixupTests.cpp | 2 +- .../SerializeContextTools/SliceConverter.cpp | 2 +- .../PrefabBuilder/PrefabBuilderComponent.cpp | 2 +- 31 files changed, 990 insertions(+), 851 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EntityTypes.h create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.cpp create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.h diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorEntityAPI.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorEntityAPI.h index 3b5e5c9dc3..9ab732938c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorEntityAPI.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorEntityAPI.h @@ -8,14 +8,13 @@ #pragma once -#include #include #include +#include + namespace AzToolsFramework { - using EntityIdList = AZStd::vector; - /*! * EditorEntityAPI * Handles basic Entity operations diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityCompositionNotificationBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityCompositionNotificationBus.h index f44ccb2806..420f66e54d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityCompositionNotificationBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityCompositionNotificationBus.h @@ -8,20 +8,19 @@ #pragma once #include -#include -#include #include #include +#include +#include + +#include namespace AzToolsFramework { - using EntityIdList = AZStd::vector; - class EntityCompositionNotifications : public AZ::EBusTraits { public: - /*! * Notification that the specified entities are about to have their composition changed due to user interaction in the editor * diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h index bca68a6c0a..f84ff5f312 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/ToolsApplicationAPI.h @@ -8,40 +8,40 @@ #pragma once #include +#include +#include #include #include #include #include -#include -#include -#include +#include #include #include -#include -#include -#include #include +#include +#include +#include + namespace AZ { class Entity; class Vector2; - class Entity; -} +} // namespace AZ -class QMenu; -class QWidget; +struct IEditor; class QApplication; class QDockWidget; class QMainWindow; -struct IEditor; +class QMenu; +class QWidget; namespace AzToolsFramework { struct ViewPaneOptions; - class PreemptiveUndoCache; class EntityPropertyEditor; + class PreemptiveUndoCache; namespace UndoSystem { @@ -54,10 +54,7 @@ namespace AzToolsFramework class AssetSelectionModel; } - using EntityIdList = AZStd::vector; - using EntityList = AZStd::vector; using ClassDataList = AZStd::vector; - using EntityIdSet = AZStd::unordered_set; //! Return true to accept this type of component. using ComponentFilter = AZStd::function; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h index 17739b5098..78ebbb039f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h @@ -10,10 +10,10 @@ #include +#include + namespace AzToolsFramework { - using EntityIdList = AZStd::vector; - //! Notifications about entity transform changes from the editor. class EditorTransformChangeNotifications : public AZ::EBusTraits { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EntityTypes.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EntityTypes.h new file mode 100644 index 0000000000..826fe4417e --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EntityTypes.h @@ -0,0 +1,20 @@ +/* + * 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 +#include + +namespace AzToolsFramework +{ + using EntityIdList = AZStd::vector; + using EntityIdSet = AZStd::unordered_set; + using EntityList = AZStd::vector; + +} // namespace AZ diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h index 2d3db0ea72..8506d32d5b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -97,7 +98,6 @@ namespace AzToolsFramework , private AzFramework::SliceEntityRequestBus::MultiHandler { public: - using EntityList = AzFramework::EntityList; using OnEntitiesAddedCallback = AzFramework::OnEntitiesAddedCallback; using OnEntitiesRemovedCallback = AzFramework::OnEntitiesRemovedCallback; using ValidateEntitiesCallback = AzFramework::ValidateEntitiesCallback; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipService.h index 1399b46066..4b39a0b263 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipService.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipService.h @@ -9,13 +9,13 @@ #pragma once #include +#include #include #include namespace AzToolsFramework { - using EntityIdSet = AZStd::unordered_set; using EntityIdToEntityIdMap = AZStd::unordered_map; class SliceEditorEntityOwnershipService diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h index 4d7ea86b49..38f81ce6dc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h @@ -8,10 +8,11 @@ #pragma once -#include #include +#include #include #include +#include namespace AZ { @@ -20,9 +21,6 @@ namespace AZ namespace AzToolsFramework { - using EntityIdList = AZStd::vector; - using EntityList = AZStd::vector; - /** * Indicates how an entity was removed from its slice instance, so the said entity can be restored properly. */ diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeInterface.h index 74d207af64..2a565830bd 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/FocusMode/FocusModeInterface.h @@ -8,17 +8,17 @@ #pragma once +#include #include #include -#include #include #include +#include + namespace AzToolsFramework { - using EntityIdList = AZStd::vector; - //! FocusModeInterface //! Interface to handle the Editor Focus Mode. class FocusModeInterface diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h index ebc75dc5cf..64c7cb3d2a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace AZ @@ -62,7 +63,6 @@ namespace AzToolsFramework using AliasToInstanceMap = AZStd::unordered_map>; using AliasToEntityMap = AZStd::unordered_map>; - using EntityList = AZStd::vector; Instance(); explicit Instance(AZStd::unique_ptr containerEntity); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.cpp index ca0bb829ca..e62fc710fc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.cpp @@ -12,7 +12,7 @@ namespace AzToolsFramework { namespace Prefab { - InstanceEntityScrubber::InstanceEntityScrubber(Instance::EntityList& entities) + InstanceEntityScrubber::InstanceEntityScrubber(EntityList& entities) : m_entities(entities) {} diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.h index 394261e902..4124811795 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceEntityScrubber.h @@ -10,6 +10,7 @@ #include #include +#include #include namespace AZ @@ -19,8 +20,6 @@ namespace AZ namespace AzToolsFramework { - using EntityList = AZStd::vector; - namespace Prefab { //! Collects the entities added during deserialization @@ -29,12 +28,12 @@ namespace AzToolsFramework public: AZ_TYPE_INFO(InstanceEntityScrubber, "{0BC12562-C240-48AD-89C6-EDF572C9B485}"); - explicit InstanceEntityScrubber(Instance::EntityList& entities); + explicit InstanceEntityScrubber(EntityList& entities); void AddEntitiesToScrub(const EntityList& entities); private: - Instance::EntityList& m_entities; + EntityList& m_entities; }; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp index ea1af5cccb..336ff32498 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp @@ -154,7 +154,7 @@ namespace AzToolsFramework continue; } - Instance::EntityList newEntities; + EntityList newEntities; // Climb up to the root of the instance hierarchy from this instance InstanceOptionalConstReference rootInstance = *instanceToUpdate; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index d1d3491156..4ca1979d81 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -284,7 +284,7 @@ namespace AzToolsFramework } bool LoadInstanceFromPrefabDom( - Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadFlags flags) + Instance& instance, EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadFlags flags) { // When entities are rebuilt they are first destroyed. As a result any assets they were exclusively holding on to will // be released and reloaded once the entities are built up again. By suspending asset release temporarily the asset reload diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index d2234f423b..fe58416788 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -133,7 +133,7 @@ namespace AzToolsFramework * @return bool on whether the operation succeeded. */ bool LoadInstanceFromPrefabDom( - Instance& instance, Instance::EntityList& newlyAddedEntities, const PrefabDom& prefabDom, + Instance& instance, EntityList& newlyAddedEntities, const PrefabDom& prefabDom, LoadFlags flags = LoadFlags::None); inline PrefabDomPath GetPrefabDomInstancePath(const char* instanceName) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index a1a7ac9844..4b6a6dd039 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -22,8 +23,6 @@ class QString; namespace AzToolsFramework { - using EntityList = AZStd::vector; - namespace Prefab { class Instance; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h index 2eb0bfa8e6..bab6da0f3f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicInterface.h @@ -13,10 +13,10 @@ #include #include +#include + namespace AzToolsFramework { - using EntityIdList = AZStd::vector; - namespace UndoSystem { class URSequencePoint; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestBus.h index cf7665bdd7..779d5af9c6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicRequestBus.h @@ -9,7 +9,6 @@ #pragma once #include -#include #include #include #include @@ -18,10 +17,10 @@ #include #include +#include + namespace AzToolsFramework { - using EntityIdList = AZStd::vector; - namespace Prefab { using CreatePrefabResult = AZ::Outcome; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 3234aa8b2d..8b246161b2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -319,7 +319,7 @@ namespace AzToolsFramework } auto newInstance = AZStd::make_unique(parent); - Instance::EntityList newEntities; + EntityList newEntities; if (!PrefabDomUtils::LoadInstanceFromPrefabDom(*newInstance, newEntities, instantiatingTemplate->get().GetPrefabDom())) { AZ_Error("Prefab", false, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index b547e9bdd2..e52da2127a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -36,8 +37,6 @@ namespace AZ namespace AzToolsFramework { - using EntityList = AZStd::vector; - namespace Prefab { using InstanceList = AZStd::vector; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h index dbad58d2f5..b1bc7131b5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -50,7 +51,6 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils static void Reflect(AZ::ReflectContext* context); protected: - using EntityList = AZStd::vector; static void GetEntitiesFromInstance(AzToolsFramework::Prefab::Instance& instance, EntityList& hierarchyEntities); static bool ReadComponentAttribute( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index dfa8ad14c9..6e8bad0217 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -8,21 +8,14 @@ #include +#include +#include #include #include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include #include #include #include @@ -32,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -39,27 +33,11 @@ #include #include -#include -#include -#include -#include - #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include -#include #include -#include -#include namespace AzToolsFramework { @@ -72,31 +50,6 @@ namespace AzToolsFramework PrefabFocusPublicInterface* PrefabIntegrationManager::s_prefabFocusPublicInterface = nullptr; PrefabLoaderInterface* PrefabIntegrationManager::s_prefabLoaderInterface = nullptr; PrefabPublicInterface* PrefabIntegrationManager::s_prefabPublicInterface = nullptr; - PrefabSystemComponentInterface* PrefabIntegrationManager::s_prefabSystemComponentInterface = nullptr; - - const AZStd::string PrefabIntegrationManager::s_prefabFileExtension = ".prefab"; - - static const char* const ClosePrefabDialog = "ClosePrefabDialog"; - static const char* const FooterSeparatorLine = "FooterSeparatorLine"; - static const char* const PrefabSavedMessageFrame = "PrefabSavedMessageFrame"; - static const char* const PrefabSavePreferenceHint = "PrefabSavePreferenceHint"; - static const char* const PrefabSaveWarningFrame = "PrefabSaveWarningFrame"; - static const char* const SaveDependentPrefabsCard = "SaveDependentPrefabsCard"; - static const char* const SavePrefabDialog = "SavePrefabDialog"; - static const char* const UnsavedPrefabFileName = "UnsavedPrefabFileName"; - - - void PrefabUserSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("m_saveLocation", &PrefabUserSettings::m_saveLocation) - ->Field("m_autoNumber", &PrefabUserSettings::m_autoNumber); - } - } PrefabIntegrationManager::PrefabIntegrationManager() { @@ -128,13 +81,6 @@ namespace AzToolsFramework return; } - s_prefabSystemComponentInterface = AZ::Interface::Get(); - if (s_prefabSystemComponentInterface == nullptr) - { - AZ_Assert(false, "Prefab - could not get PrefabSystemComponentInterface on PrefabIntegrationManager construction."); - return; - } - s_prefabFocusPublicInterface = AZ::Interface::Get(); if (s_prefabFocusPublicInterface == nullptr) { @@ -143,7 +89,9 @@ namespace AzToolsFramework } m_readOnlyEntityPublicInterface = AZ::Interface::Get(); - AZ_Assert(m_readOnlyEntityPublicInterface, "Prefab - could not get ReadOnlyEntityPublicInterface on PrefabIntegrationManager construction."); + AZ_Assert( + m_readOnlyEntityPublicInterface, + "Prefab - could not get ReadOnlyEntityPublicInterface on PrefabIntegrationManager construction."); // Get EditorEntityContextId EditorEntityContextRequestBus::BroadcastResult(s_editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId); @@ -156,7 +104,6 @@ namespace AzToolsFramework EditorEventsBus::Handler::BusConnect(); PrefabInstanceContainerNotificationBus::Handler::BusConnect(); AZ::Interface::Register(this); - AssetBrowser::AssetBrowserSourceDropBus::Handler::BusConnect(s_prefabFileExtension); EditorEntityContextNotificationBus::Handler::BusConnect(); InitializeShortcuts(); @@ -167,7 +114,6 @@ namespace AzToolsFramework UninitializeShortcuts(); EditorEntityContextNotificationBus::Handler::BusDisconnect(); - AssetBrowser::AssetBrowserSourceDropBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); PrefabInstanceContainerNotificationBus::Handler::BusDisconnect(); EditorEventsBus::Handler::BusDisconnect(); @@ -257,7 +203,8 @@ namespace AzToolsFramework return "Prefabs"; } - void PrefabIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, [[maybe_unused]] const AZ::Vector2& point, [[maybe_unused]] int flags) + void PrefabIntegrationManager::PopulateEditorGlobalContextMenu( + QMenu* menu, [[maybe_unused]] const AZ::Vector2& point, [[maybe_unused]] int flags) { AzToolsFramework::EntityIdList selectedEntities; AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult( @@ -330,9 +277,12 @@ namespace AzToolsFramework QAction* createAction = menu->addAction(QObject::tr("Create Prefab...")); createAction->setToolTip(QObject::tr("Creates a prefab out of the currently selected entities.")); - QObject::connect(createAction, &QAction::triggered, createAction, [selectedEntities] { - ContextMenu_CreatePrefab(selectedEntities); - }); + QObject::connect( + createAction, &QAction::triggered, createAction, + [selectedEntities] + { + ContextMenu_CreatePrefab(selectedEntities); + }); itemWasShown = true; } @@ -348,7 +298,11 @@ namespace AzToolsFramework instantiateAction->setToolTip(QObject::tr("Instantiates a prefab file in the scene.")); QObject::connect( - instantiateAction, &QAction::triggered, instantiateAction, [] { ContextMenu_InstantiatePrefab(); }); + instantiateAction, &QAction::triggered, instantiateAction, + [] + { + ContextMenu_InstantiatePrefab(); + }); // Instantiate Procedural Prefab if (AZ::Prefab::ProceduralPrefabAsset::UseProceduralPrefabs()) @@ -357,7 +311,11 @@ namespace AzToolsFramework action->setToolTip(QObject::tr("Instantiates a procedural prefab file in a prefab.")); QObject::connect( - action, &QAction::triggered, action, [] { ContextMenu_InstantiateProceduralPrefab(); }); + action, &QAction::triggered, action, + [] + { + ContextMenu_InstantiateProceduralPrefab(); + }); } itemWasShown = true; @@ -433,9 +391,12 @@ namespace AzToolsFramework QAction* saveAction = menu->addAction(QObject::tr("Save Prefab to file")); saveAction->setToolTip(QObject::tr("Save the changes to the prefab to disk.")); - QObject::connect(saveAction, &QAction::triggered, saveAction, [selectedEntity] { - ContextMenu_SavePrefab(selectedEntity); - }); + QObject::connect( + saveAction, &QAction::triggered, saveAction, + [selectedEntity] + { + ContextMenu_SavePrefab(selectedEntity); + }); } itemWasShown = true; @@ -454,7 +415,12 @@ namespace AzToolsFramework !readOnlyEntityInSelection) { QAction* deleteAction = menu->addAction(QObject::tr("Delete")); - QObject::connect(deleteAction, &QAction::triggered, deleteAction, [] { ContextMenu_DeleteSelected(); }); + QObject::connect( + deleteAction, &QAction::triggered, deleteAction, + [] + { + ContextMenu_DeleteSelected(); + }); } // Detach Prefab @@ -477,16 +443,6 @@ namespace AzToolsFramework s_prefabFocusPublicInterface->FocusOnOwningPrefab(AZ::EntityId()); } - void PrefabIntegrationManager::HandleSourceFileType(AZStd::string_view sourceFilePath, AZ::EntityId parentId, AZ::Vector3 position) const - { - auto instantiatePrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(sourceFilePath, parentId, position); - - if (!instantiatePrefabOutcome.IsSuccess()) - { - WarnUserOfError("Prefab Instantiation Error", instantiatePrefabOutcome.GetError()); - } - } - void PrefabIntegrationManager::OnStartPlayInEditorBegin() { // Focus on the root prefab (AZ::EntityId() will default to it) @@ -501,8 +457,7 @@ namespace AzToolsFramework [&]() { s_containerEntityInterface->RefreshAllContainerEntities(s_editorEntityContextId); - } - ); + }); } void PrefabIntegrationManager::ContextMenu_CreatePrefab(AzToolsFramework::EntityIdList selectedEntities) @@ -553,7 +508,8 @@ namespace AzToolsFramework if (hasExternalReferences) { bool useAllReferencedEntities = false; - bool continueCreation = QueryAndPruneMissingExternalReferences(entitiesToIncludeInAsset, allReferencedEntities, useAllReferencedEntities); + bool continueCreation = + QueryAndPruneMissingExternalReferences(entitiesToIncludeInAsset, allReferencedEntities, useAllReferencedEntities); if (!continueCreation) { // User canceled the operation @@ -576,17 +532,19 @@ namespace AzToolsFramework { AZ::EntityId commonRoot; bool hasCommonRoot = false; - AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(hasCommonRoot, - &AzToolsFramework::ToolsApplicationRequests::FindCommonRoot, entitiesToIncludeInAsset, commonRoot, &prefabRootEntities); - if (hasCommonRoot && commonRoot.IsValid() && entitiesToIncludeInAsset.find(commonRoot) != entitiesToIncludeInAsset.end()) + AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult( + hasCommonRoot, &AzToolsFramework::ToolsApplicationRequests::FindCommonRoot, entitiesToIncludeInAsset, commonRoot, + &prefabRootEntities); + if (hasCommonRoot && commonRoot.IsValid() && + entitiesToIncludeInAsset.find(commonRoot) != entitiesToIncludeInAsset.end()) { prefabRootEntities.insert(prefabRootEntities.begin(), commonRoot); } } - GenerateSuggestedFilenameFromEntities(prefabRootEntities, suggestedName); + PrefabSaveHandler::GenerateSuggestedFilenameFromEntities(prefabRootEntities, suggestedName); - if (!QueryUserForPrefabSaveLocation( + if (!PrefabSaveHandler::QueryUserForPrefabSaveLocation( suggestedName, targetDirectory, AZ_CRC("PrefabUserSettings"), activeWindow, prefabName, prefabFilePath)) { // User canceled prefab creation, or error prevented continuation. @@ -598,14 +556,14 @@ namespace AzToolsFramework if (!createPrefabOutcome.IsSuccess()) { - WarnUserOfError("Prefab Creation Error", createPrefabOutcome.GetError()); + WarningDialog("Prefab Creation Error", createPrefabOutcome.GetError()); } } void PrefabIntegrationManager::ContextMenu_InstantiatePrefab() { AZStd::string prefabFilePath; - bool hasUserSelectedValidSourceFile = QueryUserForPrefabFilePath(prefabFilePath); + bool hasUserSelectedValidSourceFile = PrefabSaveHandler::QueryUserForPrefabFilePath(prefabFilePath); if (hasUserSelectedValidSourceFile) { @@ -629,7 +587,7 @@ namespace AzToolsFramework auto createPrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(prefabFilePath, parentId, position); if (!createPrefabOutcome.IsSuccess()) { - WarnUserOfError("Prefab Instantiation Error",createPrefabOutcome.GetError()); + WarningDialog("Prefab Instantiation Error", createPrefabOutcome.GetError()); } } } @@ -637,7 +595,7 @@ namespace AzToolsFramework void PrefabIntegrationManager::ContextMenu_InstantiateProceduralPrefab() { AZStd::string prefabAssetPath; - bool hasUserForProceduralPrefabAsset = QueryUserForProceduralPrefabAsset(prefabAssetPath); + bool hasUserForProceduralPrefabAsset = PrefabSaveHandler::QueryUserForProceduralPrefabAsset(prefabAssetPath); if (hasUserForProceduralPrefabAsset) { @@ -659,7 +617,7 @@ namespace AzToolsFramework auto createPrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(prefabAssetPath, parentId, position); if (!createPrefabOutcome.IsSuccess()) { - WarnUserOfError("Procedural Prefab Instantiation Error", createPrefabOutcome.GetError()); + WarningDialog("Procedural Prefab Instantiation Error", createPrefabOutcome.GetError()); } } } @@ -682,7 +640,7 @@ namespace AzToolsFramework if (!savePrefabOutcome.IsSuccess()) { - WarnUserOfError("Prefab Save Error", savePrefabOutcome.GetError()); + WarningDialog("Prefab Save Error", savePrefabOutcome.GetError()); } } @@ -695,401 +653,22 @@ namespace AzToolsFramework s_prefabPublicInterface->DeleteEntitiesAndAllDescendantsInInstance(selectedEntityIds); if (!deleteSelectedResult.IsSuccess()) { - WarnUserOfError("Delete selected entities error", deleteSelectedResult.GetError()); + WarningDialog("Delete selected entities error", deleteSelectedResult.GetError()); } } void PrefabIntegrationManager::ContextMenu_DetachPrefab(AZ::EntityId containerEntity) { - PrefabOperationResult detachPrefabResult = - s_prefabPublicInterface->DetachPrefab(containerEntity); + PrefabOperationResult detachPrefabResult = s_prefabPublicInterface->DetachPrefab(containerEntity); if (!detachPrefabResult.IsSuccess()) { - WarnUserOfError("Detach Prefab error", detachPrefabResult.GetError()); - } - } - - void PrefabIntegrationManager::GenerateSuggestedFilenameFromEntities(const EntityIdList& entityIds, AZStd::string& outName) - { - AZ_PROFILE_FUNCTION(AzToolsFramework); - - AZStd::string suggestedName; - - for (const AZ::EntityId& entityId : entityIds) - { - if (!AppendEntityToSuggestedFilename(suggestedName, entityId)) - { - break; - } - } - - if (suggestedName.size() == 0 || AzFramework::StringFunc::Utf8::CheckNonAsciiChar(suggestedName)) - { - suggestedName = "NewPrefab"; - } - - outName = suggestedName; - } - - bool PrefabIntegrationManager::AppendEntityToSuggestedFilename(AZStd::string& filename, AZ::EntityId entityId) - { - // When naming a prefab after its entities, we stop appending additional names once we've reached this cutoff length - size_t prefabNameCutoffLength = 32; - AzToolsFramework::EntityIdSet usedNameEntities; - - if (usedNameEntities.find(entityId) == usedNameEntities.end()) - { - AZ::Entity* entity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId); - if (entity) - { - AZStd::string entityNameFiltered = entity->GetName(); - - // Convert spaces in entity names to underscores - for (size_t i = 0; i < entityNameFiltered.size(); ++i) - { - char& character = entityNameFiltered.at(i); - if (character == ' ') - { - character = '_'; - } - } - - filename.append(entityNameFiltered); - usedNameEntities.insert(entityId); - if (filename.size() > prefabNameCutoffLength) - { - return false; - } - } - } - - return true; - } - - bool PrefabIntegrationManager::QueryUserForPrefabSaveLocation( - const AZStd::string& suggestedName, - const char* initialTargetDirectory, - AZ::u32 prefabUserSettingsId, - QWidget* activeWindow, - AZStd::string& outPrefabName, - AZStd::string& outPrefabFilePath - ) - { - AZStd::string saveAsInitialSuggestedDirectory; - if (!GetPrefabSaveLocation(saveAsInitialSuggestedDirectory, prefabUserSettingsId)) - { - saveAsInitialSuggestedDirectory = initialTargetDirectory; - } - - AZStd::string saveAsInitialSuggestedFullPath; - GenerateSuggestedPrefabPath(suggestedName, saveAsInitialSuggestedDirectory, saveAsInitialSuggestedFullPath); - - QString saveAs; - AZStd::string targetPath; - QFileInfo prefabSaveFileInfo; - QString prefabName; - while (true) - { - { - AZ_PROFILE_FUNCTION(AzToolsFramework); - saveAs = QFileDialog::getSaveFileName(nullptr, QString("Save As..."), saveAsInitialSuggestedFullPath.c_str(), QString("Prefabs (*.prefab)")); - } - - prefabSaveFileInfo = saveAs; - prefabName = prefabSaveFileInfo.baseName(); - if (saveAs.isEmpty()) - { - return false; - } - - targetPath = saveAs.toUtf8().constData(); - if (AzFramework::StringFunc::Utf8::CheckNonAsciiChar(targetPath)) - { - WarnUserOfError( - "Prefab Creation Failed.", - "Unicode file name is not supported. \r\n" - "Please use ASCII characters to name your prefab." - ); - return false; - } - - PrefabSaveResult saveResult = IsPrefabPathValidForAssets(activeWindow, saveAs, saveAsInitialSuggestedFullPath); - if (saveResult == PrefabSaveResult::Cancel) - { - // The error was already reported if this failed. - return false; - } - else if (saveResult == PrefabSaveResult::Continue) - { - // The prefab save name is valid, continue with the save attempt. - break; - } + WarningDialog("Detach Prefab error", detachPrefabResult.GetError()); } - - // If the prefab already exists, notify the user and bail - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - if (fileIO && fileIO->Exists(targetPath.c_str())) - { - const AZStd::string message = AZStd::string::format( - "You are attempting to overwrite an existing prefab: \"%s\".\r\n\r\n" - "This will damage instances or cascades of this prefab. \r\n\r\n" - "Instead, either push entities/fields to the prefab, or save to a different location.", - targetPath.c_str()); - - WarnUserOfError("Prefab Already Exists", message); - return false; - } - - // We prevent users from creating a new prefab with the same relative path that's already - // been used by an existing prefab in other places (e.g. Gems) because the AssetProcessor - // generates asset ids based on relative paths. This is unnecessary once AssetProcessor - // starts to generate UUID to every asset regardless of paths. - { - AZStd::string prefabRelativeName; - bool relativePathFound; - AssetSystemRequestBus::BroadcastResult(relativePathFound, &AssetSystemRequestBus::Events::GetRelativeProductPathFromFullSourceOrProductPath, targetPath, prefabRelativeName); - - AZ::Data::AssetId prefabAssetId; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(prefabAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, prefabRelativeName.c_str(), AZ::Data::s_invalidAssetType, false); - if (prefabAssetId.IsValid()) - { - const AZStd::string message = AZStd::string::format( - "A prefab with the relative path \"%s\" already exists in the Asset Database. \r\n\r\n" - "Overriding it will damage instances or cascades of this prefab. \r\n\r\n" - "Instead, either push entities/fields to the prefab, or save to a different location.", - prefabRelativeName.c_str()); - - WarnUserOfError("Prefab Path Error", message); - return false; - } - } - - AZStd::string saveDir(prefabSaveFileInfo.absoluteDir().absolutePath().toUtf8().constData()); - SetPrefabSaveLocation(saveDir, prefabUserSettingsId); - - outPrefabName = prefabName.toUtf8().constData(); - outPrefabFilePath = targetPath.c_str(); - - return true; } - bool PrefabIntegrationManager::QueryUserForPrefabFilePath(AZStd::string& outPrefabFilePath) - { - AssetSelectionModel selection; - - // Note, stringfilter will match every source file CONTAINING ".prefab". - // If this causes issues, we will need to create a new filter class for regex matching. - // We'll need to check if the file contents are actually a prefab later in the flow anyways, - // so this should not be an issue. - StringFilter* stringFilter = new StringFilter(); - stringFilter->SetName("Prefab"); - stringFilter->SetFilterString(".prefab"); - stringFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down); - auto stringFilterPtr = FilterConstType(stringFilter); - - EntryTypeFilter* sourceFilter = new EntryTypeFilter(); - sourceFilter->SetName("Source"); - sourceFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Source); - sourceFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down); - auto sourceFilterPtr = FilterConstType(sourceFilter); - - CompositeFilter* compositeFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND); - compositeFilter->SetName("Prefab"); - compositeFilter->AddFilter(sourceFilterPtr); - compositeFilter->AddFilter(stringFilterPtr); - auto compositeFilterPtr = FilterConstType(compositeFilter); - - selection.SetDisplayFilter(compositeFilterPtr); - selection.SetSelectionFilter(compositeFilterPtr); - - AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, AzToolsFramework::GetActiveWindow()); - - if (!selection.IsValid()) - { - // User closed the dialog without selecting, just return. - return false; - } - - auto source = azrtti_cast(selection.GetResult()); - - if (source == nullptr) - { - AZ_Assert(false, "Prefab - Incorrect entry type selected during prefab instantiation. Expected source."); - return false; - } - - outPrefabFilePath = source->GetFullPath(); - return true; - } - - bool PrefabIntegrationManager::QueryUserForProceduralPrefabAsset(AZStd::string& outPrefabAssetPath) - { - using namespace AzToolsFramework; - auto selection = AssetBrowser::AssetSelectionModel::AssetTypeSelection(azrtti_typeid()); - EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection); - - if (!selection.IsValid()) - { - return false; - } - - auto product = azrtti_cast(selection.GetResult()); - if (product == nullptr) - { - return false; - } - outPrefabAssetPath = product->GetRelativePath(); - return true; - } - - void PrefabIntegrationManager::WarnUserOfError(AZStd::string_view title, AZStd::string_view message) - { - QWidget* activeWindow = QApplication::activeWindow(); - - QMessageBox::warning( - activeWindow, - QString(title.data()), - QString(message.data()), - QMessageBox::Ok, - QMessageBox::Ok - ); - } - - PrefabIntegrationManager::PrefabSaveResult PrefabIntegrationManager::IsPrefabPathValidForAssets(QWidget* activeWindow, - QString prefabPath, AZStd::string& retrySavePath) - { - bool assetSetFoldersRetrieved = false; - AZStd::vector assetSafeFolders; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult( - assetSetFoldersRetrieved, - &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetSafeFolders, - assetSafeFolders); - - if (!assetSetFoldersRetrieved) - { - // If the asset safe list couldn't be retrieved, don't block the user but warn them. - AZ_Warning("Prefab", false, "Unable to verify that the prefab file to create is in a valid path."); - } - else - { - AZ::IO::FixedMaxPath lexicallyNormalPath = AZ::IO::PathView(prefabPath.toUtf8().constData()).LexicallyNormal(); - - bool isPathSafeForAssets = false; - for (const AZStd::string& assetSafeFolder : assetSafeFolders) - { - AZ::IO::PathView assetSafeFolderView(assetSafeFolder); - // Check if the prefabPath is relative to the safe asset directory. - // The Path classes are being used to make this check case insensitive. - if (lexicallyNormalPath.IsRelativeTo(assetSafeFolderView)) - { - isPathSafeForAssets = true; - break; - } - } - - if (!isPathSafeForAssets) - { - // Put an error in the console, so the log files have info about this error, or the user can look up the error after dismissing it. - AZStd::string errorMessage = "You can only save prefabs to either your game project folder or the Gems folder. Update the location and try again.\n\n" - "You can also review and update your save locations in the AssetProcessorPlatformConfig.ini file."; - AZ_Error("Prefab", false, errorMessage.c_str()); - - // Display a pop-up, the logs are easy to miss. This will make sure a user who encounters this error immediately knows their prefab save has failed. - QMessageBox msgBox(activeWindow); - msgBox.setIcon(QMessageBox::Icon::Warning); - msgBox.setTextFormat(Qt::RichText); - msgBox.setWindowTitle(QObject::tr("Invalid save location")); - msgBox.setText(QObject::tr(errorMessage.c_str())); - msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Retry); - msgBox.setDefaultButton(QMessageBox::Retry); - const int response = msgBox.exec(); - switch (response) - { - case QMessageBox::Retry: - // If the user wants to retry, they probably want to save to a valid location, - // so set the suggested save path to a known valid location. - if (assetSafeFolders.size() > 0) - { - retrySavePath = assetSafeFolders[0]; - } - return PrefabSaveResult::Retry; - case QMessageBox::Cancel: - default: - return PrefabSaveResult::Cancel; - } - } - } - // Valid prefab save location, continue with the save attempt. - return PrefabSaveResult::Continue; - } - - void PrefabIntegrationManager::GenerateSuggestedPrefabPath(const AZStd::string& prefabName, const AZStd::string& targetDirectory, AZStd::string& suggestedFullPath) - { - // Generate full suggested path from prefabName - if given NewPrefab as prefabName, - // NewPrefab_001.prefab would be tried, and if that already existed we would suggest - // the first unused number value (NewPrefab_002.prefab etc.) - AZStd::string normalizedTargetDirectory = targetDirectory; - AZ::StringFunc::Path::Normalize(normalizedTargetDirectory); - - // Convert spaces in entity names to underscores - AZStd::string prefabNameFiltered = prefabName; - AZ::StringFunc::Replace(prefabNameFiltered, ' ', '_'); - - auto settings = AZ::UserSettings::CreateFind(AZ_CRC("PrefabUserSettings"), AZ::UserSettings::CT_LOCAL); - if (settings->m_autoNumber) - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - - const AZ::u32 maxPrefabNumber = 1000; - for (AZ::u32 prefabNumber = 1; prefabNumber < maxPrefabNumber; ++prefabNumber) - { - AZStd::string possiblePath; - AZ::StringFunc::Path::Join( - normalizedTargetDirectory.c_str(), - AZStd::string::format("%s_%3.3u%s", prefabNameFiltered.c_str(), prefabNumber, s_prefabFileExtension.c_str()).c_str(), - possiblePath - ); - - if (!fileIO || !fileIO->Exists(possiblePath.c_str())) - { - suggestedFullPath = possiblePath; - break; - } - } - } - else - { - // use the entity name as the file name regardless of it already existing, the OS will ask the user to overwrite the file in that case. - AZ::StringFunc::Path::Join( - normalizedTargetDirectory.c_str(), - AZStd::string::format("%s%s", prefabNameFiltered.c_str(), s_prefabFileExtension.c_str()).c_str(), - suggestedFullPath - ); - } - } - - void PrefabIntegrationManager::SetPrefabSaveLocation(const AZStd::string& path, AZ::u32 settingsId) - { - auto settings = AZ::UserSettings::CreateFind(settingsId, AZ::UserSettings::CT_LOCAL); - settings->m_saveLocation = path; - } - - bool PrefabIntegrationManager::GetPrefabSaveLocation(AZStd::string& path, AZ::u32 settingsId) - { - auto settings = AZ::UserSettings::Find(settingsId, AZ::UserSettings::CT_LOCAL); - if (settings) - { - path = settings->m_saveLocation; - return true; - } - - return false; - } - - void PrefabIntegrationManager::GatherAllReferencedEntitiesAndCompare(const EntityIdSet& entities, - EntityIdSet& entitiesAndReferencedEntities, bool& hasExternalReferences) + void PrefabIntegrationManager::GatherAllReferencedEntitiesAndCompare( + const EntityIdSet& entities, EntityIdSet& entitiesAndReferencedEntities, bool& hasExternalReferences) { AZ::SerializeContext* serializeContext; AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); @@ -1130,7 +709,8 @@ namespace AzToolsFramework } } - const AZ::Edit::ElementData* classEditData = classData ? classData->FindElementData(AZ::Edit::ClassElements::EditorData) : nullptr; + const AZ::Edit::ElementData* classEditData = + classData ? classData->FindElementData(AZ::Edit::ClassElements::EditorData) : nullptr; if (classEditData) { AZ::Edit::Attribute* slicePushAttribute = classEditData->FindAttribute(AZ::Edit::Attributes::SliceFlags); @@ -1146,7 +726,8 @@ namespace AzToolsFramework return sliceFlags; } - void PrefabIntegrationManager::GatherAllReferencedEntities(EntityIdSet& entitiesWithReferences, AZ::SerializeContext& serializeContext) + void PrefabIntegrationManager::GatherAllReferencedEntities( + EntityIdSet& entitiesWithReferences, AZ::SerializeContext& serializeContext) { AZ_PROFILE_FUNCTION(AzToolsFramework); @@ -1172,18 +753,20 @@ namespace AzToolsFramework { AZStd::vector parentStack; parentStack.reserve(30); - auto beginCB = [&](void* ptr, const AZ::SerializeContext::ClassData* classData, const AZ::SerializeContext::ClassElement* elementData) -> bool + auto beginCB = [&](void* ptr, const AZ::SerializeContext::ClassData* classData, + const AZ::SerializeContext::ClassElement* elementData) -> bool { parentStack.push_back(classData); - AZ::u32 sliceFlags = GetSliceFlags(elementData ? elementData->m_editData : nullptr, classData ? classData->m_editData : nullptr); + AZ::u32 sliceFlags = + GetSliceFlags(elementData ? elementData->m_editData : nullptr, classData ? classData->m_editData : nullptr); // Skip any class or element marked as don't gather references if (0 != (sliceFlags & AZ::Edit::SliceFlags::DontGatherReference)) { return false; } - + if (classData->m_typeId == AZ::SerializeTypeInfo::GetUuid()) { if (!parentStack.empty() && parentStack.back()->m_typeId == AZ::SerializeTypeInfo::GetUuid()) @@ -1192,8 +775,9 @@ namespace AzToolsFramework } else { - AZ::EntityId* entityIdPtr = (elementData->m_flags & AZ::SerializeContext::ClassElement::FLG_POINTER) ? - *reinterpret_cast(ptr) : reinterpret_cast(ptr); + AZ::EntityId* entityIdPtr = (elementData->m_flags & AZ::SerializeContext::ClassElement::FLG_POINTER) + ? *reinterpret_cast(ptr) + : reinterpret_cast(ptr); if (entityIdPtr) { const AZ::EntityId id = *entityIdPtr; @@ -1219,26 +803,15 @@ namespace AzToolsFramework }; AZ::SerializeContext::EnumerateInstanceCallContext callContext( - beginCB, - endCB, - &serializeContext, - AZ::SerializeContext::ENUM_ACCESS_FOR_READ, - nullptr - ); - - serializeContext.EnumerateInstanceConst( - &callContext, - entity, - azrtti_typeid(), - nullptr, - nullptr - ); + beginCB, endCB, &serializeContext, AZ::SerializeContext::ENUM_ACCESS_FOR_READ, nullptr); + + serializeContext.EnumerateInstanceConst(&callContext, entity, azrtti_typeid(), nullptr, nullptr); } } } - bool PrefabIntegrationManager::QueryAndPruneMissingExternalReferences(EntityIdSet& entities, EntityIdSet& selectedAndReferencedEntities, - bool& useReferencedEntities, bool defaultMoveExternalRefs) + bool PrefabIntegrationManager::QueryAndPruneMissingExternalReferences( + EntityIdSet& entities, EntityIdSet& selectedAndReferencedEntities, bool& useReferencedEntities, bool defaultMoveExternalRefs) { AZ_PROFILE_FUNCTION(AzToolsFramework); useReferencedEntities = false; @@ -1278,9 +851,9 @@ namespace AzToolsFramework AZ_PROFILE_FUNCTION(AzToolsFramework); const AZStd::string message = AZStd::string::format( - "Entity references may not be valid if the entity IDs change or if the entities do not exist when the prefab is instantiated.\r\n\r\nSelected Entities\n%s\nReferenced Entities\n%s\n", - includedEntities.c_str(), - referencedEntities.c_str()); + "Entity references may not be valid if the entity IDs change or if the entities do not exist when the prefab is " + "instantiated.\r\n\r\nSelected Entities\n%s\nReferenced Entities\n%s\n", + includedEntities.c_str(), referencedEntities.c_str()); QMessageBox msgBox(AzToolsFramework::GetActiveWindow()); msgBox.setWindowTitle("External Entity References"); @@ -1361,243 +934,21 @@ namespace AzToolsFramework } else { - WarnUserOfError("Entity Creation Error", createResult.GetError()); + WarningDialog("Entity Creation Error", createResult.GetError()); return AZ::EntityId(); } } int PrefabIntegrationManager::ExecuteClosePrefabDialog(TemplateId templateId) { - if (s_prefabSystemComponentInterface->AreDirtyTemplatesPresent(templateId)) - { - auto prefabSaveSelectionDialog = ConstructClosePrefabDialog(templateId); - - int prefabSaveSelection = prefabSaveSelectionDialog->exec(); - - if (prefabSaveSelection == QDialog::Accepted) - { - SavePrefabsInDialog(prefabSaveSelectionDialog.get()); - } - - return prefabSaveSelection; - } - - return QDialogButtonBox::DestructiveRole; + return m_prefabSaveHandler.ExecuteClosePrefabDialog(templateId); } void PrefabIntegrationManager::ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) { - auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId); - AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath(); - - if (s_prefabSystemComponentInterface->IsTemplateDirty(templateId)) - { - if (s_prefabLoaderInterface->SaveTemplate(templateId) == false) - { - AZ_Error("Prefab", false, "Template '%s' could not be saved successfully.", prefabTemplatePath.c_str()); - return; - } - } - - if (s_prefabSystemComponentInterface->AreDirtyTemplatesPresent(templateId)) - { - if (useSaveAllPrefabsPreference) - { - SaveAllPrefabsPreference saveAllPrefabsPreference = s_prefabLoaderInterface->GetSaveAllPrefabsPreference(); - - if (saveAllPrefabsPreference == SaveAllPrefabsPreference::SaveAll) - { - s_prefabSystemComponentInterface->SaveAllDirtyTemplates(templateId); - return; - } - else if (saveAllPrefabsPreference == SaveAllPrefabsPreference::SaveNone) - { - return; - } - } - - AZStd::unique_ptr savePrefabDialog = ConstructSavePrefabDialog(templateId, useSaveAllPrefabsPreference); - if (savePrefabDialog) - { - int prefabSaveSelection = savePrefabDialog->exec(); - - if (prefabSaveSelection == QDialog::Accepted) - { - SavePrefabsInDialog(savePrefabDialog.get()); - } - } - } - } - - void PrefabIntegrationManager::SavePrefabsInDialog(QDialog* unsavedPrefabsDialog) - { - QList unsavedPrefabFileLabels = unsavedPrefabsDialog->findChildren(UnsavedPrefabFileName); - if (unsavedPrefabFileLabels.size() > 0) - { - for (const QLabel* unsavedPrefabFileLabel : unsavedPrefabFileLabels) - { - AZStd::string unsavedPrefabFileName = unsavedPrefabFileLabel->property("FilePath").toString().toUtf8().data(); - AzToolsFramework::Prefab::TemplateId unsavedPrefabTemplateId = - s_prefabSystemComponentInterface->GetTemplateIdFromFilePath(unsavedPrefabFileName.data()); - [[maybe_unused]] bool isTemplateSavedSuccessfully = s_prefabLoaderInterface->SaveTemplate(unsavedPrefabTemplateId); - AZ_Error("Prefab", isTemplateSavedSuccessfully, "Prefab '%s' could not be saved successfully.", unsavedPrefabFileName.c_str()); - } - } - } - - AZStd::unique_ptr PrefabIntegrationManager::ConstructSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) - { - AZStd::unique_ptr savePrefabDialog = AZStd::make_unique(AzToolsFramework::GetActiveWindow()); - - savePrefabDialog->setWindowTitle("Unsaved files detected"); - - // Main Content section begins. - savePrefabDialog->setObjectName(SavePrefabDialog); - QBoxLayout* contentLayout = new QVBoxLayout(savePrefabDialog.get()); - - QFrame* prefabSavedMessageFrame = new QFrame(savePrefabDialog.get()); - QHBoxLayout* prefabSavedMessageLayout = new QHBoxLayout(savePrefabDialog.get()); - prefabSavedMessageFrame->setObjectName(PrefabSavedMessageFrame); - prefabSavedMessageFrame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); - - // Add a checkMark icon next to the level entities saved message. - QPixmap checkMarkIcon(QString(":/Notifications/checkmark.svg")); - QLabel* prefabSavedSuccessfullyIconContainer = new QLabel(savePrefabDialog.get()); - prefabSavedSuccessfullyIconContainer->setPixmap(checkMarkIcon); - prefabSavedSuccessfullyIconContainer->setFixedWidth(checkMarkIcon.width()); - - // Add a message that level entities are saved successfully. - - auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId); - AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath(); - QLabel* prefabSavedSuccessfullyLabel = new QLabel( - QString("Prefab '%1' has been saved. Do you want to save the below dependent prefabs too?").arg(prefabTemplatePath.c_str()), - savePrefabDialog.get()); - prefabSavedMessageLayout->addWidget(prefabSavedSuccessfullyIconContainer); - prefabSavedMessageLayout->addWidget(prefabSavedSuccessfullyLabel); - prefabSavedMessageFrame->setLayout(prefabSavedMessageLayout); - contentLayout->addWidget(prefabSavedMessageFrame); - - AZStd::unique_ptr unsavedPrefabsContainer = ConstructUnsavedPrefabsCard(templateId); - contentLayout->addWidget(unsavedPrefabsContainer.release()); - - contentLayout->addStretch(); - - // Footer section begins. - QHBoxLayout* footerLayout = new QHBoxLayout(savePrefabDialog.get()); - - if (useSaveAllPrefabsPreference) - { - QFrame* footerSeparatorLine = new QFrame(savePrefabDialog.get()); - footerSeparatorLine->setObjectName(FooterSeparatorLine); - footerSeparatorLine->setFrameShape(QFrame::HLine); - contentLayout->addWidget(footerSeparatorLine); - - QLabel* prefabSavePreferenceHint = new QLabel( - "You can prevent this window from showing in the future by updating your global save preferences.", - savePrefabDialog.get()); - prefabSavePreferenceHint->setToolTip( - "Go to 'Edit > Editor Settings > Global Preferences... > Global save preferences' to update your preference"); - prefabSavePreferenceHint->setObjectName(PrefabSavePreferenceHint); - footerLayout->addWidget(prefabSavePreferenceHint); - } - - QDialogButtonBox* prefabSaveConfirmationButtons = - new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::No, savePrefabDialog.get()); - footerLayout->addWidget(prefabSaveConfirmationButtons); - contentLayout->addLayout(footerLayout); - connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, savePrefabDialog.get(), &QDialog::accept); - connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, savePrefabDialog.get(), &QDialog::reject); - AzQtComponents::StyleManager::setStyleSheet(savePrefabDialog->parentWidget(), QStringLiteral("style:Editor.qss")); - - savePrefabDialog->setLayout(contentLayout); - return AZStd::move(savePrefabDialog); - } - - AZStd::shared_ptr PrefabIntegrationManager::ConstructClosePrefabDialog(TemplateId templateId) - { - AZStd::shared_ptr closePrefabDialog = AZStd::make_shared(AzToolsFramework::GetActiveWindow()); - closePrefabDialog->setWindowTitle("Unsaved files detected"); - AZStd::weak_ptr closePrefabDialogWeakPtr(closePrefabDialog); - closePrefabDialog->setObjectName(ClosePrefabDialog); - - // Main Content section begins. - QVBoxLayout* contentLayout = new QVBoxLayout(closePrefabDialog.get()); - QFrame* prefabSaveWarningFrame = new QFrame(closePrefabDialog.get()); - QHBoxLayout* levelEntitiesSaveQuestionLayout = new QHBoxLayout(closePrefabDialog.get()); - prefabSaveWarningFrame->setObjectName(PrefabSaveWarningFrame); - - // Add a warning icon next to save prefab warning. - prefabSaveWarningFrame->setLayout(levelEntitiesSaveQuestionLayout); - QPixmap warningIcon(QString(":/Notifications/warning.svg")); - QLabel* warningIconContainer = new QLabel(closePrefabDialog.get()); - warningIconContainer->setPixmap(warningIcon); - warningIconContainer->setFixedWidth(warningIcon.width()); - levelEntitiesSaveQuestionLayout->addWidget(warningIconContainer); - - // Ask user if they want to save entities in level. - QLabel* prefabSaveQuestionLabel = new QLabel("Do you want to save the below unsaved prefabs?", closePrefabDialog.get()); - levelEntitiesSaveQuestionLayout->addWidget(prefabSaveQuestionLabel); - contentLayout->addWidget(prefabSaveWarningFrame); - - auto templateToSave = s_prefabSystemComponentInterface->FindTemplate(templateId); - AZ::IO::Path templateToSaveFilePath = templateToSave->get().GetFilePath(); - AZStd::unique_ptr unsavedPrefabsCard = ConstructUnsavedPrefabsCard(templateId); - contentLayout->addWidget(unsavedPrefabsCard.release()); - - contentLayout->addStretch(); - - QHBoxLayout* footerLayout = new QHBoxLayout(closePrefabDialog.get()); - - QDialogButtonBox* prefabSaveConfirmationButtons = new QDialogButtonBox( - QDialogButtonBox::Save | QDialogButtonBox::Discard | QDialogButtonBox::Cancel, closePrefabDialog.get()); - footerLayout->addWidget(prefabSaveConfirmationButtons); - contentLayout->addLayout(footerLayout); - QObject::connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, closePrefabDialog.get(), &QDialog::accept); - QObject::connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, closePrefabDialog.get(), &QDialog::reject); - QObject::connect( - prefabSaveConfirmationButtons, &QDialogButtonBox::clicked, closePrefabDialog.get(), - [closePrefabDialogWeakPtr, prefabSaveConfirmationButtons](QAbstractButton* button) - { - int prefabSaveSelection = prefabSaveConfirmationButtons->buttonRole(button); - closePrefabDialogWeakPtr.lock()->done(prefabSaveSelection); - }); - AzQtComponents::StyleManager::setStyleSheet(closePrefabDialog.get(), QStringLiteral("style:Editor.qss")); - closePrefabDialog->setLayout(contentLayout); - return closePrefabDialog; + m_prefabSaveHandler.ExecuteSavePrefabDialog(templateId, useSaveAllPrefabsPreference); } - AZStd::unique_ptr PrefabIntegrationManager::ConstructUnsavedPrefabsCard(TemplateId templateId) - { - FlowLayout* unsavedPrefabsLayout = new FlowLayout(nullptr); + } // namespace Prefab - AZStd::set dirtyTemplatePaths = s_prefabSystemComponentInterface->GetDirtyTemplatePaths(templateId); - - for (AZ::IO::PathView dirtyTemplatePath : dirtyTemplatePaths) - { - QLabel* prefabNameLabel = - new QLabel(QString("%1").arg(dirtyTemplatePath.Filename().Native().data()), AzToolsFramework::GetActiveWindow()); - prefabNameLabel->setObjectName(UnsavedPrefabFileName); - prefabNameLabel->setWordWrap(true); - prefabNameLabel->setToolTip(dirtyTemplatePath.Native().data()); - prefabNameLabel->setProperty("FilePath", dirtyTemplatePath.Native().data()); - unsavedPrefabsLayout->addWidget(prefabNameLabel); - } - - AZStd::unique_ptr unsavedPrefabsContainer = AZStd::make_unique(AzToolsFramework::GetActiveWindow()); - unsavedPrefabsContainer->setObjectName(SaveDependentPrefabsCard); - unsavedPrefabsContainer->setTitle("Unsaved Prefabs"); - unsavedPrefabsContainer->header()->setHasContextMenu(false); - unsavedPrefabsContainer->header()->setIcon(QIcon(QStringLiteral(":/Entity/prefab_edit.svg"))); - - QFrame* unsavedPrefabsFrame = new QFrame(unsavedPrefabsContainer.get()); - unsavedPrefabsFrame->setLayout(unsavedPrefabsLayout); - QScrollArea* unsavedPrefabsScrollArea = new QScrollArea(unsavedPrefabsContainer.get()); - unsavedPrefabsScrollArea->setWidget(unsavedPrefabsFrame); - unsavedPrefabsScrollArea->setWidgetResizable(true); - unsavedPrefabsContainer->setContentWidget(unsavedPrefabsScrollArea); - - return AZStd::move(unsavedPrefabsContainer); - } - } -} +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.h index 800873349a..bb8fa227a8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.h @@ -9,23 +9,18 @@ #pragma once #include -#include #include -#include #include #include -#include -#include #include #include #include +#include #include #include #include -#include - namespace AzToolsFramework { class ContainerEntityInterface; @@ -35,30 +30,13 @@ namespace AzToolsFramework { class PrefabFocusPublicInterface; class PrefabLoaderInterface; - - //! Structure for saving/retrieving user settings related to prefab workflows. - class PrefabUserSettings - : public AZ::UserSettings - { - public: - AZ_CLASS_ALLOCATOR(PrefabUserSettings, AZ::SystemAllocator, 0); - AZ_RTTI(PrefabUserSettings, "{E17A6128-E2C3-4501-B1AD-B8BB0D315602}", AZ::UserSettings); - - AZStd::string m_saveLocation; - bool m_autoNumber = false; //!< Should the name of the prefab file be automatically numbered. e.g PrefabName_001.prefab vs PrefabName.prefab. - - PrefabUserSettings() = default; - - static void Reflect(AZ::ReflectContext* context); - }; + class PrefabPublicInterface; class PrefabIntegrationManager final : public EditorContextMenuBus::Handler , public EditorEventsBus::Handler - , public AssetBrowser::AssetBrowserSourceDropBus::Handler , public PrefabInstanceContainerNotificationBus::Handler , public PrefabIntegrationInterface - , public QObject , private EditorEntityContextNotificationBus::Handler { public: @@ -77,9 +55,6 @@ namespace AzToolsFramework // EditorEventsBus overrides ... void OnEscape() override; - // EntityOutlinerSourceDropHandlingBus overrides ... - void HandleSourceFileType(AZStd::string_view sourceFilePath, AZ::EntityId parentId, AZ::Vector3 position) const override; - // EditorEntityContextNotificationBus overrides ... void OnStartPlayInEditorBegin() override; void OnStopPlayInEditor() override; @@ -94,6 +69,9 @@ namespace AzToolsFramework void ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) override; private: + // Handles the UI for prefab save operations. + PrefabSaveHandler m_prefabSaveHandler; + // Used to handle the UI for the level root. LevelRootUiHandler m_levelRootUiHandler; @@ -120,27 +98,6 @@ namespace AzToolsFramework void InitializeShortcuts(); void UninitializeShortcuts(); - // Prompt and resolve dialogs - static bool QueryUserForPrefabSaveLocation( - const AZStd::string& suggestedName, const char* initialTargetDirectory, AZ::u32 prefabUserSettingsId, QWidget* activeWindow, - AZStd::string& outPrefabName, AZStd::string& outPrefabFilePath); - static bool QueryUserForPrefabFilePath(AZStd::string& outPrefabFilePath); - static bool QueryUserForProceduralPrefabAsset(AZStd::string& outPrefabAssetPath); - static void WarnUserOfError(AZStd::string_view title, AZStd::string_view message); - - // Path and filename generation - static void GenerateSuggestedFilenameFromEntities(const EntityIdList& entities, AZStd::string& outName); - static bool AppendEntityToSuggestedFilename(AZStd::string& filename, AZ::EntityId entityId); - - enum class PrefabSaveResult - { - Continue, - Retry, - Cancel - }; - static PrefabSaveResult IsPrefabPathValidForAssets(QWidget* activeWindow, QString prefabPath, AZStd::string& retrySavePath); - static void GenerateSuggestedPrefabPath(const AZStd::string& prefabName, const AZStd::string& targetDirectory, AZStd::string& suggestedFullPath); - // Reference detection static void GatherAllReferencedEntitiesAndCompare(const EntityIdSet& entities, EntityIdSet& entitiesAndReferencedEntities, bool& hasExternalReferences); @@ -148,20 +105,10 @@ namespace AzToolsFramework static bool QueryAndPruneMissingExternalReferences(EntityIdSet& entities, EntityIdSet& selectedAndReferencedEntities, bool& useReferencedEntities, bool defaultMoveExternalRefs = false); - // Settings management - static void SetPrefabSaveLocation(const AZStd::string& path, AZ::u32 settingsId); - static bool GetPrefabSaveLocation(AZStd::string& path, AZ::u32 settingsId); - static AZ::u32 GetSliceFlags(const AZ::Edit::ElementData* editData, const AZ::Edit::ClassData* classData); - AZStd::shared_ptr ConstructClosePrefabDialog(TemplateId templateId); - AZStd::unique_ptr ConstructUnsavedPrefabsCard(TemplateId templateId); - AZStd::unique_ptr ConstructSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference); - void SavePrefabsInDialog(QDialog* unsavedPrefabsDialog); - AZStd::vector> m_actions; - static const AZStd::string s_prefabFileExtension; static AzFramework::EntityContextId s_editorEntityContextId; static ContainerEntityInterface* s_containerEntityInterface; @@ -169,7 +116,6 @@ namespace AzToolsFramework static PrefabFocusPublicInterface* s_prefabFocusPublicInterface; static PrefabLoaderInterface* s_prefabLoaderInterface; static PrefabPublicInterface* s_prefabPublicInterface; - static PrefabSystemComponentInterface* s_prefabSystemComponentInterface; ReadOnlyEntityPublicInterface* m_readOnlyEntityPublicInterface = nullptr; }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.cpp new file mode 100644 index 0000000000..7234165076 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.cpp @@ -0,0 +1,722 @@ +/* + * 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 + * + */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AzToolsFramework +{ + namespace Prefab + { + PrefabLoaderInterface* PrefabSaveHandler::s_prefabLoaderInterface = nullptr; + PrefabPublicInterface* PrefabSaveHandler::s_prefabPublicInterface = nullptr; + PrefabSystemComponentInterface* PrefabSaveHandler::s_prefabSystemComponentInterface = nullptr; + + const AZStd::string PrefabSaveHandler::s_prefabFileExtension = ".prefab"; + + static const char* const ClosePrefabDialog = "ClosePrefabDialog"; + static const char* const FooterSeparatorLine = "FooterSeparatorLine"; + static const char* const PrefabSavedMessageFrame = "PrefabSavedMessageFrame"; + static const char* const PrefabSavePreferenceHint = "PrefabSavePreferenceHint"; + static const char* const PrefabSaveWarningFrame = "PrefabSaveWarningFrame"; + static const char* const SaveDependentPrefabsCard = "SaveDependentPrefabsCard"; + static const char* const SavePrefabDialog = "SavePrefabDialog"; + static const char* const UnsavedPrefabFileName = "UnsavedPrefabFileName"; + + void PrefabUserSettings::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) + { + serializeContext->Class() + ->Version(1) + ->Field("m_saveLocation", &PrefabUserSettings::m_saveLocation) + ->Field("m_autoNumber", &PrefabUserSettings::m_autoNumber); + } + } + + PrefabSaveHandler::PrefabSaveHandler() + { + s_prefabLoaderInterface = AZ::Interface::Get(); + if (s_prefabLoaderInterface == nullptr) + { + AZ_Assert(false, "Prefab - could not get PrefabLoaderInterface on PrefabSaveHandler construction."); + return; + } + + s_prefabPublicInterface = AZ::Interface::Get(); + if (s_prefabPublicInterface == nullptr) + { + AZ_Assert(false, "Prefab - could not get PrefabPublicInterface on PrefabSaveHandler construction."); + return; + } + + s_prefabSystemComponentInterface = AZ::Interface::Get(); + if (s_prefabSystemComponentInterface == nullptr) + { + AZ_Assert(false, "Prefab - could not get PrefabSystemComponentInterface on PrefabSaveHandler construction."); + return; + } + + AssetBrowser::AssetBrowserSourceDropBus::Handler::BusConnect(s_prefabFileExtension); + } + + PrefabSaveHandler::~PrefabSaveHandler() + { + AssetBrowser::AssetBrowserSourceDropBus::Handler::BusDisconnect(); + } + + bool PrefabSaveHandler::GetPrefabSaveLocation(AZStd::string& path, AZ::u32 settingsId) + { + auto settings = AZ::UserSettings::Find(settingsId, AZ::UserSettings::CT_LOCAL); + if (settings) + { + path = settings->m_saveLocation; + return true; + } + + return false; + } + + void PrefabSaveHandler::SetPrefabSaveLocation(const AZStd::string& path, AZ::u32 settingsId) + { + auto settings = AZ::UserSettings::CreateFind(settingsId, AZ::UserSettings::CT_LOCAL); + settings->m_saveLocation = path; + } + + void PrefabSaveHandler::HandleSourceFileType( + AZStd::string_view sourceFilePath, AZ::EntityId parentId, AZ::Vector3 position) const + { + auto instantiatePrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(sourceFilePath, parentId, position); + + if (!instantiatePrefabOutcome.IsSuccess()) + { + WarningDialog("Prefab Instantiation Error", instantiatePrefabOutcome.GetError()); + } + } + + int PrefabSaveHandler::ExecuteClosePrefabDialog(TemplateId templateId) + { + if (s_prefabSystemComponentInterface->AreDirtyTemplatesPresent(templateId)) + { + auto prefabSaveSelectionDialog = ConstructClosePrefabDialog(templateId); + + int prefabSaveSelection = prefabSaveSelectionDialog->exec(); + + if (prefabSaveSelection == QDialog::Accepted) + { + SavePrefabsInDialog(prefabSaveSelectionDialog.get()); + } + + return prefabSaveSelection; + } + + return QDialogButtonBox::DestructiveRole; + } + + void PrefabSaveHandler::ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) + { + auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId); + AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath(); + + if (s_prefabSystemComponentInterface->IsTemplateDirty(templateId)) + { + if (s_prefabLoaderInterface->SaveTemplate(templateId) == false) + { + AZ_Error("Prefab", false, "Template '%s' could not be saved successfully.", prefabTemplatePath.c_str()); + return; + } + } + + if (s_prefabSystemComponentInterface->AreDirtyTemplatesPresent(templateId)) + { + if (useSaveAllPrefabsPreference) + { + SaveAllPrefabsPreference saveAllPrefabsPreference = s_prefabLoaderInterface->GetSaveAllPrefabsPreference(); + + if (saveAllPrefabsPreference == SaveAllPrefabsPreference::SaveAll) + { + s_prefabSystemComponentInterface->SaveAllDirtyTemplates(templateId); + return; + } + else if (saveAllPrefabsPreference == SaveAllPrefabsPreference::SaveNone) + { + return; + } + } + + AZStd::unique_ptr savePrefabDialog = ConstructSavePrefabDialog(templateId, useSaveAllPrefabsPreference); + if (savePrefabDialog) + { + int prefabSaveSelection = savePrefabDialog->exec(); + + if (prefabSaveSelection == QDialog::Accepted) + { + SavePrefabsInDialog(savePrefabDialog.get()); + } + } + } + } + + bool PrefabSaveHandler::QueryUserForPrefabFilePath(AZStd::string& outPrefabFilePath) + { + AssetSelectionModel selection; + + // Note, string filter will match every source file CONTAINING ".prefab". + // If this causes issues, we will need to create a new filter class for regex matching. + // We'll need to check if the file contents are actually a prefab later in the flow anyways, + // so this should not be an issue. + StringFilter* stringFilter = new StringFilter(); + stringFilter->SetName("Prefab"); + stringFilter->SetFilterString(".prefab"); + stringFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down); + auto stringFilterPtr = FilterConstType(stringFilter); + + EntryTypeFilter* sourceFilter = new EntryTypeFilter(); + sourceFilter->SetName("Source"); + sourceFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Source); + sourceFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down); + auto sourceFilterPtr = FilterConstType(sourceFilter); + + CompositeFilter* compositeFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND); + compositeFilter->SetName("Prefab"); + compositeFilter->AddFilter(sourceFilterPtr); + compositeFilter->AddFilter(stringFilterPtr); + auto compositeFilterPtr = FilterConstType(compositeFilter); + + selection.SetDisplayFilter(compositeFilterPtr); + selection.SetSelectionFilter(compositeFilterPtr); + + AssetBrowserComponentRequestBus::Broadcast( + &AssetBrowserComponentRequests::PickAssets, selection, AzToolsFramework::GetActiveWindow()); + + if (!selection.IsValid()) + { + // User closed the dialog without selecting, just return. + return false; + } + + auto source = azrtti_cast(selection.GetResult()); + + if (source == nullptr) + { + AZ_Assert(false, "Prefab - Incorrect entry type selected during prefab instantiation. Expected source."); + return false; + } + + outPrefabFilePath = source->GetFullPath(); + return true; + } + + bool PrefabSaveHandler::QueryUserForProceduralPrefabAsset(AZStd::string& outPrefabAssetPath) + { + using namespace AzToolsFramework; + auto selection = AssetBrowser::AssetSelectionModel::AssetTypeSelection(azrtti_typeid()); + EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection); + + if (!selection.IsValid()) + { + return false; + } + + auto product = azrtti_cast(selection.GetResult()); + if (product == nullptr) + { + return false; + } + outPrefabAssetPath = product->GetRelativePath(); + return true; + } + + PrefabSaveHandler::PrefabSaveResult PrefabSaveHandler::IsPrefabPathValidForAssets( + QWidget* activeWindow, QString prefabPath, AZStd::string& retrySavePath) + { + bool assetSetFoldersRetrieved = false; + AZStd::vector assetSafeFolders; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult( + assetSetFoldersRetrieved, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetSafeFolders, assetSafeFolders); + + if (!assetSetFoldersRetrieved) + { + // If the asset safe list couldn't be retrieved, don't block the user but warn them. + AZ_Warning("Prefab", false, "Unable to verify that the prefab file to create is in a valid path."); + } + else + { + AZ::IO::FixedMaxPath lexicallyNormalPath = AZ::IO::PathView(prefabPath.toUtf8().constData()).LexicallyNormal(); + + bool isPathSafeForAssets = false; + for (const AZStd::string& assetSafeFolder : assetSafeFolders) + { + AZ::IO::PathView assetSafeFolderView(assetSafeFolder); + // Check if the prefabPath is relative to the safe asset directory. + // The Path classes are being used to make this check case insensitive. + if (lexicallyNormalPath.IsRelativeTo(assetSafeFolderView)) + { + isPathSafeForAssets = true; + break; + } + } + + if (!isPathSafeForAssets) + { + // Put an error in the console, so the log files have info about this error, or the user can look up the error after + // dismissing it. + AZStd::string errorMessage = + "You can only save prefabs to either your game project folder or the Gems folder. Update the location and try " + "again.\n\n" + "You can also review and update your save locations in the AssetProcessorPlatformConfig.ini file."; + AZ_Error("Prefab", false, errorMessage.c_str()); + + // Display a pop-up, the logs are easy to miss. This will make sure a user who encounters this error immediately knows + // their prefab save has failed. + QMessageBox msgBox(activeWindow); + msgBox.setIcon(QMessageBox::Icon::Warning); + msgBox.setTextFormat(Qt::RichText); + msgBox.setWindowTitle(QObject::tr("Invalid save location")); + msgBox.setText(QObject::tr(errorMessage.c_str())); + msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Retry); + msgBox.setDefaultButton(QMessageBox::Retry); + const int response = msgBox.exec(); + switch (response) + { + case QMessageBox::Retry: + // If the user wants to retry, they probably want to save to a valid location, + // so set the suggested save path to a known valid location. + if (assetSafeFolders.size() > 0) + { + retrySavePath = assetSafeFolders[0]; + } + return PrefabSaveResult::Retry; + case QMessageBox::Cancel: + default: + return PrefabSaveResult::Cancel; + } + } + } + // Valid prefab save location, continue with the save attempt. + return PrefabSaveResult::Continue; + } + + void PrefabSaveHandler::GenerateSuggestedPrefabPath( + const AZStd::string& prefabName, const AZStd::string& targetDirectory, AZStd::string& suggestedFullPath) + { + // Generate full suggested path from prefabName - if given NewPrefab as prefabName, + // NewPrefab_001.prefab would be tried, and if that already existed we would suggest + // the first unused number value (NewPrefab_002.prefab etc.) + AZStd::string normalizedTargetDirectory = targetDirectory; + AZ::StringFunc::Path::Normalize(normalizedTargetDirectory); + + // Convert spaces in entity names to underscores + AZStd::string prefabNameFiltered = prefabName; + AZ::StringFunc::Replace(prefabNameFiltered, ' ', '_'); + + auto settings = AZ::UserSettings::CreateFind(AZ_CRC("PrefabUserSettings"), AZ::UserSettings::CT_LOCAL); + if (settings->m_autoNumber) + { + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + + const AZ::u32 maxPrefabNumber = 1000; + for (AZ::u32 prefabNumber = 1; prefabNumber < maxPrefabNumber; ++prefabNumber) + { + AZStd::string possiblePath; + AZ::StringFunc::Path::Join( + normalizedTargetDirectory.c_str(), + AZStd::string::format("%s_%3.3u%s", prefabNameFiltered.c_str(), prefabNumber, s_prefabFileExtension.c_str()) + .c_str(), + possiblePath); + + if (!fileIO || !fileIO->Exists(possiblePath.c_str())) + { + suggestedFullPath = possiblePath; + break; + } + } + } + else + { + // use the entity name as the file name regardless of it already existing, the OS will ask the user to overwrite the file in + // that case. + AZ::StringFunc::Path::Join( + normalizedTargetDirectory.c_str(), + AZStd::string::format("%s%s", prefabNameFiltered.c_str(), s_prefabFileExtension.c_str()).c_str(), suggestedFullPath); + } + } + + bool PrefabSaveHandler::QueryUserForPrefabSaveLocation( + const AZStd::string& suggestedName, + const char* initialTargetDirectory, + AZ::u32 prefabUserSettingsId, + QWidget* activeWindow, + AZStd::string& outPrefabName, + AZStd::string& outPrefabFilePath) + { + AZStd::string saveAsInitialSuggestedDirectory; + if (!GetPrefabSaveLocation(saveAsInitialSuggestedDirectory, prefabUserSettingsId)) + { + saveAsInitialSuggestedDirectory = initialTargetDirectory; + } + + AZStd::string saveAsInitialSuggestedFullPath; + GenerateSuggestedPrefabPath(suggestedName, saveAsInitialSuggestedDirectory, saveAsInitialSuggestedFullPath); + + QString saveAs; + AZStd::string targetPath; + QFileInfo prefabSaveFileInfo; + QString prefabName; + while (true) + { + { + AZ_PROFILE_FUNCTION(AzToolsFramework); + saveAs = QFileDialog::getSaveFileName( + nullptr, QString("Save As..."), saveAsInitialSuggestedFullPath.c_str(), QString("Prefabs (*.prefab)")); + } + + prefabSaveFileInfo = saveAs; + prefabName = prefabSaveFileInfo.baseName(); + if (saveAs.isEmpty()) + { + return false; + } + + targetPath = saveAs.toUtf8().constData(); + if (AzFramework::StringFunc::Utf8::CheckNonAsciiChar(targetPath)) + { + WarningDialog( + "Prefab Creation Failed.", + "Unicode file name is not supported. \r\n" + "Please use ASCII characters to name your prefab."); + return false; + } + + PrefabSaveResult saveResult = IsPrefabPathValidForAssets(activeWindow, saveAs, saveAsInitialSuggestedFullPath); + if (saveResult == PrefabSaveResult::Cancel) + { + // The error was already reported if this failed. + return false; + } + else if (saveResult == PrefabSaveResult::Continue) + { + // The prefab save name is valid, continue with the save attempt. + break; + } + } + + // If the prefab already exists, notify the user and bail + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + if (fileIO && fileIO->Exists(targetPath.c_str())) + { + const AZStd::string message = AZStd::string::format( + "You are attempting to overwrite an existing prefab: \"%s\".\r\n\r\n" + "This will damage instances or cascades of this prefab. \r\n\r\n" + "Instead, either push entities/fields to the prefab, or save to a different location.", + targetPath.c_str()); + + WarningDialog("Prefab Already Exists", message); + return false; + } + + // We prevent users from creating a new prefab with the same relative path that's already + // been used by an existing prefab in other places (e.g. Gems) because the AssetProcessor + // generates asset ids based on relative paths. This is unnecessary once AssetProcessor + // starts to generate UUID to every asset regardless of paths. + { + AZStd::string prefabRelativeName; + bool relativePathFound; + AssetSystemRequestBus::BroadcastResult( + relativePathFound, &AssetSystemRequestBus::Events::GetRelativeProductPathFromFullSourceOrProductPath, targetPath, + prefabRelativeName); + + AZ::Data::AssetId prefabAssetId; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + prefabAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, prefabRelativeName.c_str(), + AZ::Data::s_invalidAssetType, false); + if (prefabAssetId.IsValid()) + { + const AZStd::string message = AZStd::string::format( + "A prefab with the relative path \"%s\" already exists in the Asset Database. \r\n\r\n" + "Overriding it will damage instances or cascades of this prefab. \r\n\r\n" + "Instead, either push entities/fields to the prefab, or save to a different location.", + prefabRelativeName.c_str()); + + WarningDialog("Prefab Path Error", message); + return false; + } + } + + AZStd::string saveDir(prefabSaveFileInfo.absoluteDir().absolutePath().toUtf8().constData()); + SetPrefabSaveLocation(saveDir, prefabUserSettingsId); + + outPrefabName = prefabName.toUtf8().constData(); + outPrefabFilePath = targetPath.c_str(); + + return true; + } + + void PrefabSaveHandler::GenerateSuggestedFilenameFromEntities(const EntityIdList& entityIds, AZStd::string& outName) + { + AZ_PROFILE_FUNCTION(AzToolsFramework); + + AZStd::string suggestedName; + + for (const AZ::EntityId& entityId : entityIds) + { + if (!AppendEntityToSuggestedFilename(suggestedName, entityId)) + { + break; + } + } + + if (suggestedName.size() == 0 || AzFramework::StringFunc::Utf8::CheckNonAsciiChar(suggestedName)) + { + suggestedName = "NewPrefab"; + } + + outName = suggestedName; + } + + bool PrefabSaveHandler::AppendEntityToSuggestedFilename(AZStd::string& filename, AZ::EntityId entityId) + { + // When naming a prefab after its entities, we stop appending additional names once we've reached this cutoff length + size_t prefabNameCutoffLength = 32; + AzToolsFramework::EntityIdSet usedNameEntities; + + if (usedNameEntities.find(entityId) == usedNameEntities.end()) + { + AZ::Entity* entity = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId); + if (entity) + { + AZStd::string entityNameFiltered = entity->GetName(); + + // Convert spaces in entity names to underscores + for (size_t i = 0; i < entityNameFiltered.size(); ++i) + { + char& character = entityNameFiltered.at(i); + if (character == ' ') + { + character = '_'; + } + } + + filename.append(entityNameFiltered); + usedNameEntities.insert(entityId); + if (filename.size() > prefabNameCutoffLength) + { + return false; + } + } + } + + return true; + } + + void PrefabSaveHandler::SavePrefabsInDialog(QDialog* unsavedPrefabsDialog) + { + QList unsavedPrefabFileLabels = unsavedPrefabsDialog->findChildren(UnsavedPrefabFileName); + if (unsavedPrefabFileLabels.size() > 0) + { + for (const QLabel* unsavedPrefabFileLabel : unsavedPrefabFileLabels) + { + AZStd::string unsavedPrefabFileName = unsavedPrefabFileLabel->property("FilePath").toString().toUtf8().data(); + AzToolsFramework::Prefab::TemplateId unsavedPrefabTemplateId = + s_prefabSystemComponentInterface->GetTemplateIdFromFilePath(unsavedPrefabFileName.data()); + [[maybe_unused]] bool isTemplateSavedSuccessfully = s_prefabLoaderInterface->SaveTemplate(unsavedPrefabTemplateId); + AZ_Error("Prefab", isTemplateSavedSuccessfully, "Prefab '%s' could not be saved successfully.", unsavedPrefabFileName.c_str()); + } + } + } + + AZStd::unique_ptr PrefabSaveHandler::ConstructSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) + { + AZStd::unique_ptr savePrefabDialog = AZStd::make_unique(AzToolsFramework::GetActiveWindow()); + + savePrefabDialog->setWindowTitle("Unsaved files detected"); + + // Main Content section begins. + savePrefabDialog->setObjectName(SavePrefabDialog); + QBoxLayout* contentLayout = new QVBoxLayout(savePrefabDialog.get()); + + QFrame* prefabSavedMessageFrame = new QFrame(savePrefabDialog.get()); + QHBoxLayout* prefabSavedMessageLayout = new QHBoxLayout(savePrefabDialog.get()); + prefabSavedMessageFrame->setObjectName(PrefabSavedMessageFrame); + prefabSavedMessageFrame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); + + // Add a checkMark icon next to the level entities saved message. + QPixmap checkMarkIcon(QString(":/Notifications/checkmark.svg")); + QLabel* prefabSavedSuccessfullyIconContainer = new QLabel(savePrefabDialog.get()); + prefabSavedSuccessfullyIconContainer->setPixmap(checkMarkIcon); + prefabSavedSuccessfullyIconContainer->setFixedWidth(checkMarkIcon.width()); + + // Add a message that level entities are saved successfully. + + auto prefabTemplate = s_prefabSystemComponentInterface->FindTemplate(templateId); + AZ::IO::Path prefabTemplatePath = prefabTemplate->get().GetFilePath(); + QLabel* prefabSavedSuccessfullyLabel = new QLabel( + QString("Prefab '%1' has been saved. Do you want to save the below dependent prefabs too?").arg(prefabTemplatePath.c_str()), + savePrefabDialog.get()); + prefabSavedMessageLayout->addWidget(prefabSavedSuccessfullyIconContainer); + prefabSavedMessageLayout->addWidget(prefabSavedSuccessfullyLabel); + prefabSavedMessageFrame->setLayout(prefabSavedMessageLayout); + contentLayout->addWidget(prefabSavedMessageFrame); + + AZStd::unique_ptr unsavedPrefabsContainer = ConstructUnsavedPrefabsCard(templateId); + contentLayout->addWidget(unsavedPrefabsContainer.release()); + + contentLayout->addStretch(); + + // Footer section begins. + QHBoxLayout* footerLayout = new QHBoxLayout(savePrefabDialog.get()); + + if (useSaveAllPrefabsPreference) + { + QFrame* footerSeparatorLine = new QFrame(savePrefabDialog.get()); + footerSeparatorLine->setObjectName(FooterSeparatorLine); + footerSeparatorLine->setFrameShape(QFrame::HLine); + contentLayout->addWidget(footerSeparatorLine); + + QLabel* prefabSavePreferenceHint = new QLabel( + "You can prevent this window from showing in the future by updating your global save preferences.", + savePrefabDialog.get()); + prefabSavePreferenceHint->setToolTip( + "Go to 'Edit > Editor Settings > Global Preferences... > Global save preferences' to update your preference"); + prefabSavePreferenceHint->setObjectName(PrefabSavePreferenceHint); + footerLayout->addWidget(prefabSavePreferenceHint); + } + + QDialogButtonBox* prefabSaveConfirmationButtons = + new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::No, savePrefabDialog.get()); + footerLayout->addWidget(prefabSaveConfirmationButtons); + contentLayout->addLayout(footerLayout); + connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, savePrefabDialog.get(), &QDialog::accept); + connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, savePrefabDialog.get(), &QDialog::reject); + AzQtComponents::StyleManager::setStyleSheet(savePrefabDialog->parentWidget(), QStringLiteral("style:Editor.qss")); + + savePrefabDialog->setLayout(contentLayout); + return AZStd::move(savePrefabDialog); + } + + AZStd::shared_ptr PrefabSaveHandler::ConstructClosePrefabDialog(TemplateId templateId) + { + AZStd::shared_ptr closePrefabDialog = AZStd::make_shared(AzToolsFramework::GetActiveWindow()); + closePrefabDialog->setWindowTitle("Unsaved files detected"); + AZStd::weak_ptr closePrefabDialogWeakPtr(closePrefabDialog); + closePrefabDialog->setObjectName(ClosePrefabDialog); + + // Main Content section begins. + QVBoxLayout* contentLayout = new QVBoxLayout(closePrefabDialog.get()); + QFrame* prefabSaveWarningFrame = new QFrame(closePrefabDialog.get()); + QHBoxLayout* levelEntitiesSaveQuestionLayout = new QHBoxLayout(closePrefabDialog.get()); + prefabSaveWarningFrame->setObjectName(PrefabSaveWarningFrame); + + // Add a warning icon next to save prefab warning. + prefabSaveWarningFrame->setLayout(levelEntitiesSaveQuestionLayout); + QPixmap warningIcon(QString(":/Notifications/warning.svg")); + QLabel* warningIconContainer = new QLabel(closePrefabDialog.get()); + warningIconContainer->setPixmap(warningIcon); + warningIconContainer->setFixedWidth(warningIcon.width()); + levelEntitiesSaveQuestionLayout->addWidget(warningIconContainer); + + // Ask user if they want to save entities in level. + QLabel* prefabSaveQuestionLabel = new QLabel("Do you want to save the below unsaved prefabs?", closePrefabDialog.get()); + levelEntitiesSaveQuestionLayout->addWidget(prefabSaveQuestionLabel); + contentLayout->addWidget(prefabSaveWarningFrame); + + auto templateToSave = s_prefabSystemComponentInterface->FindTemplate(templateId); + AZ::IO::Path templateToSaveFilePath = templateToSave->get().GetFilePath(); + AZStd::unique_ptr unsavedPrefabsCard = ConstructUnsavedPrefabsCard(templateId); + contentLayout->addWidget(unsavedPrefabsCard.release()); + + contentLayout->addStretch(); + + QHBoxLayout* footerLayout = new QHBoxLayout(closePrefabDialog.get()); + + QDialogButtonBox* prefabSaveConfirmationButtons = new QDialogButtonBox( + QDialogButtonBox::Save | QDialogButtonBox::Discard | QDialogButtonBox::Cancel, closePrefabDialog.get()); + footerLayout->addWidget(prefabSaveConfirmationButtons); + contentLayout->addLayout(footerLayout); + QObject::connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, closePrefabDialog.get(), &QDialog::accept); + QObject::connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, closePrefabDialog.get(), &QDialog::reject); + QObject::connect( + prefabSaveConfirmationButtons, &QDialogButtonBox::clicked, closePrefabDialog.get(), + [closePrefabDialogWeakPtr, prefabSaveConfirmationButtons](QAbstractButton* button) + { + int prefabSaveSelection = prefabSaveConfirmationButtons->buttonRole(button); + closePrefabDialogWeakPtr.lock()->done(prefabSaveSelection); + }); + AzQtComponents::StyleManager::setStyleSheet(closePrefabDialog.get(), QStringLiteral("style:Editor.qss")); + closePrefabDialog->setLayout(contentLayout); + return closePrefabDialog; + } + + AZStd::unique_ptr PrefabSaveHandler::ConstructUnsavedPrefabsCard(TemplateId templateId) + { + FlowLayout* unsavedPrefabsLayout = new FlowLayout(nullptr); + + AZStd::set dirtyTemplatePaths = s_prefabSystemComponentInterface->GetDirtyTemplatePaths(templateId); + + for (AZ::IO::PathView dirtyTemplatePath : dirtyTemplatePaths) + { + QLabel* prefabNameLabel = + new QLabel(QString("%1").arg(dirtyTemplatePath.Filename().Native().data()), AzToolsFramework::GetActiveWindow()); + prefabNameLabel->setObjectName(UnsavedPrefabFileName); + prefabNameLabel->setWordWrap(true); + prefabNameLabel->setToolTip(dirtyTemplatePath.Native().data()); + prefabNameLabel->setProperty("FilePath", dirtyTemplatePath.Native().data()); + unsavedPrefabsLayout->addWidget(prefabNameLabel); + } + + AZStd::unique_ptr unsavedPrefabsContainer = AZStd::make_unique(AzToolsFramework::GetActiveWindow()); + unsavedPrefabsContainer->setObjectName(SaveDependentPrefabsCard); + unsavedPrefabsContainer->setTitle("Unsaved Prefabs"); + unsavedPrefabsContainer->header()->setHasContextMenu(false); + unsavedPrefabsContainer->header()->setIcon(QIcon(QStringLiteral(":/Entity/prefab_edit.svg"))); + + QFrame* unsavedPrefabsFrame = new QFrame(unsavedPrefabsContainer.get()); + unsavedPrefabsFrame->setLayout(unsavedPrefabsLayout); + QScrollArea* unsavedPrefabsScrollArea = new QScrollArea(unsavedPrefabsContainer.get()); + unsavedPrefabsScrollArea->setWidget(unsavedPrefabsFrame); + unsavedPrefabsScrollArea->setWidgetResizable(true); + unsavedPrefabsContainer->setContentWidget(unsavedPrefabsScrollArea); + + return AZStd::move(unsavedPrefabsContainer); + } + } +} diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.h new file mode 100644 index 0000000000..0a7cd2c582 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabSaveLoadHandler.h @@ -0,0 +1,101 @@ +/* + * 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 + +#include +#include +#include + +#include + +namespace AzToolsFramework +{ + namespace Prefab + { + class PrefabLoaderInterface; + class PrefabPublicInterface; + class PrefabSystemComponentInterface; + + //! Structure for saving/retrieving user settings related to prefab workflows. + class PrefabUserSettings : public AZ::UserSettings + { + public: + AZ_CLASS_ALLOCATOR(PrefabUserSettings, AZ::SystemAllocator, 0); + AZ_RTTI(PrefabUserSettings, "{E17A6128-E2C3-4501-B1AD-B8BB0D315602}", AZ::UserSettings); + + AZStd::string m_saveLocation; + bool m_autoNumber = + false; //!< Should the name of the prefab file be automatically numbered. e.g PrefabName_001.prefab vs PrefabName.prefab. + + PrefabUserSettings() = default; + + static void Reflect(AZ::ReflectContext* context); + }; + + //! Class to handle dialogs and windows related to prefab save operations. + class PrefabSaveHandler final + : public QObject + , public AssetBrowser::AssetBrowserSourceDropBus::Handler + { + public: + AZ_CLASS_ALLOCATOR(PrefabSaveHandler, AZ::SystemAllocator, 0); + + PrefabSaveHandler(); + ~PrefabSaveHandler(); + + // Settings management + static bool GetPrefabSaveLocation(AZStd::string& path, AZ::u32 settingsId); + static void SetPrefabSaveLocation(const AZStd::string& path, AZ::u32 settingsId); + + // EntityOutlinerSourceDropHandlingBus overrides ... + void HandleSourceFileType(AZStd::string_view sourceFilePath, AZ::EntityId parentId, AZ::Vector3 position) const override; + + // Dialogs + int ExecuteClosePrefabDialog(TemplateId templateId); + void ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference); + static bool QueryUserForPrefabFilePath(AZStd::string& outPrefabFilePath); + static bool QueryUserForProceduralPrefabAsset(AZStd::string& outPrefabAssetPath); + static bool QueryUserForPrefabSaveLocation( + const AZStd::string& suggestedName, + const char* initialTargetDirectory, + AZ::u32 prefabUserSettingsId, + QWidget* activeWindow, + AZStd::string& outPrefabName, + AZStd::string& outPrefabFilePath); + + // Path and filename generation + enum class PrefabSaveResult + { + Continue, + Retry, + Cancel + }; + + static void GenerateSuggestedFilenameFromEntities(const EntityIdList& entities, AZStd::string& outName); + static bool AppendEntityToSuggestedFilename(AZStd::string& filename, AZ::EntityId entityId); + static PrefabSaveResult IsPrefabPathValidForAssets(QWidget* activeWindow, QString prefabPath, AZStd::string& retrySavePath); + static void GenerateSuggestedPrefabPath( + const AZStd::string& prefabName, const AZStd::string& targetDirectory, AZStd::string& suggestedFullPath); + + private: + AZStd::shared_ptr ConstructClosePrefabDialog(TemplateId templateId); + AZStd::unique_ptr ConstructUnsavedPrefabsCard(TemplateId templateId); + AZStd::unique_ptr ConstructSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference); + void SavePrefabsInDialog(QDialog* unsavedPrefabsDialog); + + static const AZStd::string s_prefabFileExtension; + + static PrefabLoaderInterface* s_prefabLoaderInterface; + static PrefabPublicInterface* s_prefabPublicInterface; + static PrefabSystemComponentInterface* s_prefabSystemComponentInterface; + }; + } +} diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/UICore/WidgetHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/UICore/WidgetHelpers.h index 0c326f9640..379a19739e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/UICore/WidgetHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/UICore/WidgetHelpers.h @@ -11,11 +11,12 @@ #include #include +#include namespace AzToolsFramework { - /// Gets the currently active window, or the Editor's main window if there is no active window. - /// Can be used to guarantee that modal dialogs have a valid parent in every context. + //! Gets the currently active window, or the Editor's main window if there is no active window. + //! Can be used to guarantee that modal dialogs have a valid parent in every context. inline QWidget* GetActiveWindow() { QWidget* activeWindow = QApplication::activeWindow(); @@ -26,5 +27,12 @@ namespace AzToolsFramework return activeWindow; } + + //! Create a simple modal dialog with a warning message. + inline void WarningDialog(AZStd::string_view title, AZStd::string_view message) + { + QMessageBox::warning(GetActiveWindow(), QString(title.data()), QString(message.data()), QMessageBox::Ok, QMessageBox::Ok); + } + } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h index 0465a7920f..8d3cef890a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -36,8 +37,6 @@ namespace AzToolsFramework { class EditorVisibleEntityDataCacheInterface; - using EntityIdSet = AZStd::unordered_set; //!< Alias for unordered_set of EntityIds. - //! Entity related data required by manipulators during action. struct EntityIdManipulatorLookup { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 3947008ce7..e5e09f7cb3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -153,6 +153,7 @@ set(FILES Entity/SliceEditorEntityOwnershipService.h Entity/SliceEditorEntityOwnershipService.cpp Entity/SliceEditorEntityOwnershipServiceBus.h + Entity/EntityTypes.h Entity/EntityUtilityComponent.h Entity/EntityUtilityComponent.cpp Entity/ReadOnly/ReadOnlyEntityInterface.h @@ -758,6 +759,8 @@ set(FILES UI/Prefab/PrefabIntegrationManager.h UI/Prefab/PrefabIntegrationManager.cpp UI/Prefab/PrefabIntegrationInterface.h + UI/Prefab/PrefabSaveLoadHandler.h + UI/Prefab/PrefabSaveLoadHandler.cpp UI/Prefab/PrefabUiHandler.h UI/Prefab/PrefabUiHandler.cpp UI/Prefab/PrefabViewportFocusPathHandler.h diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp index 4f2a19faec..a0c8f7a317 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp @@ -176,7 +176,7 @@ namespace UnitTest TEST_F(PrefabFixupTest, Test_LoadInstanceFromPrefabDom_Overload3) { Instance instance; - Instance::EntityList entityList; + AzToolsFramework::EntityList entityList; (PrefabDomUtils::LoadInstanceFromPrefabDom(instance, entityList, m_prefabDom)); CheckInstance(instance); diff --git a/Code/Tools/SerializeContextTools/SliceConverter.cpp b/Code/Tools/SerializeContextTools/SliceConverter.cpp index cfb1998f48..3d94a6e023 100644 --- a/Code/Tools/SerializeContextTools/SliceConverter.cpp +++ b/Code/Tools/SerializeContextTools/SliceConverter.cpp @@ -553,7 +553,7 @@ namespace AZ // Create a new unmodified prefab Instance for the nested slice instance. auto nestedInstance = AZStd::make_unique(AZStd::move(instanceAlias)); - AzToolsFramework::Prefab::Instance::EntityList newEntities; + AzToolsFramework::EntityList newEntities; if (!AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom( *nestedInstance, newEntities, nestedTemplate->get().GetPrefabDom())) { diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp index 71464501ba..a79f9e4cdb 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp @@ -76,7 +76,7 @@ namespace AZ::Prefab // Deserialize all of the entities and their components (for this prefab only) auto newInstance = AZStd::make_unique(); - AzToolsFramework::Prefab::Instance::EntityList entities; + AzToolsFramework::EntityList entities; if (AzToolsFramework::Prefab::PrefabDomUtils::LoadInstanceFromPrefabDom(*newInstance, entities, genericDocument)) { // Add the fingerprint of all the components and their types From 4bf6b6ba15e435f7ebd6aace4123b5d2f7e14ff7 Mon Sep 17 00:00:00 2001 From: moudgils <47460854+moudgils@users.noreply.github.com> Date: Tue, 15 Feb 2022 10:22:32 -0800 Subject: [PATCH 40/42] Add 3p vulkan validation layer support. (#7540) * Add 3p vulkan validation layer support. Enabling device validation will automatically load the VkLayer_khronos_validation.dll ensuring that validation checks will work correctly Signed-off-by: moudgils <47460854+moudgils@users.noreply.github.com> * Addressed feedback Signed-off-by: moudgils <47460854+moudgils@users.noreply.github.com> * Updating the hash to the new 3p package Signed-off-by: moudgils <47460854+moudgils@users.noreply.github.com> --- Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt | 2 ++ .../Source/Platform/Windows/PAL_windows.cmake | 1 + .../RHI/Vulkan/Code/Source/RHI/Instance.cpp | 27 ++++++++++--------- .../Windows/BuiltInPackages_windows.cmake | 1 + 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt b/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt index 674e5aff9e..19e8943bbe 100644 --- a/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt +++ b/Gems/Atom/RHI/Vulkan/Code/CMakeLists.txt @@ -108,6 +108,7 @@ ly_add_target( BUILD_DEPENDENCIES PUBLIC AZ::AzCore + AZ::AzTest AZ::AzFramework Gem::Atom_RHI.Reflect Gem::Atom_RHI_Vulkan.Reflect @@ -130,6 +131,7 @@ ly_add_target( PRIVATE Gem::Atom_RHI_Vulkan.Private.Static Gem::Atom_RHI.Public + ${VULKAN_VALIDATION_LAYER} ) ly_add_target( diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Windows/PAL_windows.cmake b/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Windows/PAL_windows.cmake index c1a1dce4ff..154757ab41 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Windows/PAL_windows.cmake +++ b/Gems/Atom/RHI/Vulkan/Code/Source/Platform/Windows/PAL_windows.cmake @@ -7,3 +7,4 @@ # set(PAL_TRAIT_ATOM_RHI_VULKAN_SUPPORTED TRUE) +set(VULKAN_VALIDATION_LAYER 3rdParty::vulkan-validationlayers) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Instance.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Instance.cpp index 2dce5d85f3..836bcef8cf 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Instance.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Instance.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace AZ { @@ -45,8 +46,21 @@ namespace AZ bool Instance::Init(const Descriptor& descriptor) { - m_descriptor = descriptor; + m_descriptor = descriptor; + if (GetValidationMode() != RHI::ValidationMode::Disabled) + { + //This env var (VK_LAYER_PATH) is used by the drivers to look for VkLayer_khronos_validation.dll + AZ::Test::SetEnv("VK_LAYER_PATH", AZ::Test::GetCurrentExecutablePath().c_str(), 1); + RawStringList validationLayers = Debug::GetValidationLayers(); + m_descriptor.m_optionalLayers.insert(m_descriptor.m_requiredLayers.end(), validationLayers.begin(), validationLayers.end()); + m_descriptor.m_optionalExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + m_descriptor.m_optionalExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + } +#if defined(AZ_VULKAN_USE_DEBUG_LABELS) + m_descriptor.m_optionalExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); +#endif + m_functionLoader = FunctionLoader::Create(); if (!m_functionLoader->Init()) { @@ -88,17 +102,6 @@ namespace AZ instanceCreateInfo.pApplicationInfo = &appInfo; StringList instanceLayerNames = GetInstanceLayerNames(); - if (GetValidationMode() != RHI::ValidationMode::Disabled) - { - RawStringList validationLayers = Debug::GetValidationLayers(); - m_descriptor.m_optionalLayers.insert(m_descriptor.m_requiredLayers.end(), validationLayers.begin(), validationLayers.end()); - m_descriptor.m_optionalExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); - m_descriptor.m_optionalExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - } -#if defined(AZ_VULKAN_USE_DEBUG_LABELS) - m_descriptor.m_optionalExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); -#endif - RawStringList optionalLayers = FilterList(m_descriptor.m_optionalLayers, instanceLayerNames); m_descriptor.m_requiredLayers.insert(m_descriptor.m_requiredLayers.end(), optionalLayers.begin(), optionalLayers.end()); diff --git a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake index 86676529ae..374e4afef4 100644 --- a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake +++ b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake @@ -50,3 +50,4 @@ ly_associate_package(PACKAGE_NAME lz4-1.9.3-vcpkg-rev4-windows ly_associate_package(PACKAGE_NAME azslc-1.7.35-rev1-windows TARGETS azslc PACKAGE_HASH 606aea611f2f20afcd8467ddabeecd3661e946eac3c843756c7df2871c1fb8a0) ly_associate_package(PACKAGE_NAME SQLite-3.37.2-rev1-windows TARGETS SQLite PACKAGE_HASH c1658c8ed5cf0e45d4a5da940c6a6d770b76e0f4f57313b70d0fd306885f015e) ly_associate_package(PACKAGE_NAME AwsIotDeviceSdkCpp-1.15.2-rev1-windows TARGETS AwsIotDeviceSdkCpp PACKAGE_HASH b03475a9f0f7a7e7c90619fba35f1a74fb2b8f4cd33fa07af99f2ae9e0c079dd) +ly_associate_package(PACKAGE_NAME vulkan-validationlayers-1.2.198-rev1-windows TARGETS vulkan-validationlayers PACKAGE_HASH 4c617b83611f9f990b7e6ff21f2e2d22bda154591bff7e0e39610e319a3e5a53) \ No newline at end of file From aaa8b9df7c31af5ecc0260497ec1c1b4cb4758aa Mon Sep 17 00:00:00 2001 From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com> Date: Tue, 15 Feb 2022 11:17:15 -0800 Subject: [PATCH 41/42] [development] automated tests for timing editor loading of the 10k levels (#7472) It has been observed that when entering game mode in the editor with the 10k levels, the Vulkan backend performs significantly worse compared to DX12 on Windows. These tests are intended to detect if either backend gets worse with a currently generous timeout of 3 minutes to complete (10 for the Vulkan outlier) and should lowered over time as this metric stabilizes. Added a new periodic tests job to specifically run on a GPU instance. Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- .../Gem/PythonTests/CMakeLists.txt | 3 + .../PythonTests/Performance/CMakeLists.txt | 39 ++++++++++ .../Performance/TestSuite_Periodic_DX12.py | 31 ++++++++ .../Performance/TestSuite_Periodic_Vulkan.py | 34 +++++++++ .../Gem/PythonTests/Performance/__init__.py | 6 ++ ...EditorLevelLoading_10KEntityCpuPerfTest.py | 15 ++++ .../EditorLevelLoading_10kVegInstancesTest.py | 15 ++++ .../PythonTests/Performance/tests/__init__.py | 6 ++ .../PythonTests/Performance/utils/__init__.py | 6 ++ .../Performance/utils/perf_timer.py | 72 +++++++++++++++++++ .../build/Platform/Windows/build_config.json | 24 ++++++- 11 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/CMakeLists.txt create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_DX12.py create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_Vulkan.py create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/__init__.py create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10KEntityCpuPerfTest.py create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10kVegInstancesTest.py create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/tests/__init__.py create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/utils/__init__.py create mode 100644 AutomatedTesting/Gem/PythonTests/Performance/utils/perf_timer.py diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 26c03e78c2..421d095be7 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -67,3 +67,6 @@ add_subdirectory(Multiplayer) ## Integration tests for editor testing framework ## add_subdirectory(editor_test_testing) + +## Performance ## +add_subdirectory(Performance) diff --git a/AutomatedTesting/Gem/PythonTests/Performance/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Performance/CMakeLists.txt new file mode 100644 index 0000000000..c2ec14db9d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/CMakeLists.txt @@ -0,0 +1,39 @@ +# +# 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 +# +# + +if(NOT PAL_TRAIT_BUILD_TESTS_SUPPORTED OR NOT PAL_TRAIT_BUILD_HOST_TOOLS) + return() +endif() + +ly_add_pytest( + NAME AutomatedTesting::EditorLevelLoadingPerfTests_DX12 + TEST_SUITE periodic + TEST_REQUIRES gpu + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic_DX12.py + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Performance +) + +ly_add_pytest( + NAME AutomatedTesting::EditorLevelLoadingPerfTests_Vulkan + TEST_SUITE periodic + TEST_REQUIRES gpu + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic_Vulkan.py + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Performance +) diff --git a/AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_DX12.py b/AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_DX12.py new file mode 100644 index 0000000000..ac3152a090 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_DX12.py @@ -0,0 +1,31 @@ +""" +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 + +""" + +# This suite consists of all test cases that are passing and have been verified. + +import pytest +import os +import sys + +from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSingleTest + +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +class TestAutomation(EditorTestSuite): + + class Time_EditorLevelLoading_10KEntityCpuPerfTest(EditorSingleTest): + extra_cmdline_args = ['-rhi=dx12'] + use_null_renderer = False # needs renderer to validate test + + from .tests import EditorLevelLoading_10KEntityCpuPerfTest as test_module + + class Time_EditorLevelLoading_10kVegInstancesTest(EditorSingleTest): + extra_cmdline_args = ['-rhi=dx12'] + use_null_renderer = False # needs renderer to validate test + + from .tests import EditorLevelLoading_10kVegInstancesTest as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_Vulkan.py b/AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_Vulkan.py new file mode 100644 index 0000000000..c71ede27dc --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/TestSuite_Periodic_Vulkan.py @@ -0,0 +1,34 @@ +""" +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 + +""" + +# This suite consists of all test cases that are passing and have been verified. + +import pytest +import os +import sys + +from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSingleTest + +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +class TestAutomation(EditorTestSuite): + + class Time_EditorLevelLoading_10KEntityCpuPerfTest(EditorSingleTest): + # there is currently a huge discrepancy loading this level with vulkan compared to dx12 which requires the 10 min timeout + # this should be removed once that issue has been sorted out + timeout = 600 + extra_cmdline_args = ['-rhi=vulkan'] + use_null_renderer = False # needs renderer to validate test + + from .tests import EditorLevelLoading_10KEntityCpuPerfTest as test_module + + class Time_EditorLevelLoading_10kVegInstancesTest(EditorSingleTest): + extra_cmdline_args = ['-rhi=vulkan'] + use_null_renderer = False # needs renderer to validate test + + from .tests import EditorLevelLoading_10kVegInstancesTest as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Performance/__init__.py b/AutomatedTesting/Gem/PythonTests/Performance/__init__.py new file mode 100644 index 0000000000..f5193b300e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/__init__.py @@ -0,0 +1,6 @@ +""" +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 +""" diff --git a/AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10KEntityCpuPerfTest.py b/AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10KEntityCpuPerfTest.py new file mode 100644 index 0000000000..fb7707044a --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10KEntityCpuPerfTest.py @@ -0,0 +1,15 @@ +""" +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 +""" + +from Performance.utils.perf_timer import time_editor_level_loading + +def EditorLevelLoading_10KEntityCpuPerfTest(): + time_editor_level_loading('Performance', '10KEntityCpuPerfTest') + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(EditorLevelLoading_10KEntityCpuPerfTest) diff --git a/AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10kVegInstancesTest.py b/AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10kVegInstancesTest.py new file mode 100644 index 0000000000..1c71cc806e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/tests/EditorLevelLoading_10kVegInstancesTest.py @@ -0,0 +1,15 @@ +""" +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 +""" + +from Performance.utils.perf_timer import time_editor_level_loading + +def EditorLevelLoading_10kVegInstancesTest(): + time_editor_level_loading('Performance', '10kVegInstancesTest') + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(EditorLevelLoading_10kVegInstancesTest) diff --git a/AutomatedTesting/Gem/PythonTests/Performance/tests/__init__.py b/AutomatedTesting/Gem/PythonTests/Performance/tests/__init__.py new file mode 100644 index 0000000000..f5193b300e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/tests/__init__.py @@ -0,0 +1,6 @@ +""" +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 +""" diff --git a/AutomatedTesting/Gem/PythonTests/Performance/utils/__init__.py b/AutomatedTesting/Gem/PythonTests/Performance/utils/__init__.py new file mode 100644 index 0000000000..f5193b300e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/utils/__init__.py @@ -0,0 +1,6 @@ +""" +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 +""" diff --git a/AutomatedTesting/Gem/PythonTests/Performance/utils/perf_timer.py b/AutomatedTesting/Gem/PythonTests/Performance/utils/perf_timer.py new file mode 100644 index 0000000000..54497e96b2 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Performance/utils/perf_timer.py @@ -0,0 +1,72 @@ +""" +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 +""" + +import time + +ENTER_MSG = ("Entered game mode", "Failed to enter game mode") +EXIT_MSG = ("Exited game mode", "Couldn't exit game mode") + +class Timer: + unit_divisor = 60 + hour_divisor = unit_divisor * unit_divisor + + def start(self): + self._start_time = time.perf_counter() + + def log_time(self, message): + from editor_python_test_tools.utils import Report + + elapsed_time = time.perf_counter() - self._start_time + hours = int(elapsed_time / Timer.hour_divisor) + minutes = int(elapsed_time % Timer.hour_divisor / Timer.unit_divisor) + seconds = elapsed_time % Timer.unit_divisor + + Report.info(f'{message}: {hours:0>2d}:{minutes:0>2d}:{seconds:0>5.2f}\n') + +def time_editor_level_loading(level_dir, level_name): + + """ + Summary: + Time how long it takes to load an arbitrary level, entering game mode, and exiting game mode + + Level Description: + Preferably a level with a large number of entities + + Expected Behavior: + Level loads within a reasonable time frame e.i. doesn't trip the framework timeout + + Benchmark Steps: + 1) Time opening the level + 2) Time entering game mode + 3) Time exiting game mode + 4) Close the editor + + :return: None + """ + from editor_python_test_tools.utils import TestHelper as helper + + timer = Timer() + + helper.init_idle() + + # 1) Open level + timer.start() + helper.open_level(level_dir, level_name) + timer.log_time('Level load time') + + # 2) Time how long it takes to enter game mode + timer.start() + helper.enter_game_mode(ENTER_MSG) + timer.log_time('Enter game mode') + + # 3) Exit game mode + timer.start() + helper.exit_game_mode(EXIT_MSG) + timer.log_time('Exit game mode') + + # 4) Close the editor + helper.close_editor() diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index 017f56bb68..f951221d8e 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -239,7 +239,29 @@ "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_periodic", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", - "CTEST_OPTIONS": "-L \"(SUITE_periodic)\" -T Test --no-tests=error", + "CTEST_OPTIONS": "-L \"(SUITE_periodic)\" -LE \"(REQUIRES_gpu)\" -T Test --no-tests=error", + "TEST_METRICS": "True", + "TEST_RESULTS": "True" + } + }, + "periodic_test_gpu_profile": { + "TAGS": [ + "nightly-incremental", + "nightly-clean", + "weekly-build-metrics" + ], + "PIPELINE_ENV":{ + "NODE_LABEL":"windows-gpu" + }, + "COMMAND": "build_test_windows.cmd", + "PARAMETERS": { + "CONFIGURATION": "profile", + "OUTPUT_DIRECTORY": "build\\windows", + "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", + "CMAKE_LY_PROJECTS": "AutomatedTesting", + "CMAKE_TARGET": "TEST_SUITE_periodic", + "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo", + "CTEST_OPTIONS": "-L \"(SUITE_periodic_REQUIRES_gpu)\" -T Test --no-tests=error", "TEST_METRICS": "True", "TEST_RESULTS": "True" } From 7fbcab9f1341196bb50361283c99bf5961da91d4 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Tue, 15 Feb 2022 13:27:54 -0600 Subject: [PATCH 42/42] gtest_repeat crashes (#7645) * Moved allocation to avoid crash on gtest_repeat. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed GradientSignal tests to work with gtest_repeat. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../AzTest/AzTest/GemTestEnvironment.cpp | 3 ++- .../Code/Tests/GradientSignalTestFixtures.cpp | 16 ++++++++++++++++ .../Code/Tests/GradientSignalTestFixtures.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzTest/AzTest/GemTestEnvironment.cpp b/Code/Framework/AzTest/AzTest/GemTestEnvironment.cpp index e862cdfa94..47eb71898a 100644 --- a/Code/Framework/AzTest/AzTest/GemTestEnvironment.cpp +++ b/Code/Framework/AzTest/AzTest/GemTestEnvironment.cpp @@ -52,7 +52,6 @@ namespace AZ GemTestEnvironment::GemTestEnvironment() { - m_parameters = new Parameters; } void GemTestEnvironment::AddDynamicModulePaths(const AZStd::vector& dynamicModulePaths) @@ -84,6 +83,8 @@ namespace AZ AZ::AllocatorInstance::Create(); + m_parameters = new Parameters; + AddGemsAndComponents(); PreCreateApplication(); diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp index 8d5ada5214..2115d878c6 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.cpp @@ -75,6 +75,22 @@ namespace UnitTest }); } + void GradientSignalTestEnvironment::PostCreateApplication() + { + // Ebus usage will allocate a global context on first usage. If that first usage occurs in a DLL, then the context will be + // invalid on subsequent unit test runs if using gtest_repeat. However, if we force the ebus to create their global context in + // the main test DLL (this one), the context will remain active throughout repeated runs. By creating them in + // PostCreateApplication(), they will be created before the DLLs get loaded and any system components from those DLLs run, so we + // can guarantee this will be the first usage. + + // These ebuses need their contexts created here before any of the dependent DLLs get loaded: + AZ::AssetTypeInfoBus::GetOrCreateContext(); + SurfaceData::SurfaceDataSystemRequestBus::GetOrCreateContext(); + SurfaceData::SurfaceDataProviderRequestBus::GetOrCreateContext(); + SurfaceData::SurfaceDataModifierRequestBus::GetOrCreateContext(); + LmbrCentral::ShapeComponentRequestsBus::GetOrCreateContext(); + } + void GradientSignalBaseFixture::SetupCoreSystems() { // Using the AZ::RPI::MakeAssetHandler will both create the asset handlers, diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h index 4d2233528b..486cdd6cc0 100644 --- a/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h +++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestFixtures.h @@ -21,6 +21,7 @@ namespace UnitTest { public: void AddGemsAndComponents() override; + void PostCreateApplication() override; }; #ifdef HAVE_BENCHMARK