From 5d5087e0d34b327521c346395996ceb778bb5633 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 9 Nov 2021 11:11:15 -0800 Subject: [PATCH 01/72] Moving CommunicatorTracePrinter to a place that AP and Multiplayer gem can use it. MultiplayerEditorSystemComponent now watching the server process and pumping the trace printer. Wip; for some reason not all the server logs are reaching the editor Signed-off-by: Gene Walters --- .../ProcessCommunicatorTracePrinter.cpp} | 12 ++++----- .../ProcessCommunicatorTracePrinter.h} | 13 +++++----- .../AzFramework/azframework_files.cmake | 2 ++ .../assetprocessor_static_files.cmake | 2 -- .../native/resourcecompiler/RCBuilder.cpp | 2 -- .../utilities/ApplicationManagerBase.cpp | 2 +- .../native/utilities/BuilderManager.cpp | 2 +- .../native/utilities/BuilderManager.h | 4 +-- .../MultiplayerEditorSystemComponent.cpp | 26 ++++++++++++++++--- .../Editor/MultiplayerEditorSystemComponent.h | 13 +++++++--- .../Source/MultiplayerSystemComponent.cpp | 1 + 11 files changed, 51 insertions(+), 28 deletions(-) rename Code/{Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp => Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp} (82%) rename Code/{Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h => Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h} (54%) diff --git a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp similarity index 82% rename from Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp rename to Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp index c6008deb34..8f3e45bec5 100644 --- a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.cpp +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp @@ -6,16 +6,16 @@ * */ -#include "CommunicatorTracePrinter.h" +#include "ProcessCommunicatorTracePrinter.h" -CommunicatorTracePrinter::CommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : +ProcessCommunicatorTracePrinter::ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : m_communicator(communicator), m_window(window) { m_stringBeingConcatenated.reserve(1024); } -CommunicatorTracePrinter::~CommunicatorTracePrinter() +ProcessCommunicatorTracePrinter::~ProcessCommunicatorTracePrinter() { // flush stdout WriteCurrentString(false); @@ -24,7 +24,7 @@ CommunicatorTracePrinter::~CommunicatorTracePrinter() WriteCurrentString(true); } -void CommunicatorTracePrinter::Pump() +void ProcessCommunicatorTracePrinter::Pump() { if (m_communicator->IsValid()) { @@ -42,7 +42,7 @@ void CommunicatorTracePrinter::Pump() } } -void CommunicatorTracePrinter::ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr) +void ProcessCommunicatorTracePrinter::ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr) { if (readSize > AZ_ARRAY_SIZE(m_streamBuffer)) { @@ -67,7 +67,7 @@ void CommunicatorTracePrinter::ParseDataBuffer(AZ::u32 readSize, bool isFromStdE } } -void CommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) +void ProcessCommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) { AZStd::string& bufferToUse = isFromStdErr ? m_errorStringBeingConcatenated : m_stringBeingConcatenated; diff --git a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h similarity index 54% rename from Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h rename to Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h index c2e4da32af..8b84c4c28d 100644 --- a/Code/Tools/AssetProcessor/native/utilities/CommunicatorTracePrinter.h +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h @@ -10,20 +10,21 @@ #include -//! CommunicatorTracePrinter listens to stderr and stdout of a running process and writes its output to the AZ_Trace system +//! ProcessCommunicatorTracePrinter listens to stderr and stdout of a running process and writes its output to the AZ_Trace system //! Importantly, it does not do any blocking operations. -class CommunicatorTracePrinter +class ProcessCommunicatorTracePrinter { public: - CommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window); - ~CommunicatorTracePrinter(); + ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window); + ~ProcessCommunicatorTracePrinter(); - // call this periodically to drain the buffers and write them. + // Call this periodically to drain the buffers and write them. void Pump(); - // drains the buffer into the string thats being built, then traces the string when it hits a newline. + // Drains the buffer into the string that's being built, then traces the string when it hits a newline. void ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr); + // Prints the current buffer to AZ_Error or AZ_TracePrintf so that it can be picked up by AZ::Debug::Trace void WriteCurrentString(bool isFromStdError); private: diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index e03d166cfc..232975d7c8 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -274,6 +274,8 @@ set(FILES Process/ProcessWatcher.cpp Process/ProcessWatcher.h Process/ProcessCommon_fwd.h + Process/ProcessCommunicatorTracePrinter.cpp + Process/ProcessCommunicatorTracePrinter.h ProjectManager/ProjectManager.h ProjectManager/ProjectManager.cpp Render/GameIntersectorComponent.h diff --git a/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake b/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake index 0c1347517f..056b88beb2 100644 --- a/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake +++ b/Code/Tools/AssetProcessor/assetprocessor_static_files.cmake @@ -89,8 +89,6 @@ set(FILES native/utilities/BuilderManager.inl native/utilities/ByteArrayStream.cpp native/utilities/ByteArrayStream.h - native/utilities/CommunicatorTracePrinter.cpp - native/utilities/CommunicatorTracePrinter.h native/utilities/IniConfiguration.cpp native/utilities/IniConfiguration.h native/utilities/JobDiagnosticTracker.cpp diff --git a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp index 27210685fc..c463f2320e 100644 --- a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp +++ b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -31,7 +30,6 @@ #include "native/utilities/assetUtils.h" #include "native/utilities/AssetBuilderInfo.h" -#include "native/utilities/CommunicatorTracePrinter.h" #include diff --git a/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp b/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp index 4e0bc7e434..2c322da2f7 100644 --- a/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp @@ -1479,7 +1479,7 @@ bool ApplicationManagerBase::WaitForBuilderExit(AzFramework::ProcessWatcher* pro AZ::u32 exitCode = 0; bool finishedOK = false; QElapsedTimer ticker; - CommunicatorTracePrinter tracer(processWatcher->GetCommunicator(), "AssetBuilder"); + ProcessCommunicatorTracePrinter tracer(processWatcher->GetCommunicator(), "AssetBuilder"); ticker.start(); diff --git a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp index 751afc1a5d..aa462f7590 100644 --- a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp @@ -164,7 +164,7 @@ namespace AssetProcessor return false; } - m_tracePrinter = AZStd::make_unique(m_processWatcher->GetCommunicator(), "AssetBuilder"); + m_tracePrinter = AZStd::make_unique(m_processWatcher->GetCommunicator(), "AssetBuilder"); return WaitForConnection(); } diff --git a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h index 657e4c7788..440f0b3709 100644 --- a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h +++ b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.h @@ -10,11 +10,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include // used in the inl file. @@ -127,7 +127,7 @@ namespace AssetProcessor AZStd::unique_ptr m_processWatcher = nullptr; //! Optional communicator, only available if we have a process watcher - AZStd::unique_ptr m_tracePrinter = nullptr; + AZStd::unique_ptr m_tracePrinter = nullptr; const AssetUtilities::QuitListener& m_quitListener; }; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 11aca101b3..7d6a684b6b 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -6,6 +6,8 @@ * */ +#include "AzFramework/Process/ProcessCommunicator.h" + #include #include #include @@ -133,6 +135,7 @@ namespace Multiplayer AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); AzFramework::GameEntityContextEventBus::Handler::BusDisconnect(); MultiplayerEditorServerRequestBus::Handler::BusDisconnect(); + AZ::TickBus::Handler::BusDisconnect(); } void MultiplayerEditorSystemComponent::NotifyRegisterViews() @@ -157,12 +160,21 @@ namespace Multiplayer [[fallthrough]]; case eNotify_OnEndGameMode: // Kill the configured server if it's active - if (m_serverProcess) + if (m_serverProcessWatcher) { - m_serverProcess->TerminateProcess(0); - m_serverProcess = nullptr; + m_serverProcessWatcher->TerminateProcess(0); + if (m_serverProcessTracePrinter) + { + m_serverProcessTracePrinter->Pump(); + m_serverProcessTracePrinter->WriteCurrentString(true); + m_serverProcessTracePrinter->WriteCurrentString(false); + } + m_serverProcessWatcher = nullptr; + m_serverProcessTracePrinter = nullptr; } + AZ::TickBus::Handler::BusDisconnect(); + if (INetworkInterface* editorNetworkInterface = AZ::Interface::Get()->RetrieveNetworkInterface(AZ::Name(MpEditorInterfaceName))) { editorNetworkInterface->Disconnect(m_editorConnId, AzNetworking::DisconnectReason::TerminatedByClient); @@ -220,7 +232,7 @@ namespace Multiplayer // Launch the Server AzFramework::ProcessWatcher* outProcess = AzFramework::ProcessWatcher::LaunchProcess( - processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); + processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT); AZ_Error( "MultiplayerEditor", processLaunchInfo.m_launchResult != AzFramework::ProcessLauncher::ProcessLaunchResult::PLR_MissingFile, @@ -389,4 +401,10 @@ namespace Multiplayer { return PyIsInGameMode(); } + + void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) + { + m_serverProcessTracePrinter->Pump(); + } + } diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h index 77b41a5dc4..330a2c9d81 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h @@ -13,14 +13,12 @@ #include #include -#include - #include #include #include -#include #include #include +#include #include namespace AzNetworking @@ -52,6 +50,7 @@ namespace Multiplayer , private AzToolsFramework::EditorEvents::Bus::Handler , private IEditorNotifyListener , private MultiplayerEditorServerRequestBus::Handler + , private AZ::TickBus::Handler { public: AZ_COMPONENT(MultiplayerEditorSystemComponent, "{9F335CC0-5574-4AD3-A2D8-2FAEF356946C}"); @@ -101,8 +100,14 @@ namespace Multiplayer void SendEditorServerLevelDataPacket(AzNetworking::IConnection* connection) override; //! @} + //! AZ::TickBus::Handler + //! @{ + void OnTick(float, AZ::ScriptTimePoint) override; + //! @} + IEditor* m_editor = nullptr; - AzFramework::ProcessWatcher* m_serverProcess = nullptr; + AzFramework::ProcessWatcher* m_serverProcessWatcher = nullptr; + AZStd::unique_ptr m_serverProcessTracePrinter = nullptr; AzNetworking::ConnectionId m_editorConnId; ServerAcceptanceReceivedEvent::Handler m_serverAcceptanceReceivedHandler; diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 6df5e4611f..54f5534864 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -1134,6 +1134,7 @@ namespace Multiplayer AZStd::to_lower(sv_defaultPlayerSpawnAssetLowerCase.begin(), sv_defaultPlayerSpawnAssetLowerCase.end()); PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast(sv_defaultPlayerSpawnAssetLowerCase).c_str())); INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity(), Multiplayer::AutoActivate::DoNotActivate); + AZ_TracePrintf("MultiplayerSystemComponent", "Server spawned the default player: %s", sv_defaultPlayerSpawnAssetLowerCase.c_str()) for (NetworkEntityHandle subEntity : entityList) { From d6803d800b1521456cfbdbcaacf0c9883dbd4083 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 10 Nov 2021 19:37:11 -0800 Subject: [PATCH 02/72] Externed cvars dont get registered with setreg (not sure why). Updating sv_defaultPlayer to grab the variable via console string lookup instead so the proper value is gathered Signed-off-by: Gene Walters --- .../Editor/MultiplayerEditorSystemComponent.cpp | 16 ++++++++++++++-- .../Code/Source/MultiplayerSystemComponent.h | 2 -- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 7d6a684b6b..c5f3d0e226 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -219,12 +219,22 @@ namespace Multiplayer { server_rhi = static_cast(editorsv_rhi_override); } + + const auto console = AZ::Interface::Get(); + AZ::CVarFixedString sv_defaultPlayerSpawnAsset; + + if (console->GetCvarValue("sv_defaultPlayerSpawnAsset", sv_defaultPlayerSpawnAsset) != AZ::GetValueResult::Success) + { + AZ_Assert( false, + "MultiplayerEditorSystemComponent::LaunchEditorServer failed! Could not find the sv_defaultPlayerSpawnAsset cvar; the editor-server " + "will fall back to using some other default player! Please update this code to use a valid cvar!") + } processLaunchInfo.m_commandlineParameters = AZStd::string::format( R"("%s" --project-path "%s" --editorsv_isDedicated true --sv_defaultPlayerSpawnAsset "%s" --rhi "%s")", serverPath.c_str(), AZ::Utils::GetProjectPath().c_str(), - static_cast(sv_defaultPlayerSpawnAsset).c_str(), + sv_defaultPlayerSpawnAsset.c_str(), server_rhi.GetCStr() ); processLaunchInfo.m_showWindow = true; @@ -292,7 +302,9 @@ namespace Multiplayer editorNetworkInterface->Listen(editorsv_port); // Launch the editor-server - m_serverProcess = LaunchEditorServer(); + m_serverProcessWatcher = LaunchEditorServer(); + m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); + AZ::TickBus::Handler::BusConnect(); } else { diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index 87d084d5bc..0281916de2 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -37,8 +37,6 @@ namespace AzNetworking namespace Multiplayer { - AZ_CVAR_EXTERNED(AZ::CVarFixedString, sv_defaultPlayerSpawnAsset); - //! Multiplayer system component wraps the bridging logic between the game and transport layer. class MultiplayerSystemComponent final : public AZ::Component From 4d161f42dfe65d483c50ee16a3713186dd8c8cf8 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 15 Nov 2021 12:37:21 -0800 Subject: [PATCH 03/72] WiP. fwrites are being stopped by AZCoreLogSink; need a long term solution to work around this... Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 7 +++++-- .../AzFramework/Process/ProcessCommunicator_Win.cpp | 2 ++ .../Source/Editor/MultiplayerEditorSystemComponent.cpp | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index b9e4003500..d393018a92 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -26,6 +26,7 @@ #include #include #include +#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AZ::Debug { @@ -523,10 +524,10 @@ namespace AZ::Debug EBUS_EVENT(TraceMessageDrillerBus, OnOutput, window, message); TraceMessageResult result; EBUS_EVENT_RESULT(result, TraceMessageBus, OnOutput, window, message); - if (result.m_value) + /* if (result.m_value) { return; - } + }*/ } // printf on Windows platforms seem to have a buffer length limit of 4096 characters @@ -537,6 +538,7 @@ namespace AZ::Debug fwrite(windowView.data(), 1, windowView.size(), stdout); fwrite(windowMessageSeparator.data(), 1, windowMessageSeparator.size(), stdout); fwrite(messageView.data(), 1, messageView.size(), stdout); + fwrite("\n\r", 1, 2, stdout); } //========================================================================= @@ -612,3 +614,4 @@ namespace AZ::Debug } } } // namspace AZ::Debug +#pragma optimize("", on) diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp index c4629ccf2c..9c7bbfac15 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp @@ -8,6 +8,7 @@ #include +#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AzFramework { @@ -274,3 +275,4 @@ namespace AzFramework } } // namespace AzToolsFramework +#pragma optimize("", on) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 669393e31e..d75fbcbc70 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -420,6 +420,8 @@ namespace Multiplayer void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) { + AZ_TracePrintf("MultiplayerEditorSystemComponent", "OnTick Pump"); + m_serverProcessTracePrinter->Pump(); } From e1ace4a8f63244f16a03b82a9ffd56586ec6e859 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 15 Nov 2021 12:37:52 -0800 Subject: [PATCH 04/72] WiP. fwrites are being stopped by AZCoreLogSink; need a long term solution to work around this... Signed-off-by: Gene Walters --- .../AzFramework/Process/ProcessCommunicatorTracePrinter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp index 8f3e45bec5..ab9f7c8103 100644 --- a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp @@ -8,6 +8,8 @@ #include "ProcessCommunicatorTracePrinter.h" +#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want + ProcessCommunicatorTracePrinter::ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : m_communicator(communicator), m_window(window) @@ -84,3 +86,4 @@ void ProcessCommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) bufferToUse.clear(); } } +#pragma optimize("", on) From 02590a1766d0613a12ec3be95f10fd8f7057c402 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Sat, 20 Nov 2021 14:48:48 -0800 Subject: [PATCH 05/72] AzCoreLogSink will check if it's running in an editor-server and will allow stdouts Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 4 ++-- Code/Legacy/CrySystem/AZCoreLogSink.h | 11 +++++++++++ .../Editor/MultiplayerEditorSystemComponent.cpp | 2 -- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index 78dbf3c979..d8a39deebb 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -535,10 +535,10 @@ namespace AZ::Debug EBUS_EVENT(TraceMessageDrillerBus, OnOutput, window, message); TraceMessageResult result; EBUS_EVENT_RESULT(result, TraceMessageBus, OnOutput, window, message); - /* if (result.m_value) + if (result.m_value) { return; - }*/ + } } RawOutput(window, message); diff --git a/Code/Legacy/CrySystem/AZCoreLogSink.h b/Code/Legacy/CrySystem/AZCoreLogSink.h index 1b09c3198d..605367f418 100644 --- a/Code/Legacy/CrySystem/AZCoreLogSink.h +++ b/Code/Legacy/CrySystem/AZCoreLogSink.h @@ -180,6 +180,17 @@ public: CryLog("(%s) - %s", window, message); } + // If this is an editor-server, then allow the default trace behavior (fwrites to stdout) to occur + // The editor will being listening to the stdout of this server + if (const auto console = AZ::Interface::Get()) + { + bool editorsv_isDedicated = false; + if (console->GetCvarValue("editorsv_isDedicated", editorsv_isDedicated) == AZ::GetValueResult::Success) + { + return !editorsv_isDedicated; + } + } + return true; // suppress default AzCore behavior. } diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index d75fbcbc70..669393e31e 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -420,8 +420,6 @@ namespace Multiplayer void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) { - AZ_TracePrintf("MultiplayerEditorSystemComponent", "OnTick Pump"); - m_serverProcessTracePrinter->Pump(); } From 0bd86cf0a4f7bf3a2f5a2bec63f420872a71d558 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Sat, 20 Nov 2021 14:58:09 -0800 Subject: [PATCH 06/72] small edit: removing pragma optimize offs Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 2 -- .../AzFramework/Process/ProcessCommunicatorTracePrinter.cpp | 2 -- .../Windows/AzFramework/Process/ProcessCommunicator_Win.cpp | 2 -- Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp | 1 - 4 files changed, 7 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index d8a39deebb..e2f0c6b29c 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -26,7 +26,6 @@ #include #include #include -#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AZ::Debug { @@ -645,4 +644,3 @@ namespace AZ::Debug } } } // namspace AZ::Debug -#pragma optimize("", on) diff --git a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp index ab9f7c8103..51674bb32c 100644 --- a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.cpp @@ -8,7 +8,6 @@ #include "ProcessCommunicatorTracePrinter.h" -#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want ProcessCommunicatorTracePrinter::ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window) : m_communicator(communicator), @@ -86,4 +85,3 @@ void ProcessCommunicatorTracePrinter::WriteCurrentString(bool isFromStdErr) bufferToUse.clear(); } } -#pragma optimize("", on) diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp index 9c7bbfac15..c4629ccf2c 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Process/ProcessCommunicator_Win.cpp @@ -8,7 +8,6 @@ #include -#pragma optimize("", off) //< remember to place this after the #includes so that you only optimize the code you want namespace AzFramework { @@ -275,4 +274,3 @@ namespace AzFramework } } // namespace AzToolsFramework -#pragma optimize("", on) diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 8eb6d2d777..503a8128b0 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -1137,7 +1137,6 @@ namespace Multiplayer AZStd::to_lower(sv_defaultPlayerSpawnAssetLowerCase.begin(), sv_defaultPlayerSpawnAssetLowerCase.end()); PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast(sv_defaultPlayerSpawnAssetLowerCase).c_str())); INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity(), Multiplayer::AutoActivate::DoNotActivate); - AZ_TracePrintf("MultiplayerSystemComponent", "Server spawned the default player: %s", sv_defaultPlayerSpawnAssetLowerCase.c_str()) for (NetworkEntityHandle subEntity : entityList) { From ff862a2f206aa2449e4c7ee77d2914b091103086 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 22 Nov 2021 18:56:48 -0800 Subject: [PATCH 07/72] Fix memory leak of ProcessWatcher Signed-off-by: Gene Walters --- .../Editor/MultiplayerEditorSystemComponent.cpp | 13 +++++++++---- .../Editor/MultiplayerEditorSystemComponent.h | 6 ++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 669393e31e..7cc6fbc1b5 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -193,7 +193,7 @@ namespace Multiplayer } } - AzFramework::ProcessWatcher* LaunchEditorServer() + void MultiplayerEditorSystemComponent::LaunchEditorServer() { // Assemble the server's path AZ::CVarFixedString serverProcess = editorsv_process; @@ -248,7 +248,13 @@ namespace Multiplayer "MultiplayerEditor", processLaunchInfo.m_launchResult != AzFramework::ProcessLauncher::ProcessLaunchResult::PLR_MissingFile, "LaunchEditorServer failed! The ServerLauncher binary is missing! (%s) Please build server launcher.", serverPath.c_str()) - return outProcess; + // Stop the previous server if one exists + if (m_serverProcessWatcher) + { + m_serverProcessWatcher->TerminateProcess(0); + } + m_serverProcessWatcher.reset(outProcess); + m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); } void MultiplayerEditorSystemComponent::OnGameEntitiesStarted() @@ -308,8 +314,7 @@ namespace Multiplayer editorNetworkInterface->Listen(editorsv_port); // Launch the editor-server - m_serverProcessWatcher = LaunchEditorServer(); - m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); + LaunchEditorServer(); AZ::TickBus::Handler::BusConnect(); } else diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h index 330a2c9d81..5e49f8f08d 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h @@ -83,7 +83,9 @@ namespace Multiplayer bool IsInGameMode() override; //! @} - private: + private: + void LaunchEditorServer(); + //! EditorEvents::Handler overrides //! @{ void OnEditorNotifyEvent(EEditorNotifyEvent event) override; @@ -106,7 +108,7 @@ namespace Multiplayer //! @} IEditor* m_editor = nullptr; - AzFramework::ProcessWatcher* m_serverProcessWatcher = nullptr; + AZStd::unique_ptr m_serverProcessWatcher = nullptr; AZStd::unique_ptr m_serverProcessTracePrinter = nullptr; AzNetworking::ConnectionId m_editorConnId; From 33e44a4813b5beb109225085ed05e0d35e5dfa11 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 23 Nov 2021 09:27:50 -0800 Subject: [PATCH 08/72] revert rawoutput function. we'll update any of the logs we care about to include newlines Signed-off-by: Gene Walters --- Code/Framework/AzCore/AzCore/Debug/Trace.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp index e2f0c6b29c..2c2b8215c0 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.cpp @@ -558,7 +558,6 @@ namespace AZ::Debug fwrite(windowView.data(), 1, windowView.size(), stdout); fwrite(windowMessageSeparator.data(), 1, windowMessageSeparator.size(), stdout); fwrite(messageView.data(), 1, messageView.size(), stdout); - fwrite("\n\r", 1, 2, stdout); } //========================================================================= From 91060efd461f4f692435f4990ef11c92c328cec7 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Wed, 24 Nov 2021 10:56:22 -0800 Subject: [PATCH 09/72] add a LDR color Grading LUT property set step as part of the p0 test for the Display Mapper component Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Atom/atom_utils/atom_constants.py | 1 + ...AtomEditorComponents_DisplayMapperAdded.py | 35 ++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index ef9e90802b..ebc8a932d6 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -154,6 +154,7 @@ class AtomComponentProperties: """ properties = { 'name': 'Display Mapper', + 'LDR color Grading LUT': 'Controller|Configuration|LDR color Grading LUT', } return properties[property] diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py index f8881bfa2a..e2e432364d 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py @@ -5,6 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ + class Tests: camera_creation = ( "Camera Entity successfully created", @@ -39,6 +40,9 @@ class Tests: is_hidden = ( "Entity is hidden", "Entity was not hidden") + ldr_color_grading_lut = ( + "LDR color Grading LUT asset set", + "LDR color Grading LUT asset could not be set") entity_deleted = ( "Entity deleted", "Entity was not deleted") @@ -71,16 +75,19 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity(): 5) Enter/Exit game mode. 6) Test IsHidden. 7) Test IsVisible. - 8) Delete Display Mapper entity. - 9) UNDO deletion. - 10) REDO deletion. - 11) Look for errors and asserts. + 8) Set LDR color Grading LUT asset. + 9) Delete Display Mapper entity. + 10) UNDO deletion. + 11) REDO deletion. + 12) Look for errors and asserts. :return: None """ + import os import azlmbr.legacy.general as general + from editor_python_test_tools.asset_utils import Asset from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.utils import Report, Tracer, TestHelper from Atom.atom_utils.atom_constants import AtomComponentProperties @@ -97,7 +104,7 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity(): Report.critical_result(Tests.display_mapper_creation, display_mapper_entity.exists()) # 2. Add Display Mapper component to Display Mapper entity. - display_mapper_entity.add_component(AtomComponentProperties.display_mapper()) + display_mapper_component = display_mapper_entity.add_component(AtomComponentProperties.display_mapper()) Report.critical_result( Tests.display_mapper_component, display_mapper_entity.has_component(AtomComponentProperties.display_mapper())) @@ -140,19 +147,29 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity(): general.idle_wait_frames(1) Report.result(Tests.is_visible, display_mapper_entity.is_visible() is True) - # 8. Delete Display Mapper entity. + # 8. Set LDR color Grading LUT asset. + display_mapper_asset_path = os.path.join("TestData", "test.lightingpreset.azasset") + display_mapper_asset = Asset.find_asset_by_path(display_mapper_asset_path, False) + display_mapper_component.set_component_property_value( + AtomComponentProperties.display_mapper("LDR color Grading LUT"), display_mapper_asset.id) + Report.result( + Tests.ldr_color_grading_lut, + display_mapper_component.get_component_property_value( + AtomComponentProperties.display_mapper("LDR color Grading LUT")) == display_mapper_asset.id) + + # 9. Delete Display Mapper entity. display_mapper_entity.delete() Report.result(Tests.entity_deleted, not display_mapper_entity.exists()) - # 9. UNDO deletion. + # 10. UNDO deletion. general.undo() Report.result(Tests.deletion_undo, display_mapper_entity.exists()) - # 10. REDO deletion. + # 11. REDO deletion. general.redo() Report.result(Tests.deletion_redo, not display_mapper_entity.exists()) - # 11. Look for errors and asserts. + # 12. Look for errors and asserts. TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) for error_info in error_tracer.errors: Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") From 77e3dd786d30d14e45ccc847c999f87d75c815ec Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 24 Nov 2021 16:05:53 -0800 Subject: [PATCH 10/72] Instead of AZCoreLogSink pulling a cvar, we'll check if we're running an editor-server on SystemInit Signed-off-by: Gene Walters --- Code/Legacy/CrySystem/AZCoreLogSink.h | 19 +++++-------------- Code/Legacy/CrySystem/SystemInit.cpp | 13 ++++++++++++- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Code/Legacy/CrySystem/AZCoreLogSink.h b/Code/Legacy/CrySystem/AZCoreLogSink.h index 605367f418..39a6131262 100644 --- a/Code/Legacy/CrySystem/AZCoreLogSink.h +++ b/Code/Legacy/CrySystem/AZCoreLogSink.h @@ -36,9 +36,10 @@ public: Disconnect(); } - inline static void Connect() + inline static void Connect(bool suppressSystemOutput) { GetInstance().m_ignoredAsserts = new IgnoredAssertMap(); + GetInstance().m_suppressSystemOutput = suppressSystemOutput; GetInstance().BusConnect(); } @@ -179,23 +180,13 @@ public: { CryLog("(%s) - %s", window, message); } - - // If this is an editor-server, then allow the default trace behavior (fwrites to stdout) to occur - // The editor will being listening to the stdout of this server - if (const auto console = AZ::Interface::Get()) - { - bool editorsv_isDedicated = false; - if (console->GetCvarValue("editorsv_isDedicated", editorsv_isDedicated) == AZ::GetValueResult::Success) - { - return !editorsv_isDedicated; - } - } - - return true; // suppress default AzCore behavior. + + return m_suppressSystemOutput; } private: using IgnoredAssertMap = AZStd::unordered_map, AZStd::equal_to, AZ::OSStdAllocator>; IgnoredAssertMap* m_ignoredAsserts; + bool m_suppressSystemOutput = true; }; diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp index c5039f57e9..6f550fcac6 100644 --- a/Code/Legacy/CrySystem/SystemInit.cpp +++ b/Code/Legacy/CrySystem/SystemInit.cpp @@ -737,7 +737,18 @@ bool CSystem::Init(const SSystemInitParams& startupParams) m_pCmdLine = new CCmdLine(startupParams.szSystemCmdLine); - AZCoreLogSink::Connect(); + // Init AZCoreLogSink. Don't suppress system output if we're running as an editor-server + bool suppressSystemOutput = true; + if (const ICmdLineArg* isEditorServerArg = m_pCmdLine->FindArg(eCLAT_Pre, "editorsv_isDedicated")) + { + AZ::CVarFixedString lowercaseValue(isEditorServerArg->GetValue()); + AZStd::to_lower(lowercaseValue.begin(), lowercaseValue.end()); + if (lowercaseValue == "true") + { + suppressSystemOutput = false; + } + } + AZCoreLogSink::Connect(suppressSystemOutput); // Registers all AZ Console Variables functors specified within CrySystem if (auto azConsole = AZ::Interface::Get(); azConsole) From 34542337b9345786ef79afd61756ad42f143ca49 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Wed, 24 Nov 2021 22:34:04 -0800 Subject: [PATCH 11/72] Remove dependency of ScriptCanvasPhysics on ScriptCanvas gem to fix runtime dependency conflict Signed-off-by: amzn-sj --- Gems/ScriptCanvas/Code/CMakeLists.txt | 16 + .../Code/scriptcanvasgem_headers.cmake | 378 ++++++++++++++++++ Gems/ScriptCanvasPhysics/Code/CMakeLists.txt | 2 +- 3 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake diff --git a/Gems/ScriptCanvas/Code/CMakeLists.txt b/Gems/ScriptCanvas/Code/CMakeLists.txt index c126d343ed..25b0099e88 100644 --- a/Gems/ScriptCanvas/Code/CMakeLists.txt +++ b/Gems/ScriptCanvas/Code/CMakeLists.txt @@ -89,6 +89,22 @@ ly_add_target( Gem::ScriptCanvasDebugger ) +ly_add_target( + NAME ScriptCanvasAPI HEADERONLY + NAMESPACE Gem + FILES_CMAKE + scriptcanvasgem_headers.cmake + COMPILE_DEFINITIONS + INTERFACE + SCRIPTCANVAS_ERRORS_ENABLED + ${SCRIPT_CANVAS_COMMON_DEFINES} + INCLUDE_DIRECTORIES + INTERFACE + . + Include + Include/ScriptCanvas +) + ly_add_target( NAME ScriptCanvas ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} NAMESPACE Gem diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake new file mode 100644 index 0000000000..7dfe9653b6 --- /dev/null +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_headers.cmake @@ -0,0 +1,378 @@ +# +# 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 +# +# + +set(FILES + Include/ScriptCanvas/SystemComponent.h + Include/ScriptCanvas/ScriptCanvasGem.h + Include/ScriptCanvas/Asset/AssetDescription.h + Include/ScriptCanvas/Asset/AssetRegistry.h + Include/ScriptCanvas/Asset/AssetRegistryBus.h + Include/ScriptCanvas/Asset/ExecutionLogAsset.h + Include/ScriptCanvas/Asset/ExecutionLogAssetBus.h + Include/ScriptCanvas/Asset/RuntimeAsset.h + Include/ScriptCanvas/Asset/RuntimeAssetHandler.h + Include/ScriptCanvas/Asset/ScriptCanvasAssetBase.h + Include/ScriptCanvas/Asset/ScriptCanvasAssetData.h + Include/ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h + Include/ScriptCanvas/Core/ScriptCanvasBus.h + Include/ScriptCanvas/Core/ExecutionNotificationsBus.h + Include/ScriptCanvas/Core/GraphBus.h + Include/ScriptCanvas/Core/NodeBus.h + Include/ScriptCanvas/Core/EBusNodeBus.h + Include/ScriptCanvas/Core/NodelingBus.h + Include/ScriptCanvas/Core/ContractBus.h + Include/ScriptCanvas/Core/Attributes.h + Include/ScriptCanvas/Core/Connection.h + Include/ScriptCanvas/Core/ConnectionBus.h + Include/ScriptCanvas/Core/Contract.h + Include/ScriptCanvas/Core/Contracts.h + Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.h + Include/ScriptCanvas/Core/Contracts/RestrictedNodeContract.h + Include/ScriptCanvas/Core/Core.h + Include/ScriptCanvas/Core/Datum.h + Include/ScriptCanvas/Core/DatumBus.h + Include/ScriptCanvas/Core/EBusHandler.h + Include/ScriptCanvas/Core/Endpoint.h + Include/ScriptCanvas/Core/Graph.h + Include/ScriptCanvas/Core/GraphData.h + Include/ScriptCanvas/Core/GraphScopedTypes.h + Include/ScriptCanvas/Core/MethodConfiguration.h + Include/ScriptCanvas/Core/ModifiableDatumView.h + Include/ScriptCanvas/Core/Node.h + Include/ScriptCanvas/Core/Nodeable.h + Include/ScriptCanvas/Core/NodeableNode.h + Include/ScriptCanvas/Core/NodeableNodeOverloaded.h + Include/ScriptCanvas/Core/NodeFunctionGeneric.h + Include/ScriptCanvas/Core/SerializationListener.h + Include/ScriptCanvas/Core/Slot.h + Include/ScriptCanvas/Core/SlotConfigurationDefaults.h + Include/ScriptCanvas/Core/SlotConfigurations.h + Include/ScriptCanvas/Core/SlotExecutionMap.h + Include/ScriptCanvas/Core/SlotMetadata.h + Include/ScriptCanvas/Core/SlotNames.h + Include/ScriptCanvas/Core/SubgraphInterface.h + Include/ScriptCanvas/Core/SubgraphInterfaceUtility.h + Include/ScriptCanvas/Translation/AbstractModelTranslator.h + Include/ScriptCanvas/Translation/Configuration.h + Include/ScriptCanvas/Translation/GraphToCPlusPlus.h + Include/ScriptCanvas/Translation/GraphToLua.h + Include/ScriptCanvas/Translation/GraphToLuaUtility.h + Include/ScriptCanvas/Translation/GraphToX.h + Include/ScriptCanvas/Translation/Translation.h + Include/ScriptCanvas/Translation/TranslationContext.h + Include/ScriptCanvas/Translation/TranslationResult.h + Include/ScriptCanvas/Translation/TranslationUtilities.h + Include/ScriptCanvas/PerformanceStatistician.h + Include/ScriptCanvas/PerformanceStatisticsBus.h + Include/ScriptCanvas/PerformanceTracker.h + Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja + Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja + Include/ScriptCanvas/CodeGen/NodeableCodegen.h + Include/ScriptCanvas/Core/Contracts/ConnectionLimitContract.h + Include/ScriptCanvas/Core/Contracts/ContractRTTI.h + Include/ScriptCanvas/Core/Contracts/DisallowReentrantExecutionContract.h + Include/ScriptCanvas/Core/Contracts/DisplayGroupConnectedSlotLimitContract.h + Include/ScriptCanvas/Core/Contracts/DynamicTypeContract.h + Include/ScriptCanvas/Core/Contracts/IsReferenceTypeContract.h + Include/ScriptCanvas/Core/Contracts/MathOperatorContract.h + Include/ScriptCanvas/Core/Contracts/SlotTypeContract.h + Include/ScriptCanvas/Core/Contracts/SupportsMethodContract.h + Include/ScriptCanvas/Core/Contracts/TypeContract.h + Include/ScriptCanvas/Data/BehaviorContextObject.h + Include/ScriptCanvas/Data/BehaviorContextObjectPtr.h + Include/ScriptCanvas/Data/Data.h + Include/ScriptCanvas/Data/DataMacros.h + Include/ScriptCanvas/Data/DataRegistry.h + Include/ScriptCanvas/Data/NumericData.h + Include/ScriptCanvas/Deprecated/VariableDatumBase.h + Include/ScriptCanvas/Deprecated/VariableDatum.h + Include/ScriptCanvas/Deprecated/VariableHelpers.h + Include/ScriptCanvas/Execution/ErrorBus.h + Include/ScriptCanvas/Execution/ExecutionBus.h + Include/ScriptCanvas/Execution/ExecutionContext.h + Include/ScriptCanvas/Execution/ExecutionObjectCloning.h + Include/ScriptCanvas/Execution/ExecutionPerformanceTimer.h + Include/ScriptCanvas/Execution/ExecutionState.h + Include/ScriptCanvas/Execution/ExecutionStateDeclarations.h + Include/ScriptCanvas/Execution/NativeHostDeclarations.h + Include/ScriptCanvas/Execution/NativeHostDefinitions.h + Include/ScriptCanvas/Execution/RuntimeComponent.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedCloningAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedDebugAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedOut.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedSingleton.h + Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedUtility.h + Include/ScriptCanvas/Execution/NodeableOut/NodeableOutNative.h + Include/ScriptCanvas/Grammar/AbstractCodeModel.h + Include/ScriptCanvas/Grammar/DebugMap.h + Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.h + Include/ScriptCanvas/Grammar/ParsingMetaData.h + Include/ScriptCanvas/Grammar/ParsingUtilities.h + Include/ScriptCanvas/Grammar/Primitives.h + Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h + Include/ScriptCanvas/Grammar/PrimitivesExecution.h + Include/ScriptCanvas/Grammar/SymbolNames.h + Include/ScriptCanvas/Execution/ErrorBus.h + Include/ScriptCanvas/Execution/ExecutionContext.h + Include/ScriptCanvas/Execution/ExecutionBus.h + Include/ScriptCanvas/Execution/NativeHostDeclarations.h + Include/ScriptCanvas/Execution/NativeHostDefinitions.h + Include/ScriptCanvas/Execution/RuntimeComponent.h + Include/ScriptCanvas/Internal/Nodeables/BaseTimer.h + Include/ScriptCanvas/Internal/Nodeables/BaseTimer.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.h + Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.h + Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Internal/Nodes/StringFormatted.h + Include/ScriptCanvas/Internal/Nodes/StringFormatted.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Grammar/AbstractCodeModel.h + Include/ScriptCanvas/Libraries/Libraries.h + Include/ScriptCanvas/Libraries/Core/AzEventHandler.h + Include/ScriptCanvas/Libraries/Core/AzEventHandler.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/BinaryOperator.h + Include/ScriptCanvas/Libraries/Core/CoreNodes.h + Include/ScriptCanvas/Libraries/Core/ContainerTypeReflection.h + Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h + Include/ScriptCanvas/Libraries/Core/EBusEventHandler.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/ExtractProperty.h + Include/ScriptCanvas/Libraries/Core/ExtractProperty.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h + Include/ScriptCanvas/Libraries/Core/ForEach.h + Include/ScriptCanvas/Libraries/Core/ForEach.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/FunctionBus.h + Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h + Include/ScriptCanvas/Libraries/Core/FunctionCallNode.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h + Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h + Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/GetVariable.h + Include/ScriptCanvas/Libraries/Core/GetVariable.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/Method.h + Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h + Include/ScriptCanvas/Libraries/Core/MethodUtility.h + Include/ScriptCanvas/Libraries/Core/Nodeling.h + Include/ScriptCanvas/Libraries/Core/Nodeling.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h + Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/Repeater.h + Include/ScriptCanvas/Libraries/Core/Repeater.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.h + Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Core/ScriptEventBase.h + Include/ScriptCanvas/Libraries/Core/ScriptEventBase.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/SendScriptEvent.h + Include/ScriptCanvas/Libraries/Core/SendScriptEvent.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/SetVariable.h + Include/ScriptCanvas/Libraries/Core/SetVariable.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/Start.h + Include/ScriptCanvas/Libraries/Core/Start.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Core/UnaryOperator.h + Include/ScriptCanvas/Libraries/Entity/Entity.h + Include/ScriptCanvas/Libraries/Entity/EntityNodes.h + Include/ScriptCanvas/Libraries/Entity/RotateMethod.h + Include/ScriptCanvas/Libraries/Logic/And.h + Include/ScriptCanvas/Libraries/Logic/Any.h + Include/ScriptCanvas/Libraries/Logic/Any.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Break.h + Include/ScriptCanvas/Libraries/Logic/Break.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Cycle.h + Include/ScriptCanvas/Libraries/Logic/Cycle.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Gate.h + Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Indexer.h + Include/ScriptCanvas/Libraries/Logic/Indexer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/IsNull.h + Include/ScriptCanvas/Libraries/Logic/IsNull.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Logic.h + Include/ScriptCanvas/Libraries/Logic/Multiplexer.h + Include/ScriptCanvas/Libraries/Logic/Multiplexer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Not.h + Include/ScriptCanvas/Libraries/Logic/Once.h + Include/ScriptCanvas/Libraries/Logic/Once.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Or.h + Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.h + Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/Sequencer.h + Include/ScriptCanvas/Libraries/Logic/Sequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.h + Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.h + Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Logic/While.h + Include/ScriptCanvas/Libraries/Logic/While.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Math/AABBNodes.h + Include/ScriptCanvas/Libraries/Math/ColorNodes.h + Include/ScriptCanvas/Libraries/Math/CRCNodes.h + Include/ScriptCanvas/Libraries/Math/Divide.h + Include/ScriptCanvas/Libraries/Math/Math.h + Include/ScriptCanvas/Libraries/Math/MathExpression.h + Include/ScriptCanvas/Libraries/Math/MathExpression.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Math/MathNodeUtilities.h + Include/ScriptCanvas/Libraries/Math/MathGenerics.h + Include/ScriptCanvas/Libraries/Math/MathRandom.h + Include/ScriptCanvas/Libraries/Math/Matrix3x3Nodes.h + Include/ScriptCanvas/Libraries/Math/Matrix4x4Nodes.h + Include/ScriptCanvas/Libraries/Math/Multiply.h + Include/ScriptCanvas/Libraries/Math/OBBNodes.h + Include/ScriptCanvas/Libraries/Math/PlaneNodes.h + Include/ScriptCanvas/Libraries/Math/RotationNodes.h + Include/ScriptCanvas/Libraries/Math/Subtract.h + Include/ScriptCanvas/Libraries/Math/Sum.h + Include/ScriptCanvas/Libraries/Math/TransformNodes.h + Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h + Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h + Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h + Include/ScriptCanvas/Libraries/Comparison/Comparison.h + Include/ScriptCanvas/Libraries/Comparison/ComparisonFunctions.h + Include/ScriptCanvas/Libraries/Comparison/EqualTo.h + Include/ScriptCanvas/Libraries/Comparison/NotEqualTo.h + Include/ScriptCanvas/Libraries/Comparison/Less.h + Include/ScriptCanvas/Libraries/Comparison/Greater.h + Include/ScriptCanvas/Libraries/Comparison/LessEqual.h + Include/ScriptCanvas/Libraries/Comparison/GreaterEqual.h + Include/ScriptCanvas/Libraries/Time/Time.h + Include/ScriptCanvas/Libraries/Time/Countdown.h + Include/ScriptCanvas/Libraries/Time/Countdown.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/DelayNodeable.h + Include/ScriptCanvas/Libraries/Time/DelayNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/Duration.h + Include/ScriptCanvas/Libraries/Time/Duration.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/HeartBeat.h + Include/ScriptCanvas/Libraries/Time/HeartBeat.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/Timer.h + Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.h + Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/DurationNodeable.h + Include/ScriptCanvas/Libraries/Time/DurationNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.h + Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Time/TimerNodeable.h + Include/ScriptCanvas/Libraries/Time/TimerNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/Spawning/Spawning.h + Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.h + Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.ScriptCanvasNodeable.xml + Include/ScriptCanvas/Libraries/String/Contains.h + Include/ScriptCanvas/Libraries/String/Contains.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/Format.h + Include/ScriptCanvas/Libraries/String/Format.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/Print.h + Include/ScriptCanvas/Libraries/String/Print.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/Replace.h + Include/ScriptCanvas/Libraries/String/Replace.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/String/String.h + Include/ScriptCanvas/Libraries/String/StringMethods.h + Include/ScriptCanvas/Libraries/String/StringGenerics.h + Include/ScriptCanvas/Libraries/String/Utilities.h + Include/ScriptCanvas/Libraries/String/Utilities.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.h + Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.h + Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.h + Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.h + Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.h + Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBus.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusMacros.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTesting.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestingLibrary.h + Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/Auxiliary.h + Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/AuxiliaryGenerics.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.h + Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSenderMacros.h + Include/ScriptCanvas/Libraries/Operators/Operators.h + Include/ScriptCanvas/Libraries/Operators/Operator.h + Include/ScriptCanvas/Libraries/Operators/Operator.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.h + Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.ScriptCanvasGrammar.xml + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h + Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeableNode.h + Include/ScriptCanvas/Profiler/Driller.h + Include/ScriptCanvas/Profiler/Aggregator.h + Include/ScriptCanvas/Profiler/DrillerEvents.h + Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h + Include/ScriptCanvas/Serialization/DatumSerializer.h + Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h + Include/ScriptCanvas/Data/DataTrait.h + Include/ScriptCanvas/Data/PropertyTraits.h + Include/ScriptCanvas/Data/Traits.h + Include/ScriptCanvas/Variable/VariableBus.h + Include/ScriptCanvas/Variable/GraphVariable.h + Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h + Include/ScriptCanvas/Variable/VariableCore.h + Include/ScriptCanvas/Variable/VariableData.h + Include/ScriptCanvas/Utils/DataUtils.h + Include/ScriptCanvas/Utils/NodeUtils.h + Include/ScriptCanvas/Utils/SerializationUtils.h + Include/ScriptCanvas/Utils/VersionConverters.h + Include/ScriptCanvas/Utils/BehaviorContextUtils.h +) + +set(SKIP_UNITY_BUILD_INCLUSION_FILES + Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h + Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h +) diff --git a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt index ac25c7275b..2addf3e8ca 100644 --- a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt @@ -32,7 +32,7 @@ ly_add_target( PRIVATE Legacy::CryCommon Gem::ScriptCanvasPhysics.Static - Gem::ScriptCanvas + Gem::ScriptCanvasAPI ) # By default, the above module is used by all application types, however, the module depends at runtime to ScriptCanvas From 5794fa6c9dc3c847be568e0f04f9feea0d48f4bf Mon Sep 17 00:00:00 2001 From: carlitosan <82187351+carlitosan@users.noreply.github.com> Date: Fri, 26 Nov 2021 10:17:14 -0800 Subject: [PATCH 12/72] non-handler static initialization for runtime assets is made recursive on dependencies Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com> --- .../Interpreted/ExecutionInterpretedAPI.cpp | 70 +++++++++++-------- .../Interpreted/ExecutionInterpretedAPI.h | 2 +- .../Interpreted/ExecutionStateInterpreted.cpp | 6 +- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp index bba56847ce..bbd16dfb96 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp @@ -501,43 +501,53 @@ namespace ScriptCanvas return lua_gettop(lua); } - void InitializeInterpretedStatics(const RuntimeData& runtimeData) + void InitializeInterpretedStatics(RuntimeData& runtimeData) { -#if defined(AZ_PROFILE_BUILD) || defined(AZ_DEBUG_BUILD) - Execution::InitializeFromLuaStackFunctions(const_cast(runtimeData.m_debugMap)); -#endif - AZ_WarningOnce("ScriptCanvas", !runtimeData.m_areStaticsInitialized, "ScriptCanvas runtime data already initalized"); - - if (runtimeData.RequiresStaticInitialization()) + if (!runtimeData.m_areStaticsInitialized) { - AZ::ScriptLoadResult result{}; - AZ::ScriptSystemRequestBus::BroadcastResult(result, &AZ::ScriptSystemRequests::LoadAndGetNativeContext, runtimeData.m_script, AZ::k_scriptLoadBinary, AZ::ScriptContextIds::DefaultScriptContextId); - AZ_Assert(result.status == AZ::ScriptLoadResult::Status::Initial, "ExecutionStateInterpreted script asset was valid but failed to load."); - AZ_Assert(result.lua, "Must have a default script context and a lua_State"); - AZ_Assert(lua_istable(result.lua, -1), "No run-time execution was available for this script"); + runtimeData.m_areStaticsInitialized = true; - auto lua = result.lua; - // Lua: table - lua_getfield(lua, -1, Grammar::k_InitializeStaticsName); - // Lua: table, ? - if (lua_isfunction(lua, -1)) + for (auto& dependency : runtimeData.m_requiredAssets) { - // Lua: table, function - lua_pushvalue(lua, -2); - // Lua: table, function, table - for (auto& clonerSource : runtimeData.m_cloneSources) - { - lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&clonerSource))); - } - // Lua: table, function, table, cloners... - AZ::Internal::LuaSafeCall(lua, aznumeric_caster(runtimeData.m_cloneSources.size() + 1), 0); - // Lua: table - lua_pop(lua, 1); + InitializeInterpretedStatics(dependency.Get()->GetData()); } - else + +#if defined(AZ_PROFILE_BUILD) || defined(AZ_DEBUG_BUILD) + Execution::InitializeFromLuaStackFunctions(const_cast(runtimeData.m_debugMap)); +#endif + AZ_WarningOnce("ScriptCanvas", !runtimeData.m_areStaticsInitialized, "ScriptCanvas runtime data already initalized"); + + if (runtimeData.RequiresStaticInitialization()) { + AZ::ScriptLoadResult result{}; + AZ::ScriptSystemRequestBus::BroadcastResult(result, &AZ::ScriptSystemRequests::LoadAndGetNativeContext, runtimeData.m_script, AZ::k_scriptLoadBinary, AZ::ScriptContextIds::DefaultScriptContextId); + AZ_Assert(result.status == AZ::ScriptLoadResult::Status::Initial, "ExecutionStateInterpreted script asset was valid but failed to load."); + AZ_Assert(result.lua, "Must have a default script context and a lua_State"); + AZ_Assert(lua_istable(result.lua, -1), "No run-time execution was available for this script"); + + auto lua = result.lua; + // Lua: table + lua_getfield(lua, -1, Grammar::k_InitializeStaticsName); // Lua: table, ? - lua_pop(lua, 2); + if (lua_isfunction(lua, -1)) + { + // Lua: table, function + lua_pushvalue(lua, -2); + // Lua: table, function, table + for (auto& clonerSource : runtimeData.m_cloneSources) + { + lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&clonerSource))); + } + // Lua: table, function, table, cloners... + AZ::Internal::LuaSafeCall(lua, aznumeric_caster(runtimeData.m_cloneSources.size() + 1), 0); + // Lua: table + lua_pop(lua, 1); + } + else + { + // Lua: table, ? + lua_pop(lua, 2); + } } } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h index c86327bc8d..db8473a468 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h @@ -43,7 +43,7 @@ namespace ScriptCanvas void InterpretedUnloadData(RuntimeData& runtimeData); - void InitializeInterpretedStatics(const RuntimeData& runtimeData); + void InitializeInterpretedStatics(RuntimeData& runtimeData); int InitializeNodeableOutKeys(lua_State* lua); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp index a92c13ac63..0f090574b5 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp @@ -49,11 +49,7 @@ namespace ScriptCanvas , config.asset.GetId().ToString().data()); #endif - if (!runtimeAsset->GetData().m_areStaticsInitialized) - { - runtimeAsset->GetData().m_areStaticsInitialized = true; - Execution::InitializeInterpretedStatics(runtimeAsset->GetData()); - } + Execution::InitializeInterpretedStatics(runtimeAsset->GetData()); } void ExecutionStateInterpreted::ClearLuaRegistryIndex() From ba732480d07dd0f58138e449c6765c8636fcd814 Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Mon, 29 Nov 2021 12:41:33 -0800 Subject: [PATCH 13/72] Remove LyShineExample Gem's dependency on LmbrCentral and address feedback from previous PR with similar fix for ScriptCanvas Signed-off-by: amzn-sj --- Gems/LmbrCentral/Code/CMakeLists.txt | 11 + Gems/LmbrCentral/Code/lmbrcentral_files.cmake | 53 --- .../Code/lmbrcentral_headers_files.cmake | 63 +++ Gems/LyShineExamples/Code/CMakeLists.txt | 2 +- Gems/ScriptCanvas/Code/CMakeLists.txt | 5 +- .../Code/scriptcanvasgem_common_files.cmake | 365 ------------------ Gems/ScriptCanvasPhysics/Code/CMakeLists.txt | 2 +- 7 files changed, 79 insertions(+), 422 deletions(-) create mode 100644 Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake diff --git a/Gems/LmbrCentral/Code/CMakeLists.txt b/Gems/LmbrCentral/Code/CMakeLists.txt index b047a9f65e..2df0bd0632 100644 --- a/Gems/LmbrCentral/Code/CMakeLists.txt +++ b/Gems/LmbrCentral/Code/CMakeLists.txt @@ -13,6 +13,7 @@ ly_add_target( NAME LmbrCentral.Static STATIC NAMESPACE Gem FILES_CMAKE + lmbrcentral_headers_files.cmake lmbrcentral_files.cmake ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES @@ -27,6 +28,16 @@ ly_add_target( AZ::AzFramework ) +ly_add_target( + NAME LmbrCentral.API HEADERONLY + NAMESPACE Gem + FILES_CMAKE + lmbrcentral_headers_files.cmake + INCLUDE_DIRECTORIES + INTERFACE + include +) + ly_add_target( NAME LmbrCentral ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} NAMESPACE Gem diff --git a/Gems/LmbrCentral/Code/lmbrcentral_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_files.cmake index 20a366b5f7..10c9029777 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_files.cmake @@ -7,59 +7,6 @@ # set(FILES - include/LmbrCentral/Ai/NavigationComponentBus.h - include/LmbrCentral/Ai/NavigationAreaBus.h - include/LmbrCentral/Ai/NavigationSystemBus.h - include/LmbrCentral/Ai/NavigationSeedBus.h - include/LmbrCentral/Animation/AttachmentComponentBus.h - include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h - include/LmbrCentral/Audio/AudioEnvironmentComponentBus.h - include/LmbrCentral/Audio/AudioListenerComponentBus.h - include/LmbrCentral/Audio/AudioMultiPositionComponentBus.h - include/LmbrCentral/Audio/AudioPreloadComponentBus.h - include/LmbrCentral/Audio/AudioProxyComponentBus.h - include/LmbrCentral/Audio/AudioRtpcComponentBus.h - include/LmbrCentral/Audio/AudioSwitchComponentBus.h - include/LmbrCentral/Audio/AudioSystemComponentBus.h - include/LmbrCentral/Audio/AudioTriggerComponentBus.h - include/LmbrCentral/Bundling/BundlingSystemComponentBus.h - include/LmbrCentral/Geometry/GeometrySystemComponentBus.h - include/LmbrCentral/Dependency/DependencyMonitor.h - include/LmbrCentral/Dependency/DependencyMonitor.inl - include/LmbrCentral/Dependency/DependencyNotificationBus.h - include/LmbrCentral/Physics/WindVolumeRequestBus.h - include/LmbrCentral/Physics/ForceVolumeRequestBus.h - include/LmbrCentral/Physics/WaterNotificationBus.h - include/LmbrCentral/Rendering/DecalComponentBus.h - include/LmbrCentral/Rendering/LightComponentBus.h - include/LmbrCentral/Rendering/MaterialAsset.h - include/LmbrCentral/Rendering/MaterialHandle.h - include/LmbrCentral/Rendering/MeshAsset.h - include/LmbrCentral/Rendering/MeshModificationBus.h - include/LmbrCentral/Rendering/RenderNodeBus.h - include/LmbrCentral/Rendering/GiRegistrationBus.h - include/LmbrCentral/Rendering/RenderBoundsBus.h - include/LmbrCentral/Scripting/EditorTagComponentBus.h - include/LmbrCentral/Scripting/GameplayNotificationBus.h - include/LmbrCentral/Scripting/SimpleStateComponentBus.h - include/LmbrCentral/Scripting/SpawnerComponentBus.h - include/LmbrCentral/Scripting/RandomTimedSpawnerComponentBus.h - include/LmbrCentral/Scripting/TagComponentBus.h - include/LmbrCentral/Shape/EditorShapeComponentBus.h - include/LmbrCentral/Shape/ShapeComponentBus.h - include/LmbrCentral/Shape/SphereShapeComponentBus.h - include/LmbrCentral/Shape/BoxShapeComponentBus.h - include/LmbrCentral/Shape/CylinderShapeComponentBus.h - include/LmbrCentral/Shape/CapsuleShapeComponentBus.h - include/LmbrCentral/Shape/DiskShapeComponentBus.h - include/LmbrCentral/Shape/CompoundShapeComponentBus.h - include/LmbrCentral/Shape/QuadShapeComponentBus.h - include/LmbrCentral/Shape/SplineComponentBus.h - include/LmbrCentral/Shape/PolygonPrismShapeComponentBus.h - include/LmbrCentral/Shape/TubeShapeComponentBus.h - include/LmbrCentral/Shape/SplineAttribute.h - include/LmbrCentral/Shape/SplineAttribute.inl - include/LmbrCentral/Terrain/TerrainSystemRequestBus.h Source/Ai/NavigationSystemComponent.h Source/Ai/NavigationSystemComponent.cpp Source/Audio/AudioAreaEnvironmentComponent.h diff --git a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake new file mode 100644 index 0000000000..76b5412c58 --- /dev/null +++ b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake @@ -0,0 +1,63 @@ +# +# 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 +# +# + +set(FILES + include/LmbrCentral/Ai/NavigationComponentBus.h + include/LmbrCentral/Ai/NavigationAreaBus.h + include/LmbrCentral/Ai/NavigationSystemBus.h + include/LmbrCentral/Ai/NavigationSeedBus.h + include/LmbrCentral/Animation/AttachmentComponentBus.h + include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h + include/LmbrCentral/Audio/AudioEnvironmentComponentBus.h + include/LmbrCentral/Audio/AudioListenerComponentBus.h + include/LmbrCentral/Audio/AudioMultiPositionComponentBus.h + include/LmbrCentral/Audio/AudioPreloadComponentBus.h + include/LmbrCentral/Audio/AudioProxyComponentBus.h + include/LmbrCentral/Audio/AudioRtpcComponentBus.h + include/LmbrCentral/Audio/AudioSwitchComponentBus.h + include/LmbrCentral/Audio/AudioSystemComponentBus.h + include/LmbrCentral/Audio/AudioTriggerComponentBus.h + include/LmbrCentral/Bundling/BundlingSystemComponentBus.h + include/LmbrCentral/Geometry/GeometrySystemComponentBus.h + include/LmbrCentral/Dependency/DependencyMonitor.h + include/LmbrCentral/Dependency/DependencyMonitor.inl + include/LmbrCentral/Dependency/DependencyNotificationBus.h + include/LmbrCentral/Physics/WindVolumeRequestBus.h + include/LmbrCentral/Physics/ForceVolumeRequestBus.h + include/LmbrCentral/Physics/WaterNotificationBus.h + include/LmbrCentral/Rendering/DecalComponentBus.h + include/LmbrCentral/Rendering/LightComponentBus.h + include/LmbrCentral/Rendering/MaterialAsset.h + include/LmbrCentral/Rendering/MaterialHandle.h + include/LmbrCentral/Rendering/MeshAsset.h + include/LmbrCentral/Rendering/MeshModificationBus.h + include/LmbrCentral/Rendering/RenderNodeBus.h + include/LmbrCentral/Rendering/GiRegistrationBus.h + include/LmbrCentral/Rendering/RenderBoundsBus.h + include/LmbrCentral/Scripting/EditorTagComponentBus.h + include/LmbrCentral/Scripting/GameplayNotificationBus.h + include/LmbrCentral/Scripting/SimpleStateComponentBus.h + include/LmbrCentral/Scripting/SpawnerComponentBus.h + include/LmbrCentral/Scripting/RandomTimedSpawnerComponentBus.h + include/LmbrCentral/Scripting/TagComponentBus.h + include/LmbrCentral/Shape/EditorShapeComponentBus.h + include/LmbrCentral/Shape/ShapeComponentBus.h + include/LmbrCentral/Shape/SphereShapeComponentBus.h + include/LmbrCentral/Shape/BoxShapeComponentBus.h + include/LmbrCentral/Shape/CylinderShapeComponentBus.h + include/LmbrCentral/Shape/CapsuleShapeComponentBus.h + include/LmbrCentral/Shape/DiskShapeComponentBus.h + include/LmbrCentral/Shape/CompoundShapeComponentBus.h + include/LmbrCentral/Shape/QuadShapeComponentBus.h + include/LmbrCentral/Shape/SplineComponentBus.h + include/LmbrCentral/Shape/PolygonPrismShapeComponentBus.h + include/LmbrCentral/Shape/TubeShapeComponentBus.h + include/LmbrCentral/Shape/SplineAttribute.h + include/LmbrCentral/Shape/SplineAttribute.inl + include/LmbrCentral/Terrain/TerrainSystemRequestBus.h +) \ No newline at end of file diff --git a/Gems/LyShineExamples/Code/CMakeLists.txt b/Gems/LyShineExamples/Code/CMakeLists.txt index 5cd023db02..6e8f53d5cd 100644 --- a/Gems/LyShineExamples/Code/CMakeLists.txt +++ b/Gems/LyShineExamples/Code/CMakeLists.txt @@ -37,7 +37,7 @@ ly_add_target( BUILD_DEPENDENCIES PRIVATE Gem::LyShineExamples.Static - Gem::LmbrCentral + Gem::LmbrCentral.API ) # if enabled, LyShineExamples is used by all kinds of applications, however, the dependency to LmbrCentral is different diff --git a/Gems/ScriptCanvas/Code/CMakeLists.txt b/Gems/ScriptCanvas/Code/CMakeLists.txt index 25b0099e88..f83f0d3593 100644 --- a/Gems/ScriptCanvas/Code/CMakeLists.txt +++ b/Gems/ScriptCanvas/Code/CMakeLists.txt @@ -57,6 +57,7 @@ ly_add_target( NAME ScriptCanvas.Static STATIC NAMESPACE Gem FILES_CMAKE + scriptcanvasgem_headers.cmake scriptcanvasgem_common_files.cmake scriptcanvasgem_runtime_asset_files.cmake INCLUDE_DIRECTORIES @@ -90,7 +91,7 @@ ly_add_target( ) ly_add_target( - NAME ScriptCanvasAPI HEADERONLY + NAME ScriptCanvas.API HEADERONLY NAMESPACE Gem FILES_CMAKE scriptcanvasgem_headers.cmake @@ -102,7 +103,7 @@ ly_add_target( INTERFACE . Include - Include/ScriptCanvas + ${SCRIPT_CANVAS_AUTOGEN_BUILD_DIR} ) ly_add_target( diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 7984340b7a..eb50f5cb51 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -7,575 +7,210 @@ # set(FILES - Include/ScriptCanvas/SystemComponent.h Source/SystemComponent.cpp Source/ScriptCanvasCommonGem.cpp Source/PerformanceStatistician.cpp Source/PerformanceTracker.cpp - Include/ScriptCanvas/ScriptCanvasGem.h - Include/ScriptCanvas/Asset/AssetDescription.h Include/ScriptCanvas/Asset/AssetRegistry.cpp - Include/ScriptCanvas/Asset/AssetRegistry.h - Include/ScriptCanvas/Asset/AssetRegistryBus.h Include/ScriptCanvas/Asset/ExecutionLogAsset.cpp - Include/ScriptCanvas/Asset/ExecutionLogAsset.h - Include/ScriptCanvas/Asset/ExecutionLogAssetBus.h Include/ScriptCanvas/Asset/RuntimeAsset.cpp - Include/ScriptCanvas/Asset/RuntimeAsset.h Include/ScriptCanvas/Asset/RuntimeAssetHandler.cpp - Include/ScriptCanvas/Asset/RuntimeAssetHandler.h - Include/ScriptCanvas/Asset/ScriptCanvasAssetBase.h - Include/ScriptCanvas/Asset/ScriptCanvasAssetData.h Include/ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.cpp - Include/ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h - Include/ScriptCanvas/Core/ScriptCanvasBus.h Include/ScriptCanvas/Core/ExecutionNotificationsBus.cpp - Include/ScriptCanvas/Core/ExecutionNotificationsBus.h - Include/ScriptCanvas/Core/GraphBus.h - Include/ScriptCanvas/Core/NodeBus.h - Include/ScriptCanvas/Core/EBusNodeBus.h - Include/ScriptCanvas/Core/NodelingBus.h - Include/ScriptCanvas/Core/ContractBus.h - Include/ScriptCanvas/Core/Attributes.h Include/ScriptCanvas/Core/Connection.cpp - Include/ScriptCanvas/Core/Connection.h - Include/ScriptCanvas/Core/ConnectionBus.h Include/ScriptCanvas/Core/Contract.cpp - Include/ScriptCanvas/Core/Contract.h - Include/ScriptCanvas/Core/Contracts.h - Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.h Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.cpp - Include/ScriptCanvas/Core/Contracts/RestrictedNodeContract.h Include/ScriptCanvas/Core/Contracts/RestrictedNodeContract.cpp Include/ScriptCanvas/Core/Core.cpp - Include/ScriptCanvas/Core/Core.h Include/ScriptCanvas/Core/Datum.cpp - Include/ScriptCanvas/Core/Datum.h - Include/ScriptCanvas/Core/DatumBus.h - Include/ScriptCanvas/Core/EBusHandler.h Include/ScriptCanvas/Core/EBusHandler.cpp Include/ScriptCanvas/Core/Endpoint.cpp - Include/ScriptCanvas/Core/Endpoint.h Include/ScriptCanvas/Core/Graph.cpp - Include/ScriptCanvas/Core/Graph.h - Include/ScriptCanvas/Core/GraphData.h Include/ScriptCanvas/Core/GraphData.cpp - Include/ScriptCanvas/Core/GraphScopedTypes.h - Include/ScriptCanvas/Core/MethodConfiguration.h Include/ScriptCanvas/Core/MethodConfiguration.cpp Include/ScriptCanvas/Core/ModifiableDatumView.cpp - Include/ScriptCanvas/Core/ModifiableDatumView.h Include/ScriptCanvas/Core/Node.cpp - Include/ScriptCanvas/Core/Node.h Include/ScriptCanvas/Core/Nodeable.cpp - Include/ScriptCanvas/Core/Nodeable.h Include/ScriptCanvas/Core/NodeableNode.cpp - Include/ScriptCanvas/Core/NodeableNode.h Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp - Include/ScriptCanvas/Core/NodeableNodeOverloaded.h - Include/ScriptCanvas/Core/NodeFunctionGeneric.h - Include/ScriptCanvas/Core/SerializationListener.h Include/ScriptCanvas/Core/Slot.cpp - Include/ScriptCanvas/Core/Slot.h - Include/ScriptCanvas/Core/SlotConfigurationDefaults.h Include/ScriptCanvas/Core/SlotConfigurations.cpp - Include/ScriptCanvas/Core/SlotConfigurations.h Include/ScriptCanvas/Core/SlotExecutionMap.cpp - Include/ScriptCanvas/Core/SlotExecutionMap.h Include/ScriptCanvas/Core/SlotMetadata.cpp - Include/ScriptCanvas/Core/SlotMetadata.h - Include/ScriptCanvas/Core/SlotNames.h - Include/ScriptCanvas/Core/SubgraphInterface.h Include/ScriptCanvas/Core/SubgraphInterface.cpp - Include/ScriptCanvas/Core/SubgraphInterfaceUtility.h Include/ScriptCanvas/Core/SubgraphInterfaceUtility.cpp - Include/ScriptCanvas/Translation/AbstractModelTranslator.h - Include/ScriptCanvas/Translation/Configuration.h Include/ScriptCanvas/Translation/GraphToCPlusPlus.cpp - Include/ScriptCanvas/Translation/GraphToCPlusPlus.h - Include/ScriptCanvas/Translation/GraphToLua.h Include/ScriptCanvas/Translation/GraphToLua.cpp - Include/ScriptCanvas/Translation/GraphToLuaUtility.h Include/ScriptCanvas/Translation/GraphToLuaUtility.cpp - Include/ScriptCanvas/Translation/GraphToX.h Include/ScriptCanvas/Translation/GraphToX.cpp - Include/ScriptCanvas/Translation/Translation.h Include/ScriptCanvas/Translation/Translation.cpp - Include/ScriptCanvas/Translation/TranslationContext.h Include/ScriptCanvas/Translation/TranslationContext.cpp - Include/ScriptCanvas/Translation/TranslationResult.h Include/ScriptCanvas/Translation/TranslationResult.cpp - Include/ScriptCanvas/Translation/TranslationUtilities.h Include/ScriptCanvas/Translation/TranslationUtilities.cpp - Include/ScriptCanvas/PerformanceStatistician.h - Include/ScriptCanvas/PerformanceStatisticsBus.h - Include/ScriptCanvas/PerformanceTracker.h - Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja - Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja - Include/ScriptCanvas/CodeGen/NodeableCodegen.h Include/ScriptCanvas/Core/Contracts/ConnectionLimitContract.cpp - Include/ScriptCanvas/Core/Contracts/ConnectionLimitContract.h Include/ScriptCanvas/Core/Contracts/ContractRTTI.cpp - Include/ScriptCanvas/Core/Contracts/ContractRTTI.h Include/ScriptCanvas/Core/Contracts/DisallowReentrantExecutionContract.cpp - Include/ScriptCanvas/Core/Contracts/DisallowReentrantExecutionContract.h Include/ScriptCanvas/Core/Contracts/DisplayGroupConnectedSlotLimitContract.cpp - Include/ScriptCanvas/Core/Contracts/DisplayGroupConnectedSlotLimitContract.h Include/ScriptCanvas/Core/Contracts/DynamicTypeContract.cpp - Include/ScriptCanvas/Core/Contracts/DynamicTypeContract.h Include/ScriptCanvas/Core/Contracts/IsReferenceTypeContract.cpp - Include/ScriptCanvas/Core/Contracts/IsReferenceTypeContract.h Include/ScriptCanvas/Core/Contracts/MathOperatorContract.cpp - Include/ScriptCanvas/Core/Contracts/MathOperatorContract.h Include/ScriptCanvas/Core/Contracts/SlotTypeContract.cpp - Include/ScriptCanvas/Core/Contracts/SlotTypeContract.h Include/ScriptCanvas/Core/Contracts/SupportsMethodContract.cpp - Include/ScriptCanvas/Core/Contracts/SupportsMethodContract.h Include/ScriptCanvas/Core/Contracts/TypeContract.cpp - Include/ScriptCanvas/Core/Contracts/TypeContract.h Include/ScriptCanvas/Data/BehaviorContextObject.cpp - Include/ScriptCanvas/Data/BehaviorContextObject.h Include/ScriptCanvas/Data/BehaviorContextObjectPtr.cpp - Include/ScriptCanvas/Data/BehaviorContextObjectPtr.h Include/ScriptCanvas/Data/Data.cpp - Include/ScriptCanvas/Data/Data.h - Include/ScriptCanvas/Data/DataMacros.h Include/ScriptCanvas/Data/DataRegistry.cpp - Include/ScriptCanvas/Data/DataRegistry.h - Include/ScriptCanvas/Data/NumericData.h - Include/ScriptCanvas/Deprecated/VariableDatumBase.h Include/ScriptCanvas/Deprecated/VariableDatumBase.cpp - Include/ScriptCanvas/Deprecated/VariableDatum.h Include/ScriptCanvas/Deprecated/VariableDatum.cpp - Include/ScriptCanvas/Deprecated/VariableHelpers.h Include/ScriptCanvas/Deprecated/VariableHelpers.cpp - Include/ScriptCanvas/Execution/ErrorBus.h - Include/ScriptCanvas/Execution/ExecutionBus.h - Include/ScriptCanvas/Execution/ExecutionContext.h Include/ScriptCanvas/Execution/ExecutionContext.cpp - Include/ScriptCanvas/Execution/ExecutionObjectCloning.h Include/ScriptCanvas/Execution/ExecutionObjectCloning.cpp - Include/ScriptCanvas/Execution/ExecutionPerformanceTimer.h Include/ScriptCanvas/Execution/ExecutionPerformanceTimer.cpp - Include/ScriptCanvas/Execution/ExecutionState.h Include/ScriptCanvas/Execution/ExecutionState.cpp - Include/ScriptCanvas/Execution/ExecutionStateDeclarations.h - Include/ScriptCanvas/Execution/NativeHostDeclarations.h Include/ScriptCanvas/Execution/NativeHostDeclarations.cpp - Include/ScriptCanvas/Execution/NativeHostDefinitions.h Include/ScriptCanvas/Execution/NativeHostDefinitions.cpp - Include/ScriptCanvas/Execution/RuntimeComponent.h Include/ScriptCanvas/Execution/RuntimeComponent.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedCloningAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedCloningAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedDebugAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedDebugAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedOut.h Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedOut.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedSingleton.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedSingleton.cpp - Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedUtility.h Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedUtility.cpp - Include/ScriptCanvas/Execution/NodeableOut/NodeableOutNative.h - Include/ScriptCanvas/Grammar/AbstractCodeModel.h Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp - Include/ScriptCanvas/Grammar/DebugMap.h Include/ScriptCanvas/Grammar/DebugMap.cpp - Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.h Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp - Include/ScriptCanvas/Grammar/ParsingMetaData.h Include/ScriptCanvas/Grammar/ParsingMetaData.cpp - Include/ScriptCanvas/Grammar/ParsingUtilities.h Include/ScriptCanvas/Grammar/ParsingUtilities.cpp - Include/ScriptCanvas/Grammar/Primitives.h Include/ScriptCanvas/Grammar/Primitives.cpp - Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp - Include/ScriptCanvas/Grammar/PrimitivesExecution.h - Include/ScriptCanvas/Grammar/SymbolNames.h - Include/ScriptCanvas/Execution/ErrorBus.h Include/ScriptCanvas/Execution/ExecutionContext.cpp - Include/ScriptCanvas/Execution/ExecutionContext.h - Include/ScriptCanvas/Execution/ExecutionBus.h Include/ScriptCanvas/Execution/NativeHostDeclarations.cpp - Include/ScriptCanvas/Execution/NativeHostDeclarations.h Include/ScriptCanvas/Execution/NativeHostDefinitions.cpp - Include/ScriptCanvas/Execution/NativeHostDefinitions.h Include/ScriptCanvas/Execution/RuntimeComponent.cpp - Include/ScriptCanvas/Execution/RuntimeComponent.h Include/ScriptCanvas/Internal/Nodeables/BaseTimer.cpp - Include/ScriptCanvas/Internal/Nodeables/BaseTimer.h - Include/ScriptCanvas/Internal/Nodeables/BaseTimer.ScriptCanvasNodeable.xml Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.cpp - Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.h - Include/ScriptCanvas/Internal/Nodes/BaseTimerNode.ScriptCanvasGrammar.xml Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.cpp - Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.h - Include/ScriptCanvas/Internal/Nodes/ExpressionNodeBase.ScriptCanvasGrammar.xml Include/ScriptCanvas/Internal/Nodes/StringFormatted.cpp - Include/ScriptCanvas/Internal/Nodes/StringFormatted.h - Include/ScriptCanvas/Internal/Nodes/StringFormatted.ScriptCanvasGrammar.xml Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp - Include/ScriptCanvas/Grammar/AbstractCodeModel.h - Include/ScriptCanvas/Libraries/Libraries.h Include/ScriptCanvas/Libraries/Libraries.cpp Include/ScriptCanvas/Libraries/Core/AzEventHandler.cpp - Include/ScriptCanvas/Libraries/Core/AzEventHandler.h - Include/ScriptCanvas/Libraries/Core/AzEventHandler.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/BinaryOperator.cpp - Include/ScriptCanvas/Libraries/Core/BinaryOperator.h Include/ScriptCanvas/Libraries/Core/CoreNodes.cpp - Include/ScriptCanvas/Libraries/Core/CoreNodes.h - Include/ScriptCanvas/Libraries/Core/ContainerTypeReflection.h Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp - Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h - Include/ScriptCanvas/Libraries/Core/EBusEventHandler.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/ExtractProperty.cpp - Include/ScriptCanvas/Libraries/Core/ExtractProperty.h - Include/ScriptCanvas/Libraries/Core/ExtractProperty.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.h Include/ScriptCanvas/Libraries/Core/EventHandlerTranslationUtility.cpp Include/ScriptCanvas/Libraries/Core/ForEach.cpp - Include/ScriptCanvas/Libraries/Core/ForEach.h - Include/ScriptCanvas/Libraries/Core/ForEach.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/FunctionBus.h Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp - Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h - Include/ScriptCanvas/Libraries/Core/FunctionCallNode.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.cpp Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.cpp - Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h - Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/GetVariable.cpp - Include/ScriptCanvas/Libraries/Core/GetVariable.h - Include/ScriptCanvas/Libraries/Core/GetVariable.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/Method.cpp - Include/ScriptCanvas/Libraries/Core/Method.h Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp - Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h Include/ScriptCanvas/Libraries/Core/MethodUtility.cpp - Include/ScriptCanvas/Libraries/Core/MethodUtility.h Include/ScriptCanvas/Libraries/Core/Nodeling.cpp - Include/ScriptCanvas/Libraries/Core/Nodeling.h - Include/ScriptCanvas/Libraries/Core/Nodeling.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp - Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h - Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/Repeater.cpp - Include/ScriptCanvas/Libraries/Core/Repeater.h - Include/ScriptCanvas/Libraries/Core/Repeater.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.h Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.cpp - Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/Core/ScriptEventBase.cpp - Include/ScriptCanvas/Libraries/Core/ScriptEventBase.h - Include/ScriptCanvas/Libraries/Core/ScriptEventBase.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/SendScriptEvent.cpp - Include/ScriptCanvas/Libraries/Core/SendScriptEvent.h - Include/ScriptCanvas/Libraries/Core/SendScriptEvent.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/SetVariable.cpp - Include/ScriptCanvas/Libraries/Core/SetVariable.h - Include/ScriptCanvas/Libraries/Core/SetVariable.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Core/Start.h - Include/ScriptCanvas/Libraries/Core/Start.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Core/UnaryOperator.cpp - Include/ScriptCanvas/Libraries/Core/UnaryOperator.h Include/ScriptCanvas/Libraries/Entity/Entity.cpp - Include/ScriptCanvas/Libraries/Entity/Entity.h - Include/ScriptCanvas/Libraries/Entity/EntityNodes.h Include/ScriptCanvas/Libraries/Entity/RotateMethod.cpp - Include/ScriptCanvas/Libraries/Entity/RotateMethod.h - Include/ScriptCanvas/Libraries/Logic/And.h Include/ScriptCanvas/Libraries/Logic/Any.cpp - Include/ScriptCanvas/Libraries/Logic/Any.h - Include/ScriptCanvas/Libraries/Logic/Any.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Break.h Include/ScriptCanvas/Libraries/Logic/Break.cpp - Include/ScriptCanvas/Libraries/Logic/Break.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Cycle.cpp - Include/ScriptCanvas/Libraries/Logic/Cycle.h - Include/ScriptCanvas/Libraries/Logic/Cycle.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Gate.cpp - Include/ScriptCanvas/Libraries/Logic/Gate.h - Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Indexer.h - Include/ScriptCanvas/Libraries/Logic/Indexer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/IsNull.cpp - Include/ScriptCanvas/Libraries/Logic/IsNull.h - Include/ScriptCanvas/Libraries/Logic/IsNull.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Logic.cpp - Include/ScriptCanvas/Libraries/Logic/Logic.h - Include/ScriptCanvas/Libraries/Logic/Multiplexer.h - Include/ScriptCanvas/Libraries/Logic/Multiplexer.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Not.h Include/ScriptCanvas/Libraries/Logic/Once.cpp - Include/ScriptCanvas/Libraries/Logic/Once.h - Include/ScriptCanvas/Libraries/Logic/Once.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Logic/Or.h Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.cpp - Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.h - Include/ScriptCanvas/Libraries/Logic/OrderedSequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/Sequencer.cpp - Include/ScriptCanvas/Libraries/Logic/Sequencer.h - Include/ScriptCanvas/Libraries/Logic/Sequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.cpp - Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.h - Include/ScriptCanvas/Libraries/Logic/TargetedSequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.cpp - Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.h - Include/ScriptCanvas/Libraries/Logic/WeightedRandomSequencer.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Logic/While.cpp - Include/ScriptCanvas/Libraries/Logic/While.h - Include/ScriptCanvas/Libraries/Logic/While.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Math/AABBNodes.h - Include/ScriptCanvas/Libraries/Math/ColorNodes.h - Include/ScriptCanvas/Libraries/Math/CRCNodes.h - Include/ScriptCanvas/Libraries/Math/Divide.h Include/ScriptCanvas/Libraries/Math/Math.cpp - Include/ScriptCanvas/Libraries/Math/Math.h Include/ScriptCanvas/Libraries/Math/MathExpression.cpp - Include/ScriptCanvas/Libraries/Math/MathExpression.h - Include/ScriptCanvas/Libraries/Math/MathExpression.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Math/MathNodeUtilities.cpp - Include/ScriptCanvas/Libraries/Math/MathNodeUtilities.h - Include/ScriptCanvas/Libraries/Math/MathGenerics.h - Include/ScriptCanvas/Libraries/Math/MathRandom.h - Include/ScriptCanvas/Libraries/Math/Matrix3x3Nodes.h - Include/ScriptCanvas/Libraries/Math/Matrix4x4Nodes.h - Include/ScriptCanvas/Libraries/Math/Multiply.h - Include/ScriptCanvas/Libraries/Math/OBBNodes.h - Include/ScriptCanvas/Libraries/Math/PlaneNodes.h - Include/ScriptCanvas/Libraries/Math/RotationNodes.h - Include/ScriptCanvas/Libraries/Math/Subtract.h - Include/ScriptCanvas/Libraries/Math/Sum.h - Include/ScriptCanvas/Libraries/Math/TransformNodes.h - Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h - Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h - Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h - Include/ScriptCanvas/Libraries/Comparison/Comparison.h Include/ScriptCanvas/Libraries/Comparison/Comparison.cpp - Include/ScriptCanvas/Libraries/Comparison/ComparisonFunctions.h - Include/ScriptCanvas/Libraries/Comparison/EqualTo.h - Include/ScriptCanvas/Libraries/Comparison/NotEqualTo.h - Include/ScriptCanvas/Libraries/Comparison/Less.h - Include/ScriptCanvas/Libraries/Comparison/Greater.h - Include/ScriptCanvas/Libraries/Comparison/LessEqual.h - Include/ScriptCanvas/Libraries/Comparison/GreaterEqual.h - Include/ScriptCanvas/Libraries/Time/Time.h Include/ScriptCanvas/Libraries/Time/Time.cpp Include/ScriptCanvas/Libraries/Time/Countdown.cpp - Include/ScriptCanvas/Libraries/Time/Countdown.h - Include/ScriptCanvas/Libraries/Time/Countdown.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Time/DelayNodeable.h Include/ScriptCanvas/Libraries/Time/DelayNodeable.cpp - Include/ScriptCanvas/Libraries/Time/DelayNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/Time/Duration.cpp - Include/ScriptCanvas/Libraries/Time/Duration.h - Include/ScriptCanvas/Libraries/Time/Duration.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Time/HeartBeat.cpp - Include/ScriptCanvas/Libraries/Time/HeartBeat.h - Include/ScriptCanvas/Libraries/Time/HeartBeat.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Time/Timer.cpp - Include/ScriptCanvas/Libraries/Time/Timer.h - Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.h Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.cpp - Include/ScriptCanvas/Libraries/Time/TimeDelayNodeable.ScriptCanvasNodeable.xml - Include/ScriptCanvas/Libraries/Time/DurationNodeable.h Include/ScriptCanvas/Libraries/Time/DurationNodeable.cpp - Include/ScriptCanvas/Libraries/Time/DurationNodeable.ScriptCanvasNodeable.xml - Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.h Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.cpp - Include/ScriptCanvas/Libraries/Time/HeartBeatNodeable.ScriptCanvasNodeable.xml - Include/ScriptCanvas/Libraries/Time/TimerNodeable.h Include/ScriptCanvas/Libraries/Time/TimerNodeable.cpp - Include/ScriptCanvas/Libraries/Time/TimerNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/Spawning/Spawning.cpp - Include/ScriptCanvas/Libraries/Spawning/Spawning.h Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.cpp - Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.h - Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.ScriptCanvasNodeable.xml Include/ScriptCanvas/Libraries/String/Contains.cpp - Include/ScriptCanvas/Libraries/String/Contains.h - Include/ScriptCanvas/Libraries/String/Contains.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/String/Format.cpp - Include/ScriptCanvas/Libraries/String/Format.h - Include/ScriptCanvas/Libraries/String/Format.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/String/Print.h - Include/ScriptCanvas/Libraries/String/Print.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/String/Replace.cpp - Include/ScriptCanvas/Libraries/String/Replace.h - Include/ScriptCanvas/Libraries/String/Replace.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/String/String.h Include/ScriptCanvas/Libraries/String/String.cpp - Include/ScriptCanvas/Libraries/String/StringMethods.h Include/ScriptCanvas/Libraries/String/StringMethods.cpp - Include/ScriptCanvas/Libraries/String/StringGenerics.h Include/ScriptCanvas/Libraries/String/Utilities.cpp - Include/ScriptCanvas/Libraries/String/Utilities.h - Include/ScriptCanvas/Libraries/String/Utilities.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.cpp - Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.h - Include/ScriptCanvas/Libraries/UnitTesting/AddFailure.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.h - Include/ScriptCanvas/Libraries/UnitTesting/AddSuccess.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.h - Include/ScriptCanvas/Libraries/UnitTesting/Checkpoint.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectFalse.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThan.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectGreaterThanEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThan.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectLessThanEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectNotEqual.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.cpp - Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.h - Include/ScriptCanvas/Libraries/UnitTesting/ExpectTrue.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.h - Include/ScriptCanvas/Libraries/UnitTesting/MarkComplete.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBus.h - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusMacros.h Include/ScriptCanvas/Libraries/UnitTesting/UnitTesting.cpp - Include/ScriptCanvas/Libraries/UnitTesting/UnitTesting.h Include/ScriptCanvas/Libraries/UnitTesting/UnitTestingLibrary.cpp - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestingLibrary.h Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/Auxiliary.cpp - Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/Auxiliary.h - Include/ScriptCanvas/Libraries/UnitTesting/Auxiliary/AuxiliaryGenerics.h - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.h Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSender.cpp - Include/ScriptCanvas/Libraries/UnitTesting/UnitTestBusSenderMacros.h Include/ScriptCanvas/Libraries/Operators/Operators.cpp - Include/ScriptCanvas/Libraries/Operators/Operators.h Include/ScriptCanvas/Libraries/Operators/Operator.cpp - Include/ScriptCanvas/Libraries/Operators/Operator.h - Include/ScriptCanvas/Libraries/Operators/Operator.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorAt.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorBack.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorClear.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorEmpty.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorErase.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorFront.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorInsert.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorPushBack.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.cpp - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.h - Include/ScriptCanvas/Libraries/Operators/Containers/OperatorSize.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorAdd.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorArithmetic.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDiv.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorDivideByNumber.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLength.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerp.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorMul.ScriptCanvasGrammar.xml Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.h - Include/ScriptCanvas/Libraries/Operators/Math/OperatorSub.ScriptCanvasGrammar.xml - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.cpp - Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeableNode.h Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeableNode.cpp - Include/ScriptCanvas/Profiler/Driller.h - Include/ScriptCanvas/Profiler/Aggregator.h Include/ScriptCanvas/Profiler/Aggregator.cpp - Include/ScriptCanvas/Profiler/DrillerEvents.h Include/ScriptCanvas/Profiler/DrillerEvents.cpp - Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.cpp - Include/ScriptCanvas/Serialization/DatumSerializer.h Include/ScriptCanvas/Serialization/DatumSerializer.cpp - Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp Include/ScriptCanvas/Data/DataTrait.cpp - Include/ScriptCanvas/Data/DataTrait.h Include/ScriptCanvas/Data/PropertyTraits.cpp - Include/ScriptCanvas/Data/PropertyTraits.h - Include/ScriptCanvas/Data/Traits.h - Include/ScriptCanvas/Variable/VariableBus.h - Include/ScriptCanvas/Variable/GraphVariable.h Include/ScriptCanvas/Variable/GraphVariable.cpp - Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp - Include/ScriptCanvas/Variable/VariableCore.h Include/ScriptCanvas/Variable/VariableCore.cpp - Include/ScriptCanvas/Variable/VariableData.h Include/ScriptCanvas/Variable/VariableData.cpp - Include/ScriptCanvas/Utils/DataUtils.h Include/ScriptCanvas/Utils/DataUtils.cpp - Include/ScriptCanvas/Utils/NodeUtils.h Include/ScriptCanvas/Utils/NodeUtils.cpp - Include/ScriptCanvas/Utils/SerializationUtils.h - Include/ScriptCanvas/Utils/VersionConverters.h Include/ScriptCanvas/Utils/VersionConverters.cpp Include/ScriptCanvas/Utils/VersioningUtils.cpp Include/ScriptCanvas/Utils/VersioningUtils.cpp - Include/ScriptCanvas/Utils/BehaviorContextUtils.h Include/ScriptCanvas/Utils/BehaviorContextUtils.cpp ) set(SKIP_UNITY_BUILD_INCLUSION_FILES Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp - Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h - Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.cpp ) diff --git a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt index 2addf3e8ca..0d25959066 100644 --- a/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasPhysics/Code/CMakeLists.txt @@ -32,7 +32,7 @@ ly_add_target( PRIVATE Legacy::CryCommon Gem::ScriptCanvasPhysics.Static - Gem::ScriptCanvasAPI + Gem::ScriptCanvas.API ) # By default, the above module is used by all application types, however, the module depends at runtime to ScriptCanvas From 64139b7636fb6e7a5c8197b09e816d728cdb2e5f Mon Sep 17 00:00:00 2001 From: amzn-sj Date: Mon, 29 Nov 2021 14:30:15 -0800 Subject: [PATCH 14/72] Add new-line to end of file Signed-off-by: amzn-sj --- Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake index 76b5412c58..67f526cf21 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake @@ -60,4 +60,4 @@ set(FILES include/LmbrCentral/Shape/SplineAttribute.h include/LmbrCentral/Shape/SplineAttribute.inl include/LmbrCentral/Terrain/TerrainSystemRequestBus.h -) \ No newline at end of file +) From 8e472a030b65935c8175f663b21ddfe268f2a143 Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Mon, 29 Nov 2021 18:22:53 -0800 Subject: [PATCH 15/72] Added support for translating variables types in the variable manager Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../EBus/Senders/AWSGameLiftRequestBus.names | 81 + .../Types/BehaviorTypes.names | 1428 +++++++++++++++++ .../Editor/Translation/TranslationHelper.h | 456 +----- .../DataTypePalette/DataTypePaletteModel.cpp | 11 +- .../ScriptCanvasNodePaletteDockWidget.cpp | 9 +- .../Include/ScriptCanvas/Data/DataTrait.h | 4 +- .../Code/Tools/TranslationGeneration.cpp | 28 + .../Code/Tools/TranslationGeneration.h | 3 + 8 files changed, 1577 insertions(+), 443 deletions(-) create mode 100644 Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names create mode 100644 Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names new file mode 100644 index 0000000000..3e32cecee8 --- /dev/null +++ b/Gems/ScriptCanvas/Assets/TranslationAssets/EBus/Senders/AWSGameLiftRequestBus.names @@ -0,0 +1,81 @@ +{ + "entries": [ + { + "base": "AWSGameLiftRequestBus", + "context": "EBusSender", + "variant": "", + "details": { + "name": "Requests", + "category": "AWS Game Lift" + }, + "methods": [ + { + "base": "ConfigureGameLiftClient", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Configure Game Lift Client" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Configure Game Lift Client is invoked" + }, + "details": { + "name": "Configure Game Lift Client" + }, + "params": [ + { + "typeid": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}", + "details": { + "name": "Region" + } + } + ], + "results": [ + { + "typeid": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "details": { + "name": "Result" + } + } + ] + }, + { + "base": "CreatePlayerId", + "entry": { + "name": "In", + "tooltip": "When signaled, this will invoke Create Player Id" + }, + "exit": { + "name": "Out", + "tooltip": "Signaled after Create Player Id is invoked" + }, + "details": { + "name": "Create Player Id" + }, + "params": [ + { + "typeid": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "details": { + "name": "Include Brackets" + } + }, + { + "typeid": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "details": { + "name": "Include Dashes" + } + } + ], + "results": [ + { + "typeid": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}", + "details": { + "name": "Player Id" + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names b/Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names new file mode 100644 index 0000000000..598d058767 --- /dev/null +++ b/Gems/ScriptCanvas/Assets/TranslationAssets/Types/BehaviorTypes.names @@ -0,0 +1,1428 @@ +{ + "entries": [ + { + "base": "{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Uuid" + } + }, + { + "base": "{831C1F11-5898-4FBF-B4CF-92B757A907A8}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "FastNoiseGradientConfig" + } + }, + { + "base": "{1D00F234-8134-4A42-A357-ADAC865CF63A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Mesh Blocker Config" + } + }, + { + "base": "{40403A44-31FE-4D1D-941C-6593759CCCBD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MixedGradientConfig" + } + }, + { + "base": "{0B5D866D-C7F5-5B12-81A5-74521A8230D5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{4AADFD75-48A7-4F31-8F30-FE4505F09E35}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SphereShapeConfig" + } + }, + { + "base": "{01F6E6C5-707E-42EC-91BB-F674B9F51A40}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlockerConfig" + } + }, + { + "base": "{5574DD27-89D8-5A40-B7C4-FA04C68B8A0D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{FE862126-C838-4999-9B7B-4AEEA5507A49}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RaySplineQueryResult" + } + }, + { + "base": "{ED57731E-2821-4AA6-9BD6-9203ED0B6AB0}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaBlenderConfig" + } + }, + { + "base": "{0CE9FA36-1E3A-4C06-9254-B7C73A732053}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Vector4" + } + }, + { + "base": "{A62E9C87-093C-4534-AB48-DEF8EC80C190}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DescriptorListCombinerConfig" + } + }, + { + "base": "{73BA7B92-1061-4DDB-AA5B-A0D87303CBC8}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SlopeAlignmentModifierConfig" + } + }, + { + "base": "{C0E1DF8C-D1BE-4AF4-8100-5D71788399BA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderVariantInfo" + } + }, + { + "base": "{15A4332F-7C3F-4A58-AC35-50E1CE53FB9C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Matrix3x3" + } + }, + { + "base": "{12A1776B-61F6-4E5F-356A-AD718A62051F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "NetworkTestPlayerComponentNetworkInput" + } + }, + { + "base": "{157193C7-B673-4A2B-8B43-5681DCC3DEC3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Matrix4x4" + } + }, + { + "base": "{331A3D0E-BB1D-47BF-96A2-249FAA0D720D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AzFramework::SurfaceData::SurfacePoint" + } + }, + { + "base": "{6483F481-0C18-4171-8B59-A44F2F28EAE5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSMetrics_MetricsAttribute" + } + }, + { + "base": "{708A5B3C-E377-40CE-9572-BEB64C849D40}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "VertexHandle" + } + }, + { + "base": "{C81CC1CA-6841-5F6A-B1C7-E544590B481F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{E8C6654F-0000-5496-8A61-9DAE9CA30493}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{C16F0F38-8F8F-45A2-A33B-F2758922A7C4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexTangentData" + } + }, + { + "base": "{F56FB088-4C92-4453-AFE9-4E820F03FA90}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexBitangentData" + } + }, + { + "base": "{A7E568EC-5873-5C8A-A43E-A7228B613A21}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{00931AEB-2AD8-42CE-B1DC-FA4332F51501}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CapsuleShapeConfig" + } + }, + { + "base": "{004ABD25-CF14-4EB3-BD41-022C247C07FA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "OBB" + } + }, + { + "base": "{4AFDFD7F-384A-41DF-900C-9B25A4AA8D1E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PosterizeGradientConfig" + } + }, + { + "base": "{02FB32C4-B94E-4084-9049-3DF32F87BD76}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ClientAuthAWSCredentials" + } + }, + { + "base": "{F6B9150B-CC89-48A2-AB89-D18740CC6FA2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "FaceVertHandles" + } + }, + { + "base": "{4BC6D515-214A-4DCE-8FCB-A6389B66A1B9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Entity Transform" + } + }, + { + "base": "{F681BA9D-245C-4630-B20E-05DD752FAD57}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UiOffsets" + } + }, + { + "base": "{EBEDA5EC-29D3-4F23-ABCC-C7C4EE48FA36}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DisplaySettingsState" + } + }, + { + "base": "{344066EB-7C3D-4E92-B53D-3C9EBD546488}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EditorMaterialComponentSlot" + } + }, + { + "base": "{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Name" + } + }, + { + "base": "{F965D1B2-9DE3-4900-B44B-E58D9F083ACB}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AuthenticationTokens" + } + }, + { + "base": "{1BDB5DA4-A4A8-452B-BE6D-6BD451D4E7CD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ImageGradientConfig" + } + }, + { + "base": "{DCFE9FBF-39BF-5B3C-AD28-D61ADBAF1711}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{8FB7C786-D8A7-41C4-A703-020020EB4A4F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShapeAreaFalloffGradientConfig" + } + }, + { + "base": "{D24130B9-89C4-4EAA-9A5D-3469B05C5065}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GraphModelSlotId" + } + }, + { + "base": "{7894072A-9050-4F0F-901B-34B1A0D29417}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Color" + } + }, + { + "base": "{F2EE1768-183B-483E-9778-CB3D3D0DA68A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialData" + } + }, + { + "base": "{FF8B1DED-C1A8-4322-86D2-C8432E4B0526}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RotationModifierConfig" + } + }, + { + "base": "{902F6253-A8FA-4350-B9F1-C176F3E2D305}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DescriptorListConfig" + } + }, + { + "base": "{34516BA4-2B13-4A84-A46B-01E1980CA778}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GradientSurfaceDataConfig" + } + }, + { + "base": "{8AF3B382-F187-4323-9014-B380638767E3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::NetComponentId" + } + }, + { + "base": "{EBB1C475-FA03-4111-8C84-985377434B9B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::RpcIndex" + } + }, + { + "base": "{E134EAE8-52A1-4E43-847B-09E546CC5B95}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UVCoords" + } + }, + { + "base": "{28529C97-543C-5690-9FA4-9781271E6661}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{B94085B7-C0D4-466A-A791-188A4559EC8D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "OutputDeviceTransformType" + } + }, + { + "base": "{3EC1CE83-483D-41FD-9909-D22B03E56F4E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Render::ShadowmapSize" + } + }, + { + "base": "{9E71534D-34B3-4723-B180-2552513DDA3D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSScriptBehaviorLambda" + } + }, + { + "base": "{8CD110EE-95FA-4B26-B10E-95079BE4CB11}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DistanceBetweenFilterConfig" + } + }, + { + "base": "{A54C2B36-D5B8-46A1-A529-4EBDBD2450E7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AABB" + } + }, + { + "base": "{C845E5EC-5580-4E12-A9B2-9AE7E5B7826F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EntityComponentIdPair" + } + }, + { + "base": "{E6DA080B-7ED1-4135-A78C-A6A5E495A43E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CollisionGroup" + } + }, + { + "base": "{F01C8BDD-6F24-4344-8945-521A8750B30B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PolygonPrism" + } + }, + { + "base": "{67C8C6ED-F32A-443E-A777-1CAE48B22CD7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceTag" + } + }, + { + "base": "{48A94382-72BE-457B-BB43-0E6C245824D2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SearchFilter" + } + }, + { + "base": "{4C0F6AD4-0D4F-4354-AD4A-0C01E948245C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ScriptTimePoint" + } + }, + { + "base": "{05E4C08B-3A1B-4390-8144-3767D8E56A81}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::NetEntityId" + } + }, + { + "base": "{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UiAnchors" + } + }, + { + "base": "{691E0F23-37E9-434F-A1D1-E8DE5B4A3405}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceSlopeGradientConfig" + } + }, + { + "base": "{4E74B13E-6B4E-59D1-90E1-5E5C7EEE40D6}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{7602AA36-792C-4BDC-BDF8-AA16792151A3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CollisionEvent" + } + }, + { + "base": "{02644F52-9483-47A8-9028-37671695C34E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LightConfig" + } + }, + { + "base": "{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EntityId" + } + }, + { + "base": "{1906D8A5-7DEC-4DE3-A606-9E53BB3459E7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Matrix3x4" + } + }, + { + "base": "{17477B86-B163-4574-8FB2-4916BC218B3D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexColorData" + } + }, + { + "base": "{A504D6DA-2825-4A0E-A65E-3FC76FC8AFAC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaDebugConfig" + } + }, + { + "base": "{794F7DE4-188C-4031-8B00-C2BA0C351A1E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LevelSettingsConfig" + } + }, + { + "base": "{B88C9D87-8609-4EAB-82D6-92DFEF006629}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShapeIntersectionFilterConfig" + } + }, + { + "base": "{3D80F623-C85C-4741-90D0-E4E66164E6BF}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Vector2" + } + }, + { + "base": "{5B085DA7-CDC9-47C7-B2DB-BA5DD5AA2FB5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceMaskFilterConfig" + } + }, + { + "base": "{847DD984-9DBF-4789-8E25-E0334402E8AD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Plane" + } + }, + { + "base": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "String" + } + }, + { + "base": "{63984856-F883-4F8C-9049-5A8F26477B76}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InstanceSystemConfig" + } + }, + { + "base": "{3768D3A6-BF70-4ABC-B4EC-73C75A886916}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GradientSampler" + } + }, + { + "base": "{B435C091-482C-4EB9-B1F4-FA5B480796DA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshVertexUVData" + } + }, + { + "base": "{EA14018E-E853-4BF5-8E13-D83BB99A54CC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceTagWeight" + } + }, + { + "base": "{3CB05FC9-6E0F-435E-B420-F027B6716804}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceAltitudeGradientConfig" + } + }, + { + "base": "{C6FD75F7-58BA-46CE-8FBA-2D64CB4ECFF9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ExposureControlConfig" + } + }, + { + "base": "{27B1FEC2-8C8A-47D7-A034-6609FA092B34}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderVariantId" + } + }, + { + "base": "{41CC88A4-FE07-48E6-943D-998DE68AFF5C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Entity" + } + }, + { + "base": "{6B17F9C6-DB72-52CA-80ED-EFDFDF2DF9ED}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{F27E64FB-A7FF-47F2-80DB-7E1371B014DD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PythonBuilderWorker" + } + }, + { + "base": "{41CA80B1-9E0D-41FB-A235-9638D2A905A5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Render::DisplayMapperOperationType" + } + }, + { + "base": "{4FA91FA7-CF3C-51BF-8159-6496DC7D526C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{3EE8C0D4-3792-46C0-B91C-B89A81C36B91}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AcesParameterOverrides" + } + }, + { + "base": "{5F0CD700-EC2B-468D-B708-F6EEA7782C46}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceMaskDepthFilterConfig" + } + }, + { + "base": "{569E74F6-1268-4199-9653-A3B603FC9F4F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSScriptBehaviorDynamoDB" + } + }, + { + "base": "{7E304208-5FDF-4384-BC28-E7CDD2A15BEC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DistributionFilterConfig" + } + }, + { + "base": "{7A0851A3-2CBD-4A03-85D5-1C40221E7F61}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "TriggerEvent" + } + }, + { + "base": "{C66E5214-A24B-4722-B7F0-5991E6F8F163}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialAssignment" + } + }, + { + "base": "{110C4B14-11A8-4E9D-8638-5051013A56AC}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Number" + } + }, + { + "base": "{E35DCF28-1AC3-49E8-A0AB-2F6115348F45}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PositionSplineQueryResult" + } + }, + { + "base": "{98A6B0CE-FAD0-4108-B019-6B01931E649F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "VegetationSpawnerConfig" + } + }, + { + "base": "{1811456D-0C3D-58C8-ACE8-FD47F4E80E25}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Transform" + } + }, + { + "base": "{6CEBAF3A-2A5C-4508-A351-9613E32CF63F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceSlopeFilterConfig" + } + }, + { + "base": "{DA5C6354-AA81-504B-88BF-8EF5811ABA61}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{24EC2919-F198-4871-8404-F6DE8A16275E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DiskShapeConfig" + } + }, + { + "base": "{B1106C14-D22B-482F-B33E-B6E154A53798}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSMetrics_AttributesSubmissionList" + } + }, + { + "base": "{FF875C22-2E4F-4CE3-BA49-09BF78C70A09}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlendShapeData" + } + }, + { + "base": "{07B9E2F7-5408-49E9-904D-CC1A9C33230E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RPI::ShaderOptionDescriptor" + } + }, + { + "base": "{9274AD17-3212-4651-9F3B-7DCCB080E467}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SceneManifest" + } + }, + { + "base": "{F392F061-BF40-43C5-89F6-7323D6EF11F4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SmoothStep" + } + }, + { + "base": "{F034FBA2-AC2F-4E66-8152-14DFB90D6283}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BoxShapeConfig" + } + }, + { + "base": "{950009BC-8991-4749-9D5C-08C62AF34E7B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "FaceHandle" + } + }, + { + "base": "{B0216514-46B5-4A57-9D9D-8D9EC94C3702}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ConstantGradientConfig" + } + }, + { + "base": "{F4460210-024D-4B3B-A10A-04B669C34230}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::PropertyIndex" + } + }, + { + "base": "{6EEACBC0-2D97-414C-8E87-088E7BA231A9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LightingPreset" + } + }, + { + "base": "{9E0F0801-348B-4FF9-AF9B-858D59404968}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InputEventNotificationId" + } + }, + { + "base": "{0C899DAC-6B19-4BDD-AD8C-8A11EF2A6729}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MotionEvent" + } + }, + { + "base": "{73103120-3DD3-4873-BAB3-9713FA2804FB}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Quaternion" + } + }, + { + "base": "{23C40FD4-A55F-4BD3-BE5B-DC5423F217C2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "EmptyInstanceSpawner" + } + }, + { + "base": "{3E49974D-2EE0-4AF9-92B9-229A22B515C3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ReferenceShapeConfig" + } + }, + { + "base": "{E59D0A4C-BA3D-4288-B409-A00B7D5566AA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceMaskGradientConfig" + } + }, + { + "base": "{14CCBE43-52DD-4F56-92A8-2BB011A0F7A2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaSystemConfig" + } + }, + { + "base": "{E6D8372B-8419-4287-B478-1353709A972F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AssetInfo" + } + }, + { + "base": "{5C8C0729-5D41-5299-80F1-395F79B02D70}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{F8679938-6D3F-47CC-A078-3D6EC0011366}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderVariantListSourceData" + } + }, + { + "base": "{8F519317-4E83-4CF0-BEC9-C5F3F3198F20}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DitherGradientConfig" + } + }, + { + "base": "{1106FD53-8B3A-4F97-8051-E34AD70199A5}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "GradientTransformConfig" + } + }, + { + "base": "{A23453D5-79A8-49C8-B9F0-9CC35D711DD4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlastActorData" + } + }, + { + "base": "{E9E2D5B3-66F1-494D-91D2-1E83D36A1AC1}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ThresholdGradientConfig" + } + }, + { + "base": "{64C7F381-3313-46E8-B23B-D7AA9A915F35}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderCollectionItem" + } + }, + { + "base": "{A746CFD0-7288-42F4-837D-1CDE2EAA6923}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PerlinGradientConfig" + } + }, + { + "base": "{3F860893-1F57-5615-92CA-389B49687A9C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{61599E53-2B6A-40AC-B5B8-FC1C3F87275E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AreaConfig" + } + }, + { + "base": "{BBA5CC1E-B4CA-4792-89F7-93711E98FBD1}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DynamicSliceInstanceSpawner" + } + }, + { + "base": "{4A70FD56-10A8-460E-B822-3EF03F1EF7A0}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "String" + } + }, + { + "base": "{B980EF45-C893-56C2-9B54-44B8B14F3436}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{BB3C3018-66B1-4BAD-AD27-F385BA015C69}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceAltitudeFilterConfig" + } + }, + { + "base": "{7F4E956C-7463-4236-B320-C992D36A9C6E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AWSScriptBehaviorS3" + } + }, + { + "base": "{957264F7-A169-4D47-B94C-659B078026D4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MixedGradientLayer" + } + }, + { + "base": "{35BF3504-CEC9-4406-A275-C633A17FBEFB}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::ClientInputId" + } + }, + { + "base": "{5B169E40-E02B-5012-A085-BE7E6CA55CEA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{DE5C18B0-4214-4A37-B590-8D45CC450A96}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "UiPadding" + } + }, + { + "base": "{121A6DAB-26C1-46B7-83AE-BE750FDABC04}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ReferenceGradientConfig" + } + }, + { + "base": "{DF17F6F3-48C6-4B4A-BBD9-37DA03162864}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Multiplayer::HostFrameId" + } + }, + { + "base": "{B7A0A88D-4FDF-487F-A0E6-5BE04C82862A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PositionModifierConfig" + } + }, + { + "base": "{A7304AE2-EC26-44A4-8C00-89D9731CCB13}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ModelPreset" + } + }, + { + "base": "{3366C279-32AE-48F6-839B-7700AE117A54}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialComponentConfig" + } + }, + { + "base": "{C10E7B12-BCB6-5872-810D-D597F123DB61}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{744CCE6C-9F69-4E2F-B950-DAB8514F870B}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Physics::MaterialId" + } + }, + { + "base": "{60A9A069-9C3D-465A-B7AD-0D6CC803990A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ComponentId" + } + }, + { + "base": "{02F01CCC-CA6F-462F-BDEC-9A7EAC730D33}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LevelsGradientConfig" + } + }, + { + "base": "{571E9CC8-AE35-5EBA-9A82-4012B60E7581}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{9E576D4F-A74A-4326-9135-C07284D0A3B9}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AtomToolsDocumentSystemSettings" + } + }, + { + "base": "{D350732E-4727-41C8-95E0-FBAF5F2AC074}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AnimationData" + } + }, + { + "base": "{A0CA880C-AFE4-43CB-926C-59AC48496112}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Boolean" + } + }, + { + "base": "{A5A5E7F7-FC36-4BD1-8A93-21362574B9DA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Descriptor" + } + }, + { + "base": "{742F8581-B03E-42C2-A332-2A47C588BD1F}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "TypeExposition" + } + }, + { + "base": "{8F19B652-17A5-5646-9001-120CE0D5BF02}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{1CD41DA9-91CA-4A57-A169-B42FC25FC4C3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ScaleModifierConfig" + } + }, + { + "base": "{1DD3D37D-0855-44F9-94F8-76F0128491A1}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InstanceData" + } + }, + { + "base": "{D7439508-ED10-4395-9D48-1FC3D7815361}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Contact" + } + }, + { + "base": "{382116B1-5843-42A3-915B-A3BFC3CFAB78}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "DescriptorWeightSelectorConfig" + } + }, + { + "base": "{D9C0BF74-6FE8-536F-9432-C964B82700BE}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "AZ::RHI::Handle" + } + }, + { + "base": "{02766CCF-BDA7-46B6-9BB1-58A90C1AD6AA}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "BlendShapeAnimationData" + } + }, + { + "base": "{2AB6096D-C7C0-4C5E-AA84-7CA804A9680C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceTagDistance" + } + }, + { + "base": "{EB603581-4654-4C17-B6DE-AE61E79EDA97}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MaterialAssignmentId" + } + }, + { + "base": "{515CF4CF-4992-4139-BDE5-42A887432B45}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CryRange" + } + }, + { + "base": "{9F4E062E-06A0-46D4-85DF-E0DA96467D3A}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Tag" + } + }, + { + "base": "{A435F06D-A148-4B5F-897D-39996495B6F4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RandomGradientConfig" + } + }, + { + "base": "{B7463F12-C981-4A0B-ACEF-4B26D431D797}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Unit Testing" + } + }, + { + "base": "{53254779-82F1-441E-9116-81E1FACFECF4}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "CylinderShapeConfig" + } + }, + { + "base": "{A53D2A38-FFE1-4828-B91E-4D5A8B712BB2}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SmoothStepGradientConfig" + } + }, + { + "base": "{D435DDB9-C513-4A2E-B0AC-9933E9360857}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SurfaceDataColliderConfig" + } + }, + { + "base": "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "PrefabInstanceSpawner" + } + }, + { + "base": "{C6FFF25F-FE52-4D08-8D96-D04C14048816}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "ShaderSemantic" + } + }, + { + "base": "{35CA7415-DB12-4630-B0D0-4A140CE1B9A7}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "LmbrCentral::QuadShapeConfig" + } + }, + { + "base": "{1A4C0EF2-BF98-4EB3-B134-A6EF7B31B62E}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "InvertGradientConfig" + } + }, + { + "base": "{A935EBBC-D167-4C59-927C-5D98C6337B9C}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "RuntimeData" + } + }, + { + "base": "{8379EB7D-01FA-4538-B64B-A6543B4BE73D}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "Vector3" + } + }, + { + "base": "{A2589BD4-42FB-40BA-A38D-CFCD6E9EA169}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "MeshData" + } + }, + { + "base": "{E6E7C0C5-07C9-44BB-A38C-930431948667}", + "context": "BehaviorType", + "variant": "", + "details": { + "name": "SliceInstantiationTicket" + } + } + ] +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h b/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h index bd37ab0e2f..4d7eed7075 100644 --- a/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h +++ b/Gems/ScriptCanvas/Code/Editor/Translation/TranslationHelper.h @@ -8,15 +8,8 @@ #pragma once -#include - -#include -#include - -#include #include -#include -#include +#include namespace Translation { @@ -27,447 +20,32 @@ namespace Translation static constexpr const char* MissingFunctionKey = "Globals.MissingFunction"; static constexpr const char* EBusHandlerOutSlot = "Globals.EBusHandler.OutSlot"; } - - static inline bool GetValue(const AZStd::string key, AZStd::string& value) - { - GraphCanvas::TranslationKey tkey; - tkey = key; - - bool result = false; - GraphCanvas::TranslationRequestBus::BroadcastResult(result, &GraphCanvas::TranslationRequests::Get, key, value); - return result; - } -} - - -namespace GraphCanvasAttributeHelper -{ - template - AZStd::string GetStringAttribute(const T* source, const AZ::Crc32& attribute) - { - AZStd::string attributeValue = ""; - if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, source->m_attributes))) - { - attributeValue = attributeItem->Get(nullptr); - } - return attributeValue; - } - - inline AZStd::string ReadStringAttribute(const AZ::AttributeArray& attributes, const AZ::Crc32& attribute) - { - AZStd::string attributeValue = ""; - if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, attributes))) - { - attributeValue = attributeItem->Get(nullptr); - return attributeValue; - } - - if (auto attributeItem = azrtti_cast*>(AZ::FindAttribute(attribute, attributes))) - { - attributeValue = attributeItem->Get(nullptr); - return attributeValue; - } - - return {}; - } } namespace ScriptCanvasEditor { - enum class TranslationContextGroup : AZ::u32 + namespace TranslationHelper { - EbusSender, - EbusHandler, - ClassMethod, - GlobalMethod, - Invalid - }; - - enum class TranslationItemType : AZ::u32 - { - Node, - Wrapper, - ExecutionInSlot, - ExecutionOutSlot, - ParamDataSlot, - ReturnDataSlot, - BusIdSlot, - Invalid - }; - - enum class TranslationKeyId : AZ::u32 - { - Name, - Tooltip, - Category, - Invalid - }; - - - namespace TranslationKeyParts - { - const char* const handler = "HANDLER_"; - const char* const name = "NAME"; - const char* const tooltip = "TOOLTIP"; - const char* const category = "CATEGORY"; - const char* const in = "IN"; - const char* const out = "OUT"; - const char* const param = "PARAM"; - const char* const output = "OUTPUT"; - const char* const busid = "BUSID"; - } - - namespace TranslationContextGroupParts - { - const char* const ebusSender = "EBus"; - const char* const ebusHandler = "Handler"; - const char* const classMethod = "Method"; - constexpr const char* const globalMethod = "GlobalMethod"; - }; - - // The context name and keys generated by TranslationHelper should match the keys - // being exported by the TSGenerateAction.cpp in the ScriptCanvasDeveloper Gem. - class TranslationHelper - { - public: - static AZStd::string GetContextName(TranslationContextGroup group, AZStd::string_view keyBase) - { - if (group == TranslationContextGroup::Invalid || keyBase.empty()) - { - // Missing information - return AZStd::string(); - } - - const char* groupPart; - - switch (group) - { - case TranslationContextGroup::EbusSender: - groupPart = TranslationContextGroupParts::ebusSender; - break; - case TranslationContextGroup::EbusHandler: - groupPart = TranslationContextGroupParts::ebusHandler; - break; - case TranslationContextGroup::ClassMethod: - groupPart = TranslationContextGroupParts::classMethod; - break; - case TranslationContextGroup::GlobalMethod: - groupPart = TranslationContextGroupParts::globalMethod; - break; - default: - AZ_Warning("TranslationComponent", false, "Invalid translation group ID."); - groupPart = ""; - } - - AZStd::string fullKey = AZStd::string::format("%s: %.*s", groupPart, - aznumeric_cast(keyBase.size()), keyBase.data()); - - return fullKey; - } - - // UserDefined - static AZStd::string GetUserDefinedNodeKey(AZStd::string_view contextName, AZStd::string_view nodeName, TranslationKeyId keyId) - { - return GetKey(TranslationContextGroup::ClassMethod, contextName, nodeName, TranslationItemType::Node, keyId); - } - //// - - static AZStd::string GetKey(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0) - { - if (group == TranslationContextGroup::Invalid || keyBase.empty() - || type == TranslationItemType::Invalid || keyId == TranslationKeyId::Invalid) - { - // Missing information - return AZStd::string(); - } - - if (type != TranslationItemType::Wrapper && keyName.empty()) - { - // Missing information - return AZStd::string(); - } - - AZStd::string fullKey; - - const char* prefix = ""; - if (group == TranslationContextGroup::EbusHandler) - { - prefix = TranslationKeyParts::handler; - } - - const char* keyPart = GetKeyPart(keyId); - - switch (type) - { - case TranslationItemType::Node: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - keyPart - ); - break; - case TranslationItemType::Wrapper: - fullKey = GetClassKey(group, keyBase, keyId); - break; - case TranslationItemType::ExecutionInSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::in, - keyPart - ); - break; - case TranslationItemType::ExecutionOutSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::out, - keyPart - ); - break; - case TranslationItemType::ParamDataSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::param, - paramIndex, - keyPart - ); - break; - case TranslationItemType::ReturnDataSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::output, - paramIndex, - keyPart - ); - break; - case TranslationItemType::BusIdSlot: - fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::busid, - keyPart - ); - break; - default: - AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type."); - } - - AZStd::to_upper(fullKey.begin(), fullKey.end()); - - return fullKey; - } - - static AZStd::string GetClassKey(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId) - { - const char* prefix = ""; - if (group == TranslationContextGroup::EbusHandler) - { - prefix = TranslationKeyParts::handler; - } - - const char* keyPart = GetKeyPart(keyId); - - AZStd::string fullKey = AZStd::string::format("%s%.*s_%s", - prefix, - aznumeric_cast(keyBase.size()), - keyBase.data(), - keyPart - ); - - AZStd::to_upper(fullKey.begin(), fullKey.end()); - - return fullKey; - } - - static AZStd::string GetGlobalMethodKey(AZStd::string_view keyName, TranslationItemType keyType, - TranslationKeyId keyId, int paramIndex = 0) - { - const char* keyPart = GetKeyPart(keyId); - - AZStd::string fullKey; - switch (keyType) - { - case TranslationItemType::Node: - fullKey = AZStd::string::format("%.*s_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - keyPart - ); - break; - case TranslationItemType::ExecutionInSlot: - fullKey = AZStd::string::format("%.*s_%s_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::in, - keyPart - ); - break; - case TranslationItemType::ExecutionOutSlot: - fullKey = AZStd::string::format("%.*s_%s_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::out, - keyPart - ); - break; - case TranslationItemType::ParamDataSlot: - fullKey = AZStd::string::format("%.*s_%s%d_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::param, - paramIndex, - keyPart - ); - break; - case TranslationItemType::ReturnDataSlot: - fullKey = AZStd::string::format("%.*s_%s%d_%s", - aznumeric_cast(keyName.size()), - keyName.data(), - TranslationKeyParts::output, - paramIndex, - keyPart - ); - break; - default: - AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type."); - } - - AZStd::to_upper(fullKey.begin(), fullKey.end()); - - return fullKey; - } - - static const char* GetKeyPart(TranslationKeyId keyId) - { - const char* keyPart = ""; - - switch (keyId) - { - case TranslationKeyId::Name: - keyPart = TranslationKeyParts::name; - break; - case TranslationKeyId::Tooltip: - keyPart = TranslationKeyParts::tooltip; - break; - case TranslationKeyId::Category: - keyPart = TranslationKeyParts::category; - break; - - - default: - AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation key ID."); - } - - return keyPart; - } - - static TranslationItemType GetItemType(ScriptCanvas::SlotDescriptor slotDescriptor) - { - if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionIn()) - { - return TranslationItemType::ExecutionInSlot; - } - else if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionOut()) - { - return TranslationItemType::ExecutionOutSlot; - } - else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataIn()) - { - return TranslationItemType::ParamDataSlot; - } - else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataOut()) - { - return TranslationItemType::ReturnDataSlot; - } - - return TranslationItemType::Invalid; - } - - static AZStd::string GetSafeTypeName(ScriptCanvas::Data::Type dataType) + inline AZStd::string GetSafeTypeName(ScriptCanvas::Data::Type dataType) { if (!dataType.IsValid()) { return ""; } - return ScriptCanvas::Data::GetName(dataType); + AZStd::string azType = dataType.GetAZType().ToString(); + + GraphCanvas::TranslationKey key; + key << "BehaviorType" << azType << "details"; + + GraphCanvas::TranslationRequests::Details details; + + details.m_name = ScriptCanvas::Data::GetName(dataType); + + GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details); + + return details.m_name; } - - static AZStd::string GetKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0) - { - AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase); - AZStd::string translationKey = TranslationHelper::GetKey(group, keyBase, keyName, type, keyId, paramIndex); - AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data(); - - if (translated == translationKey) - { - return AZStd::string(); - } - - return translated; - } - - static AZStd::string GetClassKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId) - { - AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase); - AZStd::string translationKey = TranslationHelper::GetClassKey(group, keyBase, keyId); - AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data(); - - if (translated == translationKey) - { - return AZStd::string(); - } - - return translated; - } - - static AZStd::string GetGlobalMethodKeyTranslation(AZStd::string_view keyName, - TranslationItemType keyType, TranslationKeyId keyId, int paramIndex = 0) - { - AZStd::string translationKey = TranslationHelper::GetGlobalMethodKey(keyName, keyType, keyId, paramIndex); - AZStd::string translated = QCoreApplication::translate(TranslationContextGroupParts::globalMethod, translationKey.c_str()).toUtf8().data(); - - if (translated == translationKey) - { - return AZStd::string(); - } - - return translated; - } - - // Use the StackedString to index the translation keys as a Json Pointer - static AZ::StackedString GetAzEventHandlerRootPointer(AZStd::string_view eventName) - { - AZ::StackedString path(AZ::StackedString::Format::JsonPointer); - path.Push(eventName); - - return path; - } - - - - }; - - + } } + diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp index a31444921b..6e8550b1f8 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/DataTypePalette/DataTypePaletteModel.cpp @@ -243,7 +243,16 @@ namespace ScriptCanvasEditor AZStd::string DataTypePaletteModel::FindTypeNameForTypeId(const AZ::TypeId& typeId) const { - return TranslationHelper::GetSafeTypeName(ScriptCanvas::Data::FromAZType(typeId)); + GraphCanvas::TranslationKey key; + key << "BehaviorType" << typeId.ToString() << "details"; + + GraphCanvas::TranslationRequests::Details details; + + details.m_name = TranslationHelper::GetSafeTypeName(ScriptCanvas::Data::FromAZType(typeId)); + + GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details); + + return details.m_name; } void DataTypePaletteModel::TogglePendingPinChange(const AZ::Uuid& azVarType) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp index 45316778fe..0bc54a493b 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp @@ -26,12 +26,18 @@ #include #include #include + #include +#include + #include #include #include #include #include + +#include + #include #include #include @@ -50,9 +56,11 @@ #include #include #include + #include #include #include + #include #include #include @@ -63,7 +71,6 @@ #include #include #include -#include "AzQtComponents/Utilities/DesktopUtilities.h" namespace ScriptCanvasEditor { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h index 6a3c95d1e1..ca25013d35 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/DataTrait.h @@ -182,7 +182,7 @@ namespace ScriptCanvas static AZ::Uuid GetAZType(const Data::Type& = {}) { return azrtti_typeid(); } static Data::Type GetSCType(const AZ::TypeId& = AZ::TypeId::CreateNull()) { return Data::Type::CRC(); } - static AZStd::string GetName(const Data::Type& = {}) { return "CRC"; } + static AZStd::string GetName(const Data::Type& = {}) { return "Tag"; } static Type GetDefault(const Data::Type& = {}) { return CRCType(); } static bool IsDefault(const Type& value, const Data::Type& = {}) { return value == GetDefault(); } }; @@ -198,7 +198,7 @@ namespace ScriptCanvas static AZ::Uuid GetAZType(const Data::Type& = {}) { return azrtti_typeid(); } static Data::Type GetSCType(const AZ::TypeId& = AZ::TypeId::CreateNull()) { return Data::Type::EntityID(); } - static AZStd::string GetName(const Data::Type& = {}) { return "EntityID"; } + static AZStd::string GetName(const Data::Type& = {}) { return "EntityId"; } static Type GetDefault(const Data::Type& = {}) { return GraphOwnerId; } static bool IsDefault(const Type& value, const Data::Type& = {}) { return value == GetDefault(); } }; diff --git a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp index dd1f8074b1..a0f26bcec9 100644 --- a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp +++ b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.cpp @@ -34,6 +34,7 @@ #include #include #include +#include "Data/DataRegistry.h" namespace ScriptCanvasEditorTools { @@ -832,6 +833,33 @@ namespace ScriptCanvasEditorTools SaveJSONData(fileName, translationRoot); } + void TranslationGeneration::TranslateDataTypes() + { + TranslationFormat translationRoot; + + auto dataRegistry = ScriptCanvas::GetDataRegistry(); + + for (auto& typePair : dataRegistry->m_creatableTypes) + { + if (ScriptCanvas::Data::IsContainerType(typePair.first)) + { + continue; + } + + const AZStd::string typeIDStr = typePair.first.GetAZType().ToString(); + AZStd::string typeName = ScriptCanvas::Data::GetName(typePair.first); + + Entry entry; + entry.m_key = typeIDStr; + entry.m_context = "BehaviorType"; + entry.m_details.m_name = typeName; + + translationRoot.m_entries.emplace_back(entry); + } + + SaveJSONData("Types/BehaviorTypes", translationRoot); + } + void TranslationGeneration::TranslateMethod(AZ::BehaviorMethod* behaviorMethod, Method& methodEntry) { // Arguments (Input Slots) diff --git a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h index 0f84c48b22..c6d482e115 100644 --- a/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h +++ b/Gems/ScriptCanvas/Code/Tools/TranslationGeneration.h @@ -131,6 +131,9 @@ namespace ScriptCanvasEditorTools //! Generates the translation data for the specified property in the BehaviorContext void TranslateBehaviorProperty(const AZ::BehaviorProperty* behaviorProperty, const AZStd::string& className, const AZStd::string& context, Entry* entry = nullptr); + //! Generates a type map from reflected types that are suitable for BehaviorContext objects used by ScriptCanvas + void TranslateDataTypes(); + private: //! Utility to populate a BehaviorMethod's translation data From 9c9d2c70f5c9593a4087d1d44499628b8db00f2d Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Mon, 29 Nov 2021 18:26:31 -0800 Subject: [PATCH 16/72] Making sure to stop pulling server logs before terminating the server process; otherwise we might be pulling an invalid process-communicator. Updating AZCoreLogSink to also allow for piping warnings/errors/asserts Signed-off-by: Gene Walters --- Code/Legacy/CrySystem/AZCoreLogSink.h | 6 +++--- .../Source/Editor/MultiplayerEditorSystemComponent.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Code/Legacy/CrySystem/AZCoreLogSink.h b/Code/Legacy/CrySystem/AZCoreLogSink.h index 39a6131262..9d732b3dd4 100644 --- a/Code/Legacy/CrySystem/AZCoreLogSink.h +++ b/Code/Legacy/CrySystem/AZCoreLogSink.h @@ -127,7 +127,7 @@ public: CryLogAlways("%s", message); } - return true; // suppress default AzCore behavior. + return m_suppressSystemOutput; #else AZ_UNUSED(fileName); AZ_UNUSED(line); @@ -147,7 +147,7 @@ public: return false; // allow AZCore to do its default behavior. } gEnv->pLog->LogError("(%s) - %s", window, message); - return true; // suppress default AzCore behavior. + return m_suppressSystemOutput; } bool OnPreWarning(const char* window, const char* fileName, int line, const char* func, const char* message) override @@ -162,7 +162,7 @@ public: } CryWarning(VALIDATOR_MODULE_UNKNOWN, VALIDATOR_WARNING, "(%s) - %s", window, message); - return true; // suppress default AzCore behavior. + return m_suppressSystemOutput; } bool OnOutput(const char* window, const char* message) override diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 7cc6fbc1b5..fa855cf28c 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -160,6 +160,7 @@ namespace Multiplayer [[fallthrough]]; case eNotify_OnEndGameMode: // Kill the configured server if it's active + AZ::TickBus::Handler::BusDisconnect(); if (m_serverProcessWatcher) { m_serverProcessWatcher->TerminateProcess(0); @@ -172,9 +173,7 @@ namespace Multiplayer m_serverProcessWatcher = nullptr; m_serverProcessTracePrinter = nullptr; } - - AZ::TickBus::Handler::BusDisconnect(); - + if (INetworkInterface* editorNetworkInterface = AZ::Interface::Get()->RetrieveNetworkInterface(AZ::Name(MpEditorInterfaceName))) { editorNetworkInterface->Disconnect(m_editorConnId, AzNetworking::DisconnectReason::TerminatedByClient); @@ -251,10 +250,12 @@ namespace Multiplayer // Stop the previous server if one exists if (m_serverProcessWatcher) { + AZ::TickBus::Handler::BusDisconnect(); m_serverProcessWatcher->TerminateProcess(0); } m_serverProcessWatcher.reset(outProcess); m_serverProcessTracePrinter = AZStd::make_unique(m_serverProcessWatcher->GetCommunicator(), "EditorServer"); + AZ::TickBus::Handler::BusConnect(); } void MultiplayerEditorSystemComponent::OnGameEntitiesStarted() @@ -315,7 +316,6 @@ namespace Multiplayer // Launch the editor-server LaunchEditorServer(); - AZ::TickBus::Handler::BusConnect(); } else { From b56c6cce8949bee6c65ac8858c5e186f0f0c3dfb Mon Sep 17 00:00:00 2001 From: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> Date: Mon, 29 Nov 2021 19:47:17 -0700 Subject: [PATCH 17/72] Updated DiffuseProbeGridRender precompiled shader Signed-off-by: dmcdiarmid-ly <63674186+dmcdiarmid-ly@users.noreply.github.com> --- .../diffuseprobegridrender.azshader | Bin 218052 -> 240486 bytes ...fuseprobegridrender_dx12_0.azshadervariant | Bin 30631 -> 32739 bytes ...fuseprobegridrender_null_0.azshadervariant | Bin 589 -> 589 bytes ...seprobegridrender_vulkan_0.azshadervariant | Bin 22565 -> 23141 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender.azshader b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender.azshader index 56009d56abb497027e6d3aea639d3d232d0799b2..e7f4577c9acb92aa91ea989e7bba8ef99c4f20ca 100644 GIT binary patch delta 7474 zcmeHMdr*{B6zAOC<&`ck5f%Z##1N2O#78!2>}V4!g5U$SQP@v+6%u6CT{WEs)U?u4 z#iGU^UOq7Yc?8R)G%ngy~R%dLIor6`&M_cu;$ha}-nIguq_@{)M@Dt@#)V zh3S|%Hjkn#%m*h1#)O32-KD|Q>V)>8N_y>Mi0@jXPstesjWO zle~gy>kOvsBo zl}hG87-N~ZL93zgWsuq>sC6$>g@S3B`SZ;MxA%3J!m>4hm%TI@zz zy&DFg^XKgQ2IH)uTFNN}t-Q_cv&O1z2CA(G1Fo}aDWw*I(SNY9<8*P6HHk*72CZ1% z#Mb(>OGX~Y?=9XoRDj_OEVxS%;@$Mapi>tYCJdu2wIZqF7iRL__`%A=#^w68^t=h) z_cUaWo0~R^ssj`ejyl8J-t7#*9%gQgpati6o28C*p^ImE z>0Ub7u*V>=2=?0@*8%=l)uhVAC%KSr8w;Yrr};2f*9GCuT3f)~{AWffz;59T6tiy! z`tNxYjlH7C@4Phpcosl$jXZkGGBw3EaZ^bQXfXYt4V^(zxb`bsTXtV~6Z&KQo>Vlh zS5tQ<53}_2qmP>)jpwq{tFw#UU2dEfIi*vn5A>GTz^?)35$7vkI&p@FW`4OMv;#Jl zQFbT^~YRJDCK5K`5b%rJ{@tdEZhP5*nkM>Cr_dm_jmEO5o zA1)jb4q;wES`E^B}>k$3P{PZZbhQ zo{oPV!bv|5bW}Z`1>(*RM#|Pc(zC>uN~f@FS3UADbR+Fl#@i{&0Bc-k?JF#tjNeOU z-dP{|WCToh6{}A|09)W$>*tmgQRd7X}zanSR2sOi(Fnl3aHCaiHVEYYEM_2$R)7Y z1o4uCv4_1Px?%5$m7(3R=Z3w1SJ;05?6pdX66R<4DfEv?QG`fL+TG{x=!q}#KeTwr zKd35(waT6ksV>U5R4#!&dTnv;Ul7q1m3UpP_(N-y=*Xt?Hrub;zc_WXmlz$(#s^UO H7=`Y4imktX delta 2850 zcmeHJZ){Ul6yH7Xv9;Z3`!;7cNXJ97x(&8fkN_&M0Wx&_X*3xwMrdXPni)bQ&xw3M z287Y!T6eM?G#aV~7j&4C$MT}$3Sq&GFgA=8B`GU$Zpuc}#6@I6^sR5D)enXbet^ig zbI<*qd(XM&ch5OP-x<5wruvI`UO3%Ig(qTlo{y)vRq~$X65E$@2@N5z|l&MjBkKJS^O@%HAV6Jzyl<{%xxiY z7Uxl%W9)Y$l^%!HEC-KW&udMEB_yW7(-hswrjgSGIau2Fs%-5)sF%e{%Ym)LQ=CP& zuBU#^(uG^V7aV3;q%HC4{kmCGDkYFs4D0joS38A-zv>px6Z z;%MX{MU8BDmh5iKx%-3E#e>9|p$|xXM=RdEDq(b_5d%N(rmdTph(o_f_@+LKyw7qK z(JDkO&Qf(1%7t9WI}7jrUCWHjyxQ{T&KFgqfa*B zi$6-#U&S?%y+XAMg(PzBRo%8-Q`LRUh`u2S?Xro!nhBNkk`2B|&X1Zj*^sP=C+so1 z&a?ly;POY?x)rgAeV=u&^K*%^!NY2Gld&o)V{Nn1-8h|uE_Um#5AJ`)%UH5{(&UT3 zbwg6dw%PTMbUr@6qkh5C6lLHYZk?bEZUadxD_HC8WI4)}?a-tD&r2wY2S87*F}72a z3ZH=j%($3|ffK7@8vNnOe2N|hr?y}HF&wz9$3wvxxT7-(=r7?mYe3g0P(WoFV8r(V z2|)A0*EMU`q5=$@teM1)u>$J6!Peb2t=FU@K$LElZQ%`HhQEofziEXMb z?$ZR%?9m+WQ2Y(VcLe9LHc| z{Jwnhe*rcMFh~NZs!SZ{(OxQcv1($V@Kc_=ZOckm&%?4fuXde*_IOz!bx}UiuPlJx!#eT>nQfvl3(DCG zfJLz~ai3@EPq@!Bbv*hT&vbE~sguJ7X2D&d@;jIxnyphXJX(0~Ob?!a{vCr3^F!qr x9k#R*OT~HDThJWQE8b1qITjx*{_R)2U8uNQxYfLFue-r|w)d6SCJOsL;V(9*QL6v| diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_dx12_0.azshadervariant b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_dx12_0.azshadervariant index e9893c96dacf7ba371df65d3b895f19b56b0a071..2565261d622427ed4e3e9c88d063b55d3d292200 100644 GIT binary patch delta 13780 zcmb`O2~<<(_UKOrl0Xs&gOCu0Ac!D{VK5*lCIOKlwBUfKs9_MLf+DDG9hwOc6)bR| zf=CVGfQpu>Dk?1rNPz;yNNvE#9~8ON3l^=H>ebu6eV{76|K8rW-g;e&68Yx6_qX>x z`*(8gC)~r|aMeLLN^i}_%aI7Zf1>Z=gU#hN0P}E#=Hp_6|7Fh74l^9A1eX1L2p$MoF0@L>#SS2Cod%M?WR$+li7B zUXK~1y=NcJ_Y4^`i&SU8>WGui_5ei&!;$Cl$sWB$=kgtuCA(XG%K6 zR$4o&5wy_HSrS}s)oN#@RT)KykB1nx%BXcaz*jbIr=uJ|?*9h%3-{`s0T7$D08L}9)vmGqAiijxwk@jEb zTl^mU-tLKQ>L>iqgvbc;!ax#C3ZGx5+Qvf>`+D^W?<3M z>6N+uZOwj_0gG}7O9}~#I`O_4ghe--v314G6yeU#y_OYnUoH?vgHhSmiUJGq#!U=U z-96K94YbHb{0Vo}=REBWp-AMEGHF zAjR~7SJMg*VGWtrt?;yc^-~Ebj~qU*o1qKSDP4G}oiYfEI|G(f2Q2!1VOUT6;mq~s>Cv$DgxGor z$1E`vGXuBm%)JzH+B+=>e&Ws0!pbcw+Bs+Ahs6wm69e(AL1kpFh1#z=!2d+E-?bSU z|HShQv^k(Q8!bsn4tFIx2Ni6Xg|as;z!{)n8@(lXbu95z@uB~4Q)EVCaGzv00|J{D zN*i6Qjb_M7S8mmYqiIyue|=e;>3@D%{y1gWf1DH1Z+Va@o2eIfTw5I8)Yz^`gEN&n zkf!_==x53a%99-zVfGuMx5A0MmvV5I_+S);yw{2Raqz)ZF?j`irhqN0p7!u(DD9`c zR)-E#x|7bftzE&vGvj8@*0-LTu`N-Erc$leq>B%J2t&mLu9UE}hp?phVCwYce4)3u zjr@@l*~~1l|Ig1^J}YsiS3$t5=p&D;a88|G#vD$$#?Lg*SvU*`}92l22e=CF)Kc{%!y%Ug*7apoKjM@>Oyg(@jQ$l>xP^gDX6 zl}9<()WEAe!qmX0e8M0?89^}cRaO%WmM8}a=x6?J5?(nc5iy8S_UIYxRC34$yOfI$ zS2z%|eF*#_p_9T`TA=)fh6oZ7Cl3PuC<|H9iA2Paqzq3a;W$othlZ3x(?SCO0t;E! zg)p{}r0YD9VQBh+hNz&4N8s17kW*bqPYOwz>WLJV;yCwd$ao@>?M>h}ZeStLplt_9 zD)mInPT)90G=#nd8RZiAw^)crH`23{B+Y|i(DaCg%-@1IL6ek)e9(>LrIVzedm_X# zoN|eeEMRyrF;hn6|&y76Ix?|-Ld|Hnq zWm&x}*sZgeQ!HCl_sGZshYLpk#jvzI-9l0^GU+O(WCm@8mj6O!n;~=-F?tYd)ZLg( zsx~wwE{s4|7^jnz){d0qCiGk5ePqRl#hhz0KQ!EA9hGC_NYP`87=wsSU9Cwdj?~#q zj5Qoa@n(0Zf+ZrxVXtD24z~myG#i!>%d-{qAfbsiNh+|)OL{fi#q^?|XB^e9w3K6( zR;>zNL0C!WW-IiC?qqh(ur2p4qVVDLPHr}L{N?-4Mxwlbc@$;t=q+#>6)WxL<6YzJoynJTwkz^8$a~1J z#pM34Mtan31Cl2Ny0(r9M@pu3GPmGqQyYQyK-_$a9LJ@8SdBk5I~OS)f00POmytPju3fL-TH^s4CCwyjbJZ6oJUIY*ts;Ur_^JtR0uO#fFsYHjCbP1`7Ba3K=$6*zrU z#rQ?T>29ydXR&UuO{`m9ho-v++h(>n1(TBG{CLHhwGQ639yjShn%UU-tw6lSs&0g)20LlPCsMKb4Hilm1dET2nI)VI`O;)& z_n=W|tek7WaThQ$C2%p+!7z;K*~Bq)q?}e#*+jx}9&u5vfV(S!Fhuq?G4S&cIO*jV zbCkjmuxr0!&Ix=7h>hFF$Y_UKgwmToO^8>Y9lzLpG}Ns#rF$&=a!RwbTwRR|>B!)k zc1jQhcTh7q$DFr@_q=t|5v;9;s334DgrJm7ak1%}19l|uNDGRM-?bx+of8<2iG!=W zGx=!J@dxwPL^EE{FW49@@eVeIm$E5k^RC$BH~m|}xm2238gcKKZvB1M@%4Q=U2imV zeILnQW-4+3y}yvuA82p2bE&E>Si94k+>zV6Utkh2D>ZkpDP5x8(RFm0qn6|4vI#`a7uB(LE`ePiyph4`}< zuQkg1*yPA(z2-z2&>iX8)vpAtEUDwCl&|kWKC9^EXa$`a1 zh7w&&AIU*AE6$dC18h;uiat|xKfJx{z?TR5;FF-e@qAJ4Z7_^E4ShxJT}2BsZ?~Tr z0{d91l{#F94P0@74VV!w*4N%}Zm9d>%7Ty^^|gLZ4c=eYx?ivN_I7IUxN(;2+u(JR z9;|U`@fRC|eJps}{fiski+CQDR~x*b^HqJ}Q!Fg3;ilr?UZ88k7D@~vzz`qEbEzAPXR-ac=ZxLWRg6`X|k^#*;Ru>p9Q7;ZWY=WH&D+T%Uv!^!U_mqqc+TY1l;{uTt0 zB`{WzucUtF2HL#&MsEFIjcT+VM~5|SQ;yG(a?1(KX}3zNCjoOh`Bs8I#H?dmt!MSF zKhCyZ+0U}P-?P4qeVRvsdoQL}Ko~p& zVeo+-Y5~TV7?rg7!IKnX!`4woxU>`{hl;p{RQ^mbI)z00q3GWVNnjxPB7pp_;Od#z?$Pjh64=rf8&n+w}IH9I482bIpaDbXnv!KWF|S*Yoqos*)=^b1#b^ z(6rE6v4lbQP7H0}Ei~FZ2vthWM2Ggm7>K|H4p^evN&*o`3TK>|4Vuqjiz&joD+a*lCy_RC_M@*)!IY zXPU8!s}CVbviYOb9qGH%Hisu|7wy>M!Om$(<`Q6h{tI$X|U5UQ`$dU%|=>UR~wG;bD9Ug!_R^IvYH!wZYPmkwxtJfAeU}8h{Y~RUel5>cam=#8@@t;7GaLWWvsflxR!oa${dMW$6pW4dXI> zp-WW@acI`MI5|Rfa~C+p#VW)ny0ehokW@ZSW=0GJt=b}=c#W@_>yEj%DTnvP6-Z2Y z7p`6eM^+0y&NriEDrfupKlO3&zTwf(09~K?N}z8lmN<=vh#*KzM~%OSi)hX{T{-7F z$8!u*Ftau^HwCjE`@E&MqjePX^Zj3``&%>}y3ym0wWFFrt)^p`$7~-HpTOm$ihLYXi8pTW zo>m~_sean2JoW9|rE)4eEZq+}4=K)LN}ub~;N@LYdzQQSeD&f}_29y<)_}@A{G-{} zBCItg#FV+Kj)82a$UL^{48>i)VUrOG7)FAwFvf+4cZn7f3-pJ7eq&+-1 zJkZinFg&bo)2MZ=9fx(T18o{z_fd6!znZ7dY=0%512Mb_wOlb*@>Efdr9JN0njYt_ zUvXH3rR#7Wj|(0*J+45?Cksr4`h4woAplW|w$u+y78pBEsQj zUG;9b!sV6MSHqyRrNv=zNJb3=f74JZ*6pR@7PgZ8)Jhk*4fWVXkyLU$is5WawOD?| zRbY|>1)+N@rY>4V0X4nUb04}5a)y5ej1j;97^K3n0qx`dj^hJk9sOWPmCpttJY>4U zP5Vv7r_dr~CXg*e_w^R**z9{~NnZ@>K4fLZnA;a>DY7?5F*RVX_moiKAVN?;z`l5U z*yNmyJ_FdK=adT0dU@M7czgTSRo8gD(Xzf!K!rG;!8OA}!i=*B3i@nh55%$$AeL1! zt_Wd&frIKcOx|&@tNE}ib9D>_vi*QWi<=Mq2JQWapPuMS&Jda=cqGIXm zhfD1Og^qW_9)u1?FNorT5M% zlhqpZ4$0vqmoO_CTS37md3y=R?pVXl$$hbjjH5?U1@E3>Gh|jU$52c zVOeX|W@<`|@2s`H+irbd1_kkQOLe(bzn#sqa((=qWQ0cxk}xxGXYq4*Gy*gCHZj&b zE-oM<$m_UTqpLdWNGVz%VqDm$WiU-M4qNajOlER4jV-M3T2bL;dABXtp4ZQ)zfCOf z&(s(0gl8h!QJ!lSt^Bs-`P*#zj)c>ZRwt<8f$=|mAD8rR2R?yfIKDm+iwcO2bX zT+^6&yGsI*AV!=&!dvbQ309h{HKxDMg3ZcpsIP;^H#)`UQNGQ%v2E;u41?8L?O1<| zrVUK)EKxAaW3dJ148i3)<8EirzPsg?(*>bCRNQOVoL&+@wRb_c?X`y+V&bs5Z6ap4 zV`Sj*FeLnEi7V&8*z1e0)pESA3V-)H4bF0-+(>I|QbwO(ocNW;<>NYxjk8^CHOhXZO{2!r675x1T6mh}>6q$=k z9n+zF_1y6oG0Qk(2*nYZk_Z{SId8)>lb9}Ce|MSlH!ls*3vGGNc#df6jmv+(ewli4 zo}5F8V^ZM%!f&%4*G_SQKk^AZ_Rd8SWpiAm4lilkWo?fvju1q@jz4so$TBAVDISRp z%%mF*a%s(6MhjPLfinykLEW9K@i{-C5l;5#SF}UuNwE=X;2eirjHWoVagWhM&IveS z-4o|LJ<95YFFtwyLh>#kNG$Z^g84pShcJqiKXM!wg05fQMy*>Pv5nb=l`#*6AqWY6 z`@l~y{M5nEIQ-~?#8xk;BXWPhIR?(hq=+Dq)IUnm75@H4iow(=wDi>!TGG}vdbr|K zxN<}{Hyi}@>k)=InRonR_Gc)79sNhv?$YJIq#a6-jJWT6KvWeGVz0IeR+yU ziO3PvKNCSA;$=XHuwT+Mc&C`jDTMGw6L*4U=^2*~3X9SA7tWIO(Clfd*r_`Ght^JC zbqn1Cmj~mEuTv_B24)Bu&VWeyu&@Ykg(y!oxKGh8Te^v`82Ccptl<+u$EAq{TIW+4 z`m9pA9%EFO^=~XHWmP1@*kJK<7S2hK9k`4_%=TI?H6y_GL^xl`EPFHffP{7#6E{=z zqFSyeU3;y+kJ7$LKWPd*t%42krJ`SG$Ckz#*}b&up;2Y>HIXs6XbyHj+~NCPF~4Rk z$r%2S65wU>z{_MdUdC54>JV3cy$6CvYG)BKrU$1;%>?d(XlBiZaoHciM+swZ}5m~IMihLiB$eKQ5sfVHYb;JjDWAaM9Vi?n?oIXJkM}~YxK4V z-6Y!bzq;86I|csq?*wWEIq9s4`%!&kGenPTYJ~x)C2s)~!S!Z+;`bQm>%*gcMWvY77^xaFijO2)KZSQ_FJw1pqp%F@gt( zBi6jf&Z=$5`U!@5tb-WxpHG8Dwo8oFarO^?%iBErlvy^CRh&(+mZgA3ki@+hw-IqO zcZsLCgETWW4`{)`H08mxJU|aPZ+*uQs7fS_foPHVYU`kIW_!XRVf54Gh`5M)U@oXYB1KMhHfR@`Shu zq!2bn=`6&Iz?Ey9^T!cxOCms;a2cETVOwv-t%hl>gf=AgC))CEG!rC_Z7YOS#T@N!H>_5y?H0_y2Sdza+Sh83DR|t!e{5J}J$YzQet~5V$ z_Tce|e}hM6?@it1um8?}y4(D)U6e4bGMMAAicjJkT4qnjqx%(IEeT{}-A>>Zll{ckC+HIr-!He+NjEi{zc>f1o59RG0-J z2IaI+xs@mKycox6qan)@kv70g$5@COFjFE)>I*EX1gHFthR70;N_PT32WIF*@_;~@ zcp@3aIAt>pVL=l>p$rxx+1rgUc9Eo~JP`+=LO;@w$Sp{vFM)rTg(-H#zN5EasBqm9|;MkI^u~0p2R8t8BG#c(Wc_x6nx5^hEKmNwZg@qX8gIhB6Km|3U9m= zUB`bPSBzfZTN~YM&brmZYi3f8KKxu?j-q$@9)tvr3Z)8M@OebkN8pavn}co>%r`+y zO*5o4rZRiIfX5Y>XG6S|1h7JiW zaB=8Mp%ob)E@C9cI-*tqX{6*hc?5MKS{U##DK$=>O7%uf1J_aY%8EHeDBZSYo~ZjM zFbGG+zb|5Z6gwBawd}Tmzq^3)Tr5Wnm!Qg^L5YZgkAy0Q|LqL2trS;sWkIb+&2>-v zE7f&SPvk;9F=4Ugvq1tEW;_iwuC!C`M*avvn6fD`Hf>W%()Qiyo3?L`O*73v9$f2Qlw+tScKw+_mTPC((^DBO8M)?6|EZO;6$WGD^j zmMaYQBY;*CY>%%VBy3USzX*6}uzxV`gI6XO<4qNNOT(~I%i99|tJ^JjTc0<$3ZqpL z3|FbJvf!^s(A}9o; z(A`p?8+q*z0WE8#SiS4dI*Ba zbwGy#)`A4w`xrR@g*YfZz`0jYGLiJ^cm)-$a7nWdOS5-rhLyHxUgK<~V9-D22bsNS z>JvMR^)wM|eb|Rrj1s&;Oc$1LDw`#1lbL~b7N5k*k@05Y(CvfzLchvezh43{x+;Yq zEVihR(FuzwQ99ABrQNN!ohY-`#K|WNlfjrHV&#K|+iC>d=LrGTbJ;}2`#jpmE64}_ z9aQyXHv_2pH3KQa?pN5oW6|1}K1mM{7+^uhMTxUsG{yG5gI8PL;Hcm;PmTOjN9zwX zG`4@4Su>4@pw_rDX{*f0>fb39arN;q_Oxi6ZA?o7`4CF;Yhktm+`+(L5+ z#$uw+ywvwkg^DIr7IVL^$!uq-m{TAMR#}tOA~&*vV&#tb_~hN`@F+jc!%QLphw@;rG1Y42+t6^< z<2sjzeK-v+1f!PqHMQVLsxdOL#&XjTOv{`qp-vxEqFVfhz0LVDv#e-NL;jiEBCH;q zniL~9Y65a+v2HD}h7E7{7;AuNC&ub9Ze7+857PS& ze5#5XX-c0DSFP)9T^=J{)BI{dJN5v7IhjyU58c8)hiTq*qe9v34=_y5kX%!f96q)< zm8%~6R`kE`akm1bALnIy;>;EmRlCJ?+ z^&Aeha>4$=2--V5FsA8P_Cz^6fYnts13Kk!$JlZ8=&)vj$7ye5EWBNbv-Oz)iJlA$ zYul6q;4h%FBL#<5%l0Qd&or_^FR~U&?6N^C>ILCngJ|ACz>D4Vx2H}S?MgZ7)(KQx z&S(Sj@$wic;YE|(pOY#|B3M|q$kPKXY{n-3ja1>V;#fhFD9cFF^xsL9T_tQ$?h)Pr zhBLzu{+v`1uRy$uIvdM^c=uPNs%7)>KDaGw{tKz1Y=`qSiA+8B4^F&;WTEMGr9!Ix zz8l-93hJqNYH4Zc9hXuL@fxh1c($D7pNjghXH(@dVB@?yI-0E%-OP5TF-Adr?Il55 zz)PdY*=(wO19Vt?=Q-A)iET@5!U~LAEUV$Zp^w>Y8f7mg&2Ud1NE0=-vXRIZfZ%GA zI49=ycz^W_TbV{lU>+UA8nw2dZHhl9{=TAH3&0$=ml~#?HPZfP0?-s924;-**Wb&otbAgQ`}8 zKf0L|2<{$udHjy}RXbM3r)}Q6eMKzPR^d&C9hNcR^Z!7dhDsg1u%K5cysrx%7{kcR zVEKG_*Pv)f)!6mDq`he2nFja9vUW%XdXi}Vsc)O0C3EQamfJ}!u&86oru5X!n-f;2 zg4eeKum7XhnPx2h&qPjXzF4Z!d};h5&FD$W<@YXk&da%UIeGLF9eW!EBk+)YoPN(9 za)O=@UPq4DPRZN%2UDBwg@h({H`r@5I{8Z2`$%Oqw3cxwT@U4jVt*r2^y5nn_ zft$azGxJMTO%Y_T+N3}T+czOC$^&+^xW1Vbt1P3d$9lU-s_HTb)x*LuT{lsXdPHAc z1H5TtWf@&wrq4<^ zAI%nw&45D}$8)Q4avzUB4nLX;KK6tWZXT9#{dd?@;7_c?k{iP>r@5458eVz3yJI$b z*5j(DZ#^J~TK}$fAjBs#mUO8KcfACJ_59IXH~P`}moU;=|NcW42&4O^DAF`UnwLH$ z!cb4oi={4pq5WcqpYB{E+S00KVyh{rf^l}9gc0)E>*Ly?2*UG7+sU1_FY-_73oT5% z28K1=8Xcr!|MDW)`s~*|?mw-5Hlpkp1~=W(0hH@sUXmvA1AgF>+&4NMejn2*<4;J_ zt2>2|>z$Zd^|*QhX3EyU>s5ercoJsFZ(fxk58Ek9Vc+0YTaML(K?cv3cFmiR`BYC$ z_y*Lts1^ItUDB}((ysRf8MZbxYu>XFZ~z@68ps~oDGTdi!v8>?RtUS`#qNMNfHO9XzOD|nA+SlF+^WRvL(XY=r@yep1(Xl*ZG|(RXG=E zU*ur0us*`nWk1KTerk6o9{0aFaAgPZZ)}s)g_~6%zgy$sm*?k%JI%))BU&P`tY{`@ z^6bSjp`58%s?^}|TC^QXb(=&CnxQXD0h61eJ05`U&QDk0z2`M>uP&+sd_@mV3kVGN za)VBDZg^k0ex>%T_l;V36Ug@h)a&7)3jCnMK}+iggq=#_++Q4{cnckWX>FZMNaU>v z0)jwk16Mr}aVOyIIWp9(cRSUs9hH(Ekaf?1whazqv~U74zrTV^5!gaGmhKM-2gxx^ z*4pFuz_)V`!V8K);jE{!0HRw?j%(MrYoeTSqM2mBsDhLW9xG3k^{>HCf1UXBH)$Rv zKTp3r&!8rcs>-9?&ZA3)dJJDOn7R3^Gq;HXn?d>V=~tMnikvSlxWH|w^YAUE2djf} z?F>^|;6XxQrrRp#8tqhV?s!c7{pGAo0+ebW zhH=5tg4%w*!|q;Y#*_-)Xi;+ZbQO=$ZoTkK({k6``CXS>Mce09(T~EVB;*fA22c~G zx_{o;Inn_SG>mqeg>fo940a|TcFVb(485L5)|s<&u2kDE*4X<$tI!t~n83>>hL#GW zmRJSHu-r?~^eeEhLP2~oqf=VwNco@OWKMzC)*QOr@`OZ_mC7CF8;v!YZ^u~yhw6;A z?iSdL;A}^64nnm(SBCPx&E*LFWra`bCbE_&f}Rwa&Yw$&wcFXo`7XYKY}F zBXI!}p;H`82^=g@YGg|EympW-a~E(4``~>*!IEUg@xkvliJnyDY==G*&{-3!=*hX0b&E20t;yVVwP(sdqphEPjxJb~!fa|kA%(E9 z6`pm=cxD&O!v1DP{xL961aB77E+rq$V%=NM1n6oPK{ij?p1v#HG(#-14nEy*yDOZ5 z-=lOtwrBEIP*A+v_}I3iM=2Xv0~RoVWqjS^<^rI|JoDY~Mo~KZ^zJn6`7+&)WrNP2 z4<9O?yHh!LXXRY==b`7&FXMyph#_j^Fv}<6e9_~)p$09y^ED?w{C4K;qHz6<=M7n( zhn29)Vr;N?Q10srIc3+OQ%>Xe4Y%QCuyFk`{W`yd2wdHk=qkLUtJO62p+eng<~NGW z;P1lUzfpuIW7r38j6=&jICcM6Z%H7=GX>n~Zxk(6sF0g~@r|O9pI`3xKl#&Kln!4k zY7$Rge-s>THr!u z(*^~K6)lSkSnW#y6)+$mS~e+EMB1koE%n(-+uvNQO8ffyzQ2D+$eo#U=A1KU=6=pR z_zm^x_o#Xfity@od)Lz$RRSE2;+Q)NgChfju(p|owU^4CI@Yk)3~pS%H;& zI|z~^A5@o2{ni-k2irI2rmE`hM=)q)ckAX3(@F1>a@#OPk*HN~=z1VGJ zm#v>2LuEr`xF*-Y_MiV^J=<%1l;Ia>pc)7fQ7b8QhzfLoAR{7}8eafGy4UlvJVT0@ zKkdk;w6=3@+&)i#4y@$6Rg-4h(obJ)OlQkf75pL)&%-p zzy#C>`D)MsS24@$1N|y6e!WsFrFd`Yyk}hlBNJoi&PY8s9HHKnk1=%9@BK6j2LOf~7+67(#3jlppBV5#+1DEU#+wZw~UQ$2eBC`6@BXHE2H> z#`kL5@|P%La?S$XzGf7zUwp%jA&2M?K?{QTCGe}2OOV)d$};K~THecA)IVX~n`H?i ztYu_DNInv;I%Rz7jWgg^+8&;YKp$0GzyQX-=#5w)Eq$T1&)2K?h%^}@4GI+2cp@?2 zD37eoNue)r!ff(FC+s!Wq?8%BeWuHs7mK|99RV_ugOzv$U<@ zlkqfXB06Vbn#ug?0e53?O1MWzPa#@gMKRP5od#ZjSZpstGX?DEz0@?za#|fA3-VV1 z_1j!~gI1`5e3eS(9WVGF-ZWS8;~DY+XNnpw^+<2*nMAsq{`po*6qxw)z->NeeL9^h6CU~nUfv7c83Cf zpRA3d!wKXqHd}z%+$~G!ruw{mg|_Xg8`vNRV>+GQN`MxvRuVYS(Mme}h|JaXsAL%u zmsN@liJwDS@I;V{Co%UJnE_RUfan{fh_J^iWh6bX< z;>3$RprR5Ky`2PE#6ulS46DWz^6Q2uJ8|Om9#B;oN_m$AHN-=;%P_3-pciK-V64^I5C2h?7HQcjT|-O2fzlx*MgmQ`oSMjXlQN* zTt~4(=bFIxC>}=bLJ6Nm>a`_=T*%_OXiDfMY@a3zeG`-gJx4pRFNs;GkN$10&_UQfQA#04YAAY;G+hqILN}5keC8v3^VbVy(RQ!wjV4v z+@d1}KWkBWlyQMY(|3leQMl$dtdKkm`z^Yog9_kLj(V2RN7eo?)p$~bvu0@5p`d9&@l5l9P^xR1>Q6uhA0ENMv|th!uOpz~Xo^V_ z<}ygi9PfJ(cLQj6S2@WP?)N_oMx`%791ibWG)l%sxw0-JBL^6=Dlb#{neyTEuS z+dKWV_rV9=t_4B@I10NT+_=AQVe^%R9hGee%ve_O%}^eG%;I5P4pR8 zE+4~~f3wYea+_ov|ANV$mSzAUKQ=JxKLRqXXt?DaGt$rzllMwZE!LHd;;j4h9+SXK znlBuxlsA-atuE-R1mb^HC8EIWSB-48FrRPsOpm7vngKPDW{l$M6P1XX6!kD-rS&7n zM@vPKg|w}uh@nnyFuM2_Sb2O1UK;NLhBI*6qG~u4KkmT6VH@{iOHP!8iV%T|48p zr6uf24il#BN!U-zmvM3r%^Q0CA6ve8-i|zvU9LoA-M&KLi^d6A-45p-C$E0``0Nv%@TXzt5*02_y3g4w!d-NC zN%*5`oXwDaj1|)oC1nbzk=4cb!#YnKx_C(4dF@PbUSIXKmSyt3&gzLJEknhf-Ni{P z11rW0RFe*fhmW)VpoT@!X!({QDhSN?fGQ%OOVqq#W7tX+&Fqe5rApy9GHDs9 z<)?L0PnU!7GQoKFu-lOF7PufbZksSMXxHB4G((w0&x?AbT(Ap`+pW6w)~?4~^3FZx zy5v1}$WxG$B>Y(r4o3`m;UX2C{4(mTNxQ2rsvC;u*OVI)vAWmpw)BNjh$}%DrAh8; zQ`=F?&t7Q!!oH>H^Glz%T=4R_)M(%A?N@Wb!}ChzWk2sL+JVpTAY+6x13+RE#1}`T zdoS7d;_eHre}6p1xmlE+&GDX%c*FrYWEOi%hq)yev*%qXrS1^M?%J0mOkt-b3R5>E zWW*WD&_-ZAd?Gjm+@iYuc0P{X-N{5}#p5UEok=daA37%{JA{3nDB;Uman?T>k~V@c zhdcq$y%I zF(ZKX@VZSjk{wSdEodgbZ~(~|-oMFGblo20*hqD(7U>&t-rMLh87c>1&64W|2RcTc zOYA5!Ytgs(w!li?(B0Q?S%RTYsiA)-y!;u=XB2N(R~(U59Mw>)EkTishQGYgI@~qc zs%)JEpVM8FQ(n~2^8y@IhPrmiwb}i0gXg6hrq5^YR~s&S`?`xhyIgtM?F_T=!j%?X zPNO5$6a-H12d^ZKskAlQJ|IdxGH7SZr5S5dPoH*Zqh)5o)@O$WHrM8J0IK@Z=M9(L zKD&Izt)BG8h#^OZxJG_(9H?Dzq(ZCi#vJS4DrD5*pPo#9KL`!+YaH##(H2NnQZ zPDV4+z`7mpf3Xa|IfBEPO@9P3@qm^!283{O())4yQ+B29-4hofOxzn6v@0nkE;&_* zq#TgJw$^)q46eNUV$;W)jf0JGt4uh@MK7izCXH=xL~y_`qgp?_-i8YCgHd9(c_M2- z9IaWh^Q&EAu6D-D~eKCUY% zaHSDezQkno9oKHPdkj*n5i3T@B))89Gw0$k6L=BJ^*47mQ!Xl@ix3!4c%-_x zrEl5YhQ4ZbLv?W{*nc;H@b{G7B>~r6Ug~zS(e29Xwe5bH>2}Hel&442m6pcSRl1x# z9@OPxwMz6|C=Vp)ciFlQNh^t%f=SZH*0c|&<6`3D6LH(q;w9sg=sfS13r(IN#QHr- zP+%;TB^NB7=pktkG4Iap=n(vt1+dA6Q z)_ea=zGE2s}U?MuM#d;FtF_w zx@fnw7zxbsb5M^T0G8+trm;u00KsJ8iw_S7TAQS#1e z`4O-W$P3iqWcN>XJkr{9UdG1AlLNG^$QDW~jxHIg7%Gn*!P%fJ!2X-tPzzaq5Gpe~UIW{ z#QMQYKb7|~PTUE#xOc!}sFYqG7@AVr__O5qEgqZ# ztm2h{Pmugc=~1QI63z(>f|Vz03Tq2bR(R1nb4+XV=LLwc?!70p(ckFMa%F0TZr~k% zL+lO{FN(IzlqMq_^cs+?J78utn`K|o>QEo(bOG%$DRG^a_*P*2mC^uB(29Yeu)+55 z(e^F%^5|xHq6U}T%Q;YTGo#|>!QNGe2UZ;^={QW!NRZ3*X748WjA@I#Z(ZRhqwqn{p{+%C$uk{+7g9>iZs%YNBlC6Mrm9XPe> z6W!}CYj6L;|0$?V@x)n?jJ(pIk9l79z0#r`$ky?k>hJk-uw#d&`UE)dC$V1ShKP&X0LxoEcK4?@?KKnP%zQb`%qo1)zWgUPmY`@yTkNbZyx*( z85A6jmK216pNqq^dp`w(ttq9Qh_)PfuZ(tow1_Uc0vaiha}tmqrp*HEwdt_kU6ic~ zd_!m~6ELNPG`1G}{)WabMFSeU6jnN6KPnC2IB54OnB-}OW;-_7d42^5wLM}J z2;u?4yU-?7@cSE^1QF*6_5OK6-QG0e<%AX;T7aeZwR>3Xc*baVPg7y(5@1{x(gO7L zhD3+Pdyrm|9VBa#NX?W$=C%m$JN#AFH~(@n3QCjNh|e5ju2!;8iC{v2JOYZ` zWmAuWd`fAUc{JKbXULA^DL&cC?n$W9-eG&>#NyQ@`IUWqD61#wPel879fCg57aPd9 z8)YmpHxTOjy?RSp0Qoy`}7)Rkx7`lLQ5f37(HHNggO5W;q(-A?(* z@CBvN3f)~#vD?4s`XaH`{EU@@VQmlB4hC@#=P-k<8R6E9#S{XT=%%AW2RmZu5dA$i z2-NvmY$mWEh`yBp`ib{@>mFYz)MNZ4a%7xqpR~T5cNCb9V07K&&A9Iiqft~)RRD&C z#FACNHy`CJa&-IYdXhD84n%Y#0Vx4Ho9DDM37wC;K8rlkxhk2a4?MvqY=exI+w2k9 ztj-t}x`rhPxs@d*5zLn?V5_SLx+;kQ5m*|FMm^%i!9U<#$yI#v0}A=^INol5j}0FF z+}qffLVON5ZNA?BA8;dR(h%Ub>i^PPEDM}n@h9xPcyE5ZgZ_gO3LC|TJk$v34R}kv zRjvM2Qvcos$hBr6e7?O{(?ogvV4l0X+d)Jzy5w7UZlw)^czuM%{goEuSr%PF@F!?yUs@zt*CvbalIrZ7d%$QrR+LgtNMM0}31D*Srw8k7t}*0NfKMZDdS+41%f| zaRvbSn*$e=z7ejwVsgS_V7`9Pm1Q1}0@Vofu?Yk-4+*ghpS5KmkmpPoPG0W6>P6Wu zUY$h{n&XBMJBegd9*r$gsm702Dt378GK|j;|NV z>-vGe&0?AMZZm;BFytVHYOb^FAK#l$K%&fI0kt~GZ)z$bfP1qoL0M&*VKJr#YFR`w zEP7BD(?a83hIz+?#Z$E&A6mg%pdh)R2*K0#MvxXu8-m0tUIG$8j#c^OAL_|<`Q%4p z@+=4=%GdMj`}c|nKEU821%dg9Ti}M39-cy@R+QybrR89y`R_7;DAqzzhl|nKh$sdk z3dKizR3pLQ(jK@R;Qepo%7CL|N}fqq-k>#f!3;&; zkTt;4HsaVTAfrIjBJ47Np4~94k4zzn2I2!M?cf2$mZFrmNRSYqXAcbPq$%_>0Md&5qU^zPMg))iF|1)z=$jshzYix?0V;hGMSn(u^0q^{0T|XpFyd{f_W(}Z3+Om_^dkv6 zw;kdFIxaSacHV~aGjZZE4+v{@i=O)cSPMbb_dwn@!|-7Doy*`2A?7GPoD#AWRS1`a zn4|la!jeZAMKjY|0N!AWgN5bVxz#|U1j z;O!ho^c)5*;<%whY~Y(5XM=hJLz$RFRRXZ>w?m=b>R8)^TV;kqZGjnFGxYUPcsbX^ zCNf4sxr)-g!1Q*%1m0fU$$4tLpq@>^?3CPhY8Pc58&cs zBq=)X@UGA;I`Xm-I(9dc-Jw<1G!V)`;akIal>KU3n6ajh=n;pk&mr#lT*(sHCmcLXDjaOuU(2h$Q#3et@-X&hOKR@R{ z)y)hZ<%V#nE#VubAq^{PTkeJZzJbjg-`2*`*-NpC9saVTf9hTpc**(>5SY$`o--v&ss34>}`v}MK&R`!jPY{LTm|-W(*CnsWV4(CC?Vq z(9|J1)vZyel>6oD+a|rA7#E)woUjML7>?OGAZN{p$rft)&?YlL8F1DO1vpTy2FBTh zUsYram|jYiJutADCb@VDsB!LX*<~;Ykps9SBcI1DIa6s%#T*pR{0b)g7yY z5RPWBWm=kETR`h9u=rNrs+3+86v?CXqMQI@DM=)>$4Ui?&g@E~@5H>9zn1_OwG<%b zgb845kAz=ANP+Un4A+`?a2y0#`i}7|y$anB`&o6VGPI0G8DKkkkxq&7b^gg@*FVoX z`4-_JoO%Huehr3kHoFZ^*_ui9%opHRgpI!;-q`TmvK>3X^pf9U%y-X!$2NwtaU(DK zkqXMPK8?1O&p=&2{DHZd2<4E-D)eLQJk?;hB87^3H$cjt!24VJgIx=x34k_#3$_<< zZ3b7a%RRL;ILtG%6;HmddJ9l*xt!xXMkvf{+OE6$yypCC;*Ket)m~?qXEu}7_KqL_ z>uK1Bd8F@>T=D>#Pm)k-5zY$ZHojCt~*4TJeJa4zVfCK#8d0>`gBr5$S(J zYze{!&i7v>f?V=HAvOe%flY*2)C7k4w-9?rb*b(O2($TrKy11(fb!=&F9RQ}e8hXv-M2NX~TWZUzlf-qjGybfo2Hw>fTG?H_cSmT?vo5a`%TNIjz3 z&13}xAG0zSjRU>3uXuio*m*$_=4qbu_m8{t?4OYGlIJ0sgffoU`gr!%mk??2T?wY( zT4@+X5cR1aH2V$1KAl0!put4zHD{4#Klaa| ztbAsNzZ~xxz0p5d);g{jyYbzWa;$%J8sM=TV`GyYpMfNP&GVEBPyS2jUFfRoG9$`r zswC)UG?*Mj$giJ5>-441-2<90xA?U*)_8i?T=pmh?9vtNg5-rym;tY!Ja^6W0js3y z$p_@~b&5J-vV<}X%%ok)i3M5lkHni>^Al!8O7q1-#S`jl-FG_yWNWx9D%QPrQC-~9 zJzFY@Av2IED%0xT#l$vl6RuRYr4K zv7DONaND?z@e*bgHm{`~Daz;u_q*rW@hIX(P|bApU<>eRgLINx6I*Or3NpM$QW2C)0?oDiFN<1b@r)AvT*MrUE#YpO9?byoF99>Qz9ytpz*@SeV zR4}K>h7v(S9!vyf+wJY~5@-lO^D{ZxlCSjshIQxp0MhS zDJCH8K0>Kg#C1R>`gW)DWuMo4j;J!!3j(?@nmAG!ccj3DzcDcIU(vfxZZNB_b#)~}Z~ zSQV9b>d;oX7Ur7RZ4sY?g}7-O1H@)A=un zHQN>Bt*;UUIeP8?omdx~sBwD9G6%$Z0k9rU=mjobjBKod2|}d0pI&wm97pu$ne?WT z=q)8w(R-#Fsiqphyie3Pzf=ivOaE;fVY}$#r9W~&-RQ*>XNk#_*Y+2-UtL0lrsdQg zxv>OnUVnwF2?qfeo(aF>5B&9)v|5eK_>0;K4kPuW&0QgT)Df`aOn6W4hZ z^lq@|zq?bXXXQh4A5_t{vgl)2++kbX6Twn_74kD!R zFjQ1@7q__Y6L4tGt!}7pDVBGJ$&s3JCwTGrHDN~<328p``dY{+Zt=5EI8Mzfr06hD zSdn`-l%4ltqRZ?5+tC&<}qAPjola&mlovf zIi6n-wEY5uby~NLTCL9nyG4>zP}i4zO1^`e2g=;Jxt*ZCQd!*H$J~~wgIq+wK2$C4 zPWlkwdP)iAh^IGr8x;knkpGD5^(!6QUd3dB$PV0`{qKih>D@Tx(v6hlCOJJc^*Zy; zKJ&hH7W(NnAk2Tm}L-zoaFPL6m zxVPA6t;-?Zjw3rO>UihB&8t%+t(`mM2OMueZZNpFwAiyP0g`N5`~Dop)((&{ z1X&XSJ6VXVDd6`v$Qp%5kTsfug4JGDO-`{i4C=w_OV!UjsDI1y53cy+_M;zuiETvg zR#QpySF9n|zq(XSu@RCx{^C+KB}YG7NM$qs>QZ&$;4bU^7rVe=%u3Hre)xIJ7ItQ4>`o>Yy#xYej>?T%s;nr#bDB{-m! Y6R^R~36!E~cIUJaUcaq(7?|+?0aB^9X#fBK diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_null_0.azshadervariant b/Gems/Atom/Feature/Common/Assets/Shaders/DiffuseGlobalIllumination/diffuseprobegridrender_null_0.azshadervariant index d195b08c349f26e3e47b822c29d8eec1317b211b..a1db8345e447583ab7ffcee115776b0ea9a1d948 100644 GIT binary patch delta 15 WcmX@ha+YO-8xwn8lX*4+0|NjmMg%kf delta 15 WcmX@ha+YO-8xybJL{%)73RebDPz$RjD>>HyvfTcANb-u@>gWUNpLu3A65VO<@wf|mvgqaS^DV@OX~W22pS)%lY3N?A&&7IjEQT3Gp9!t>1z zr5aRF9i2X&9zF4JdM3Mgx|my7nlGkvg_-Pft}t7E&6@L<0;*a0#W^DVcrJVHXmK_@ zC+16;T>in#Qnr}O`p@=kl;7y^*&+Tc zBP%GsE^S+}nJuDwJI-6t@=C|Yb-@ol`})Ichn{;xQWn+EM(*|vf2yxX?&u>otIgIOeZ;43RT%!Qz&xlNM zqWizaiO+v2PVA&Ey3K{%%CA^kpY$h4jl#LdG?xPsZQe@miqEAvqzLW^?V5 zo{(zL>w%uGfNB)|R_SZf7rHwgDr!2jxL7%Ph56!KCND^42&xvn)}63g^`nVSt4;e7 z$!K`Xxq_-)A4oXm#l)ChY7mp#rBj;Y5*Tui^mtWnk|%m@5A?|BX~+a*>XFfV_ANDf zWc1bb231?tKpyUd$mRm=HTrgacISMFU8HeHX&h!4%fblLV=M(@W{+`-VRE`Q7+HZ) zK-iIR8jNPJl6#se6Z$s{xp+JyFOZQM#wj%YurvL6LH8Fc{r)?k!1>=%P^(qO+DjJkpSZZJw3_QyZ0B==?oQpjE~T=f|G4MwhEL4$ED zVNC|3%wcT?+g4>A2BTn;O7=fuK)ypb#|^f<%61rxYZJTO2BX?x-Y3z!4q@IWv3m8n zb|=Mm+%KQOU^#H-Y1@v{yC-X5s^mp<=sEZKOLp^S685RSOuB6sS%ndQy(;B-i^|rA+sta zKtpCdQcXi<&qy=PlO@IFn*#&B5HBz4LbZQ2f4S!EM0U}ec?@K2@Wa{#U^!9RKf5fRTT-x`TNPh#~ CKtzoI delta 2109 zcmZXVU1(fI6oBX6yLbP(-R#Ds`0QO|dGZ=I|IXYQQuoHKLo z%$a+C+OXccY2BQ&qPLHZzW>GEcc0a#thwTzgkx7DN?A&&q&g-&Ev;;b_m$NSxvq*S zSHCh|)px^htzVD0Rz|;*c*%Qc_m{T!Sn8HjD5`Jp$oO@C{ITCpxmc4WW_#1cda*?R ztv|l)kEg;Je;XrgqZQHj!sF5pMQYOD9jDKi3%*BGuSF__uxzFyHkOmk&rp>uw*y?A-4({5f8F0;DU6!bdu+t~xE#><7)51~)b7Tw~=`$*n2BQ%hFy`pRhVC=2 zRNxb=IjdB62OJE<(G28$S@5bzFd1wx4ray$$!{8Qu!yX`BU7Lm$OUIXP9j(kHnIoB4E8{ujTnsL#4l?w zzT>blgYD_FvR(KuLoO?h)8aU<92NFvYUkV{{{wcnCNge_{14>wTdHUDzWRwA9{d@O z$W!9|vd_tfFQ%{8t9xgK(AfRF*x5+Dj{>Ek Date: Wed, 17 Nov 2021 10:19:25 +0000 Subject: [PATCH 18/72] LYN-6430 Add debug draw for heightfields. Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- Gems/PhysX/Code/Editor/DebugDraw.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Gems/PhysX/Code/Editor/DebugDraw.cpp b/Gems/PhysX/Code/Editor/DebugDraw.cpp index 90a1eb6004..403fcd7ce6 100644 --- a/Gems/PhysX/Code/Editor/DebugDraw.cpp +++ b/Gems/PhysX/Code/Editor/DebugDraw.cpp @@ -687,6 +687,30 @@ namespace PhysX [[maybe_unused]] const AZ::Vector3& colliderScale, [[maybe_unused]] const bool forceUniformScaling) const { + const float minXBounds = -(heightfieldShapeConfig.GetNumColumns() * heightfieldShapeConfig.GetGridResolution().GetX()) / 2.0f; + const float minYBounds = -(heightfieldShapeConfig.GetNumRows() * heightfieldShapeConfig.GetGridResolution().GetY()) / 2.0f; + + for (int xIndex = 0; xIndex < heightfieldShapeConfig.GetNumColumns() - 1; xIndex++) + { + for (int yIndex = 0; yIndex < heightfieldShapeConfig.GetNumRows() - 1; yIndex++) + { + const int index0 = yIndex * heightfieldShapeConfig.GetNumColumns() + xIndex; + const int index1 = yIndex * heightfieldShapeConfig.GetNumColumns() + xIndex + 1; + const int index2 = (yIndex + 1) * heightfieldShapeConfig.GetNumColumns() + xIndex + 1; + const int index3 = (yIndex + 1) * heightfieldShapeConfig.GetNumColumns() + xIndex; + + const float x0 = minXBounds + heightfieldShapeConfig.GetGridResolution().GetX() * xIndex; + const float x1 = minXBounds + heightfieldShapeConfig.GetGridResolution().GetX() * (xIndex + 1); + const float y0 = minYBounds + heightfieldShapeConfig.GetGridResolution().GetY() * (yIndex + 1); + const float y1 = minYBounds + heightfieldShapeConfig.GetGridResolution().GetY() * yIndex; + + debugDisplay.DrawWireQuad( + AZ::Vector3(x0, y0, heightfieldShapeConfig.GetSamples()[index0].m_height), + AZ::Vector3(x1, y0, heightfieldShapeConfig.GetSamples()[index1].m_height), + AZ::Vector3(x1, y1, heightfieldShapeConfig.GetSamples()[index2].m_height), + AZ::Vector3(x0, y1, heightfieldShapeConfig.GetSamples()[index3].m_height)); + } + } } AZ::Transform Collider::GetColliderLocalTransform( From abf3e69b970d5c0d0f68a572e2b73d6d4cb6afbe Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:25:05 +0100 Subject: [PATCH 19/72] EMotion FX: Saving Anim Graph with CTRL+S displays unsaved changes prompt when no changes were made (#5936) Saving an anim graph did not adjust the dirty flag and thus the saved changes dialog kept showing anim graphs that already saved the latest changes. Signed-off-by: Benjamin Jillich --- .../Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp | 5 +++++ Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp index b46fa645d1..e2e2224c67 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp @@ -581,6 +581,11 @@ namespace EMStudio animGraph->SetFileName(filename.c_str()); } + if (parameters.GetValueAsBool("updateDirtyFlag", this)) + { + animGraph->SetDirtyFlag(false); + } + GetMainWindow()->GetFileManager()->SourceAssetChanged(filename); // Add file in case it did not exist before (when saving it the first time). diff --git a/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp b/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp index 2af3329203..f61c4992a6 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanUseFileMenu.cpp @@ -330,6 +330,10 @@ namespace EMotionFX const QString animGraphFilename = GenerateTempAnimGraphFilename(); SaveCurrentAnimGraph(animGraphFilename); + // Pretend editing the anim graph + EMotionFX::AnimGraph* animGraph = m_animGraphPlugin->GetActiveAnimGraph(); + animGraph->SetDirtyFlag(true); + // Prepare a watcher to press the ok button when the SaveDirtySettingsWindow appears. ModalPopupHandler saveDirtyPopupHandler; From 21cae1603adabf9baaa8a9a58e4be6eb94f435a6 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:25:25 +0100 Subject: [PATCH 20/72] EMotion FX: Added helper to sample a pose from a motion without an motion instance (#6005) Signed-off-by: Benjamin Jillich --- .../Code/EMotionFX/Source/Motion.cpp | 13 ++++++--- Gems/EMotionFX/Code/EMotionFX/Source/Motion.h | 9 ++++--- .../EMotionFX/Source/MotionData/MotionData.h | 25 +++++------------ .../MotionData/MotionDataSampleSettings.h | 27 +++++++++++++++++++ .../MotionData/NonUniformMotionData.cpp | 4 +-- .../Source/MotionData/NonUniformMotionData.h | 4 +-- .../Source/MotionData/UniformMotionData.cpp | 4 +-- .../Source/MotionData/UniformMotionData.h | 4 +-- .../Code/EMotionFX/emotionfx_files.cmake | 1 + 9 files changed, 57 insertions(+), 34 deletions(-) create mode 100644 Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionDataSampleSettings.h diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp index 9ad55b1c40..caf2acbaa2 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp @@ -6,7 +6,6 @@ * */ -// include the required headers #include "EMotionFXConfig.h" #include "Motion.h" #include @@ -19,9 +18,9 @@ #include "EventHandler.h" #include "MotionEventTable.h" #include -#include #include #include +#include namespace EMotionFX { @@ -286,7 +285,7 @@ namespace EMotionFX { AZ_Assert(m_motionData, "Expecting motion data"); - MotionData::SampleSettings sampleSettings; + MotionDataSampleSettings sampleSettings; sampleSettings.m_actorInstance = instance->GetActorInstance(); sampleSettings.m_inPlace = instance->GetIsInPlace(); sampleSettings.m_mirror = instance->GetMirrorMotion(); @@ -301,7 +300,7 @@ namespace EMotionFX { AZ_Assert(m_motionData, "Expecting motion data"); - MotionData::SampleSettings sampleSettings; + MotionDataSampleSettings sampleSettings; sampleSettings.m_actorInstance = instance->GetActorInstance(); sampleSettings.m_inPlace = instance->GetIsInPlace(); sampleSettings.m_mirror = instance->GetMirrorMotion(); @@ -312,6 +311,12 @@ namespace EMotionFX m_motionData->SamplePose(sampleSettings, outputPose); } + void Motion::SamplePose(Pose* outputPose, const MotionDataSampleSettings& sampleSettings) + { + AZ_Assert(m_motionData, "Expecting motion data"); + m_motionData->SamplePose(sampleSettings, outputPose); + } + const MotionData* Motion::GetMotionData() const { return m_motionData; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h index e6ec99835b..3873924b7c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h @@ -9,14 +9,13 @@ #pragma once #include +#include +#include #include "EMotionFXConfig.h" #include "EMotionFXManager.h" #include "PlayBackInfo.h" #include "BaseObject.h" - -#include -#include - +#include namespace EMotionFX { @@ -138,6 +137,8 @@ namespace EMotionFX */ void Update(const Pose* inputPose, Pose* outputPose, MotionInstance* instance); + void SamplePose(Pose* outputPose, const MotionDataSampleSettings& sampleSettings); + /** * Specify the actor to use as retargeting source. * This would be the actor from which the motion was originally exported. diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h index fe831f1df0..3950d99de0 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionData.h @@ -9,18 +9,17 @@ #pragma once #include -#include -#include -#include -#include - #include #include #include #include #include - #include +#include +#include +#include +#include +#include namespace MCore { @@ -109,16 +108,6 @@ namespace EMotionFX using QuaternionKey = Key; using FloatKey = Key; - struct EMFX_API SampleSettings - { - const ActorInstance* m_actorInstance = nullptr; - const Pose* m_inputPose = nullptr; - float m_sampleTime = 0.0f; - bool m_mirror = false; - bool m_retarget = false; - bool m_inPlace = false; - }; - struct EMFX_API OptimizeSettings { AZStd::vector m_jointIgnoreList; // The joint data indices to skip optimization for. @@ -162,8 +151,8 @@ namespace EMotionFX virtual const char* GetSceneSettingsName() const = 0; // Sampling - virtual Transform SampleJointTransform(const SampleSettings& settings, size_t jointSkeletonIndex) const = 0; - virtual void SamplePose(const SampleSettings& settings, Pose* outputPose) const = 0; + virtual Transform SampleJointTransform(const MotionDataSampleSettings& settings, size_t jointSkeletonIndex) const = 0; + virtual void SamplePose(const MotionDataSampleSettings& settings, Pose* outputPose) const = 0; virtual float SampleMorph(float sampleTime, size_t morphDataIndex) const = 0; virtual float SampleFloat(float sampleTime, size_t morphDataIndex) const = 0; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionDataSampleSettings.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionDataSampleSettings.h new file mode 100644 index 0000000000..ea3f766c56 --- /dev/null +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/MotionDataSampleSettings.h @@ -0,0 +1,27 @@ +/* + * 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 EMotionFX +{ + class ActorInstance; + class Pose; + + struct EMFX_API MotionDataSampleSettings + { + const ActorInstance* m_actorInstance = nullptr; + const Pose* m_inputPose = nullptr; + float m_sampleTime = 0.0f; + bool m_mirror = false; + bool m_retarget = false; + bool m_inPlace = false; + }; +} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp index 50f3a1f73f..3078978d2c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp @@ -74,7 +74,7 @@ namespace EMotionFX return values[indexA].ToQuaternion().NLerp(values[indexB].ToQuaternion(), t); } - Transform NonUniformMotionData::SampleJointTransform(const SampleSettings& settings, size_t jointSkeletonIndex) const + Transform NonUniformMotionData::SampleJointTransform(const MotionDataSampleSettings& settings, size_t jointSkeletonIndex) const { const Actor* actor = settings.m_actorInstance->GetActor(); const MotionLinkData* motionLinkData = FindMotionLinkData(actor); @@ -131,7 +131,7 @@ namespace EMotionFX return result; } - void NonUniformMotionData::SamplePose(const SampleSettings& settings, Pose* outputPose) const + void NonUniformMotionData::SamplePose(const MotionDataSampleSettings& settings, Pose* outputPose) const { AZ_Assert(settings.m_actorInstance, "Expecting a valid actor instance."); const Actor* actor = settings.m_actorInstance->GetActor(); diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h index b5d8a05c44..16b9842479 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.h @@ -55,8 +55,8 @@ namespace EMotionFX AZ::u32 GetStreamSaveVersion() const override; const char* GetSceneSettingsName() const override; - Transform SampleJointTransform(const SampleSettings& settings, size_t jointSkeletonIndex) const override; - void SamplePose(const SampleSettings& settings, Pose* outputPose) const override; + Transform SampleJointTransform(const MotionDataSampleSettings& settings, size_t jointSkeletonIndex) const override; + void SamplePose(const MotionDataSampleSettings& settings, Pose* outputPose) const override; Transform SampleJointTransform(float sampleTime, size_t jointDataIndex) const override; AZ::Vector3 SampleJointPosition(float sampleTime, size_t jointDataIndex) const override; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp index 881604c7ff..0f096e7a8b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.cpp @@ -130,7 +130,7 @@ namespace EMotionFX } } - Transform UniformMotionData::SampleJointTransform(const SampleSettings& settings, size_t jointSkeletonIndex) const + Transform UniformMotionData::SampleJointTransform(const MotionDataSampleSettings& settings, size_t jointSkeletonIndex) const { const Actor* actor = settings.m_actorInstance->GetActor(); const MotionLinkData* motionLinkData = FindMotionLinkData(actor); @@ -195,7 +195,7 @@ namespace EMotionFX return result; } - void UniformMotionData::SamplePose(const SampleSettings& settings, Pose* outputPose) const + void UniformMotionData::SamplePose(const MotionDataSampleSettings& settings, Pose* outputPose) const { AZ_Assert(settings.m_actorInstance, "Expecting a valid actor instance."); const Actor* actor = settings.m_actorInstance->GetActor(); diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h index 40674cf2d1..d51f51ffd9 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/UniformMotionData.h @@ -53,8 +53,8 @@ namespace EMotionFX const char* GetSceneSettingsName() const override; // Overloaded. - Transform SampleJointTransform(const SampleSettings& settings, size_t jointSkeletonIndex) const override; - void SamplePose(const SampleSettings& settings, Pose* outputPose) const override; + Transform SampleJointTransform(const MotionDataSampleSettings& settings, size_t jointSkeletonIndex) const override; + void SamplePose(const MotionDataSampleSettings& settings, Pose* outputPose) const override; float SampleMorph(float sampleTime, size_t morphDataIndex) const override; float SampleFloat(float sampleTime, size_t floatDataIndex) const override; Transform SampleJointTransform(float sampleTime, size_t jointDataIndex) const override; diff --git a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake index f0443ade44..8135f14f12 100644 --- a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake +++ b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake @@ -350,6 +350,7 @@ set(FILES Source/MotionData/MotionData.h Source/MotionData/MotionDataFactory.cpp Source/MotionData/MotionDataFactory.h + Source/MotionData/MotionDataSampleSettings.h Source/MotionData/NonUniformMotionData.cpp Source/MotionData/NonUniformMotionData.h Source/MotionData/UniformMotionData.cpp From 4424b4d51ec71a66be41a74accb743ea3460b4e5 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Tue, 30 Nov 2021 10:49:53 +0000 Subject: [PATCH 21/72] Fix Integer Spin Controller not sending PropertyEditorGUIMessages::Bus::Handler::OnEditingFinished (#5942) * IntWidgetHandler::CreateUI now registers and sends editingFinished event * add tests for int spin control valueChanged and editingFinished signals Signed-off-by: amzn-sean <75276488+amzn-sean@users.noreply.github.com> --- .../UI/PropertyEditor/PropertyIntCtrlCommon.h | 4 ++ .../Tests/PropertyIntCtrlCommonTests.cpp | 4 +- .../Tests/PropertyIntCtrlCommonTests.h | 10 +++ .../Tests/PropertyIntSpinCtrlTests.cpp | 67 +++++++++++++++++++ .../Tests/aztoolsframeworktests_files.cmake | 1 + 5 files changed, 85 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h index 01675e0044..bb7d03367b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyIntCtrlCommon.h @@ -169,6 +169,10 @@ namespace AzToolsFramework { AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&PropertyEditorGUIMessages::Bus::Events::RequestWrite, newCtrl); }); + this->connect(newCtrl, &PropertyControl::editingFinished, this, [newCtrl]() + { + AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&PropertyEditorGUIMessages::Bus::Handler::OnEditingFinished, newCtrl); + }); // note: Qt automatically disconnects objects from each other when either end is destroyed, no need to worry about delete. // Set the value range to that of ValueType as clamped to the range of QtWidgetValueType diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.cpp b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.cpp index 67f764d1b3..d95451441f 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.cpp @@ -6,7 +6,9 @@ * */ -#include "IntegerPrimtitiveTestConfig.h" +#include +#include +#include namespace UnitTest { diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h index 10aed57ebd..712eeb99b7 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h +++ b/Code/Framework/AzToolsFramework/Tests/PropertyIntCtrlCommonTests.h @@ -156,6 +156,16 @@ namespace UnitTest EXPECT_STREQ(tooltip.toStdString().c_str(), expected.str().c_str()); } + void EmitWidgetValueChanged() + { + emit m_widget->valueChanged(ValueType(0)); + } + + void EmitWidgetEditingFinished() + { + emit m_widget->editingFinished(); + } + AZStd::unique_ptr m_dummyWidget; AZStd::unique_ptr m_handler; WidgetType* m_widget; diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyIntSpinCtrlTests.cpp b/Code/Framework/AzToolsFramework/Tests/PropertyIntSpinCtrlTests.cpp index 01f314bcc2..d7616e6bb8 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyIntSpinCtrlTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PropertyIntSpinCtrlTests.cpp @@ -47,4 +47,71 @@ namespace UnitTest { this->HandlerMinMaxLessLimit_ModifyHandler_ExpectSuccessAndValidLessLimitToolTipString(); } + + struct PropertyEditorHandler + : public AzToolsFramework::PropertyEditorGUIMessages::Bus::Handler + { + PropertyEditorHandler() + { + AzToolsFramework::PropertyEditorGUIMessages::Bus::Handler::BusConnect(); + } + + ~PropertyEditorHandler() + { + AzToolsFramework::PropertyEditorGUIMessages::Bus::Handler::BusDisconnect(); + } + + // AzToolsFramework::PropertyEditorGUIMessages::Bus overrides ... + void RequestWrite([[maybe_unused]] QWidget* editorGUI) override + { + m_requestWriteCallCount++; + } + + void RequestRefresh([[maybe_unused]] PropertyModificationRefreshLevel level) override + { + } + + void AddElementsToParentContainer( + [[maybe_unused]] QWidget* editorGUI, + [[maybe_unused]] size_t numElements, + [[maybe_unused]] const InstanceDataNode::FillDataClassCallback& fillDataCallback) override + { + } + + void RequestPropertyNotify([[maybe_unused]] QWidget* editorGUI) override + { + } + + void OnEditingFinished([[maybe_unused]]QWidget* editorGUI) override + { + m_onEditingFinishedCallCount++; + } + + int m_requestWriteCallCount = 0; + int m_onEditingFinishedCallCount = 0; + }; + + TYPED_TEST(PropertySpinCtrlFixture, SpinBoxWidgetValueChangedInvokesPropertyEditorGUIMessages) + { + // setup the event handler + PropertyEditorHandler eventHandler; + + // trigger the QT signal + this->EmitWidgetValueChanged(); + + // there should be at least 1 call to RequestWrite. + EXPECT_GT(eventHandler.m_requestWriteCallCount, 0); + } + + TYPED_TEST(PropertySpinCtrlFixture, SpinBoxWidgetEditingFinishedInvokesPropertyEditorGUIMessages) + { + // setup the event handler + PropertyEditorHandler eventHandler; + + // trigger the QT signal + this->EmitWidgetEditingFinished(); + + // there should be at least 1 call to OnEditingFinished. + EXPECT_GT(eventHandler.m_onEditingFinishedCallCount, 0); + } } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 99a998abb8..9e052de983 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -100,6 +100,7 @@ set(FILES Prefab/SpawnableSortEntitiesTests.cpp Prefab/PrefabScriptingTests.cpp Prefab/ProceduralPrefabAssetTests.cpp + PropertyIntCtrlCommonTests.cpp PropertyIntCtrlCommonTests.h PropertyIntSliderCtrlTests.cpp PropertyIntSpinCtrlTests.cpp From 9ebb7f5c224ab9aa3025fe8232c3bc48df854873 Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:54:21 +0000 Subject: [PATCH 22/72] review changes. Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- Gems/PhysX/Code/Editor/DebugDraw.cpp | 55 ++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/Gems/PhysX/Code/Editor/DebugDraw.cpp b/Gems/PhysX/Code/Editor/DebugDraw.cpp index 403fcd7ce6..a54230ec38 100644 --- a/Gems/PhysX/Code/Editor/DebugDraw.cpp +++ b/Gems/PhysX/Code/Editor/DebugDraw.cpp @@ -687,28 +687,51 @@ namespace PhysX [[maybe_unused]] const AZ::Vector3& colliderScale, [[maybe_unused]] const bool forceUniformScaling) const { - const float minXBounds = -(heightfieldShapeConfig.GetNumColumns() * heightfieldShapeConfig.GetGridResolution().GetX()) / 2.0f; - const float minYBounds = -(heightfieldShapeConfig.GetNumRows() * heightfieldShapeConfig.GetGridResolution().GetY()) / 2.0f; + const int numColumns = heightfieldShapeConfig.GetNumColumns(); + const int numRows = heightfieldShapeConfig.GetNumRows(); - for (int xIndex = 0; xIndex < heightfieldShapeConfig.GetNumColumns() - 1; xIndex++) + const float minXBounds = -(numColumns * heightfieldShapeConfig.GetGridResolution().GetX()) / 2.0f; + const float minYBounds = -(numRows * heightfieldShapeConfig.GetGridResolution().GetY()) / 2.0f; + + auto heights = heightfieldShapeConfig.GetSamples(); + + for (int xIndex = 0; xIndex < numColumns - 1; xIndex++) { - for (int yIndex = 0; yIndex < heightfieldShapeConfig.GetNumRows() - 1; yIndex++) + for (int yIndex = 0; yIndex < numRows - 1; yIndex++) { - const int index0 = yIndex * heightfieldShapeConfig.GetNumColumns() + xIndex; - const int index1 = yIndex * heightfieldShapeConfig.GetNumColumns() + xIndex + 1; - const int index2 = (yIndex + 1) * heightfieldShapeConfig.GetNumColumns() + xIndex + 1; - const int index3 = (yIndex + 1) * heightfieldShapeConfig.GetNumColumns() + xIndex; + const int index0 = yIndex * numColumns + xIndex; + const int index1 = yIndex * numColumns + xIndex + 1; + const int index2 = (yIndex + 1) * numColumns + xIndex; + const int index3 = (yIndex + 1) * numColumns + xIndex + 1; const float x0 = minXBounds + heightfieldShapeConfig.GetGridResolution().GetX() * xIndex; const float x1 = minXBounds + heightfieldShapeConfig.GetGridResolution().GetX() * (xIndex + 1); - const float y0 = minYBounds + heightfieldShapeConfig.GetGridResolution().GetY() * (yIndex + 1); - const float y1 = minYBounds + heightfieldShapeConfig.GetGridResolution().GetY() * yIndex; - - debugDisplay.DrawWireQuad( - AZ::Vector3(x0, y0, heightfieldShapeConfig.GetSamples()[index0].m_height), - AZ::Vector3(x1, y0, heightfieldShapeConfig.GetSamples()[index1].m_height), - AZ::Vector3(x1, y1, heightfieldShapeConfig.GetSamples()[index2].m_height), - AZ::Vector3(x0, y1, heightfieldShapeConfig.GetSamples()[index3].m_height)); + const float y0 = minYBounds + heightfieldShapeConfig.GetGridResolution().GetY() * yIndex; + const float y1 = minYBounds + heightfieldShapeConfig.GetGridResolution().GetY() * (yIndex + 1); + + // Always draw top and left line of quad + debugDisplay.DrawLine( + AZ::Vector3(x0, y0, heights[index0].m_height), + AZ::Vector3(x1, y0, heights[index1].m_height)); + debugDisplay.DrawLine( + AZ::Vector3(x0, y0, heights[index0].m_height), + AZ::Vector3(x0, y1, heights[index2].m_height)); + + // Draw bottom line in last row + if (yIndex == numRows - 2) + { + debugDisplay.DrawLine( + AZ::Vector3(x1, y1, heights[index3].m_height), + AZ::Vector3(x0, y1, heights[index2].m_height)); + } + + // Draw right line in last column + if (xIndex == numColumns - 2) + { + debugDisplay.DrawLine( + AZ::Vector3(x1, y0, heights[index1].m_height), + AZ::Vector3(x1, y1, heights[index3].m_height)); + } } } } From 8ce3dc846c9acc1023f1fa1ae59f044df8621976 Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Tue, 30 Nov 2021 06:34:41 -0800 Subject: [PATCH 23/72] Missing include Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp b/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp index bdd0ddf2ac..715489280d 100644 --- a/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/DynamicSlotComponent.cpp @@ -11,6 +11,7 @@ #include +#include #include #include From 066178d7b9ff6fb785bd40c2bdc84af6207e442a Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Tue, 30 Nov 2021 06:35:44 -0800 Subject: [PATCH 24/72] PR feedback Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp index 0bc54a493b..bf8482f0ca 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp @@ -27,8 +27,8 @@ #include #include -#include #include +#include #include #include From 75d6cb2527cc41d631a371fa6dcd686345fcebfc Mon Sep 17 00:00:00 2001 From: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:54:01 +0100 Subject: [PATCH 25/72] Connected filterChanged signal to Update the table Model (#5901) Signed-off-by: AMZN-Igarri <82394219+AMZN-Igarri@users.noreply.github.com> --- .../AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp index 14c5e719b4..775462f63f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/AssetBrowserTableModel.cpp @@ -30,6 +30,7 @@ namespace AzToolsFramework connect(m_filterModel, &QAbstractItemModel::rowsRemoved, this, &AssetBrowserTableModel::UpdateTableModelMaps); connect(m_filterModel, &QAbstractItemModel::layoutChanged, this, &AssetBrowserTableModel::UpdateTableModelMaps); connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AssetBrowserTableModel::beginResetModel); + connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AssetBrowserTableModel::UpdateTableModelMaps); connect(m_filterModel, &QAbstractItemModel::dataChanged, this, &AssetBrowserTableModel::SourceDataChanged); } From 6908a3e94555c4e190c9fc0a598e5afefcc32ff4 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:07:40 +0000 Subject: [PATCH 26/72] Update intersect behavior for positioning entities in the viewport (#5906) * update intersect behavior for positioning entities in the viewport and restore SurfaceManipulator Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * tests for surface manipulator from EditorTransformComponentSelection Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * update comments in tests and remove #pragma optimize('', off)@ Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add new file for FindClosestPickIntersection tests Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add remaining tests for surface manipulator and snap fixes Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * some small updates and polish before PR Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * small updates following PR feedback Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> --- Code/Editor/EditorViewportWidget.cpp | 26 +- Code/Editor/EditorViewportWidget.h | 5 - .../SandboxIntegration.cpp | 2 +- Code/Editor/Viewport.cpp | 20 +- Code/Editor/Viewport.h | 3 - .../ActionDispatcher.h | 22 ++ .../AzManipulatorTestFramework.h | 3 +- .../DirectManipulatorViewportInteraction.h | 4 +- .../ImmediateModeActionDispatcher.h | 8 +- .../ViewportInteraction.h | 5 +- .../Source/ImmediateModeActionDispatcher.cpp | 48 ++-- .../Source/ViewportInteraction.cpp | 6 +- .../Manipulators/EditorVertexSelection.cpp | 24 +- .../Manipulators/EditorVertexSelection.h | 2 +- .../Manipulators/ManipulatorSnapping.cpp | 24 -- .../Manipulators/ManipulatorSnapping.h | 5 - .../Manipulators/SurfaceManipulator.cpp | 104 ++++--- .../Manipulators/SurfaceManipulator.h | 6 + .../Viewport/ViewportMessages.cpp | 42 ++- .../Viewport/ViewportMessages.h | 41 ++- .../ViewportSelection/EditorSelectionUtil.cpp | 14 + .../ViewportSelection/EditorSelectionUtil.h | 3 + .../EditorTransformComponentSelection.cpp | 96 ++++--- .../EditorTransformComponentSelection.h | 2 +- .../Tests/BoundsTestComponent.cpp | 49 ++++ .../Tests/BoundsTestComponent.h | 18 ++ ...EditorTransformComponentSelectionTests.cpp | 174 +++++++++++- .../Tests/EditorVertexSelectionTests.cpp | 253 +++++++++++++++--- .../Viewport/ViewportInteractionTests.cpp | 76 ++++++ .../Tests/aztoolsframeworktests_files.cmake | 1 + .../Viewport/ViewportInteractionImpl.cpp | 5 +- 31 files changed, 811 insertions(+), 280 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 60e4bf6d47..7323da9e95 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -472,7 +472,7 @@ void EditorViewportWidget::Update() { auto start = std::chrono::steady_clock::now(); - m_entityVisibilityQuery.UpdateVisibility(GetCameraState()); + m_entityVisibilityQuery.UpdateVisibility(m_renderViewport->GetCameraState()); if (ed_visibility_logTiming) { @@ -714,7 +714,7 @@ void EditorViewportWidget::RenderAll() m_debugDisplay->DepthTestOff(); m_manipulatorManager->DrawManipulators( - *m_debugDisplay, GetCameraState(), + *m_debugDisplay, m_renderViewport->GetCameraState(), BuildMouseInteractionInternal( AztfVi::MouseButtons(AztfVi::TranslateMouseButtons(QGuiApplication::mouseButtons())), keyboardModifiers, BuildMousePick(WidgetToViewport(mapFromGlobal(QCursor::pos()))))); @@ -878,31 +878,11 @@ void EditorViewportWidget::OnMenuSelectCurrentCamera() } } -AzFramework::CameraState EditorViewportWidget::GetCameraState() -{ - return m_renderViewport->GetCameraState(); -} - -AZ::Vector3 EditorViewportWidget::PickTerrain(const AzFramework::ScreenPoint& point) -{ - return LYVec3ToAZVec3(ViewToWorld(AzToolsFramework::ViewportInteraction::QPointFromScreenPoint(point), nullptr, true)); -} - -float EditorViewportWidget::TerrainHeight(const AZ::Vector2& position) -{ - return GetIEditor()->GetTerrainElevation(position.GetX(), position.GetY()); -} - void EditorViewportWidget::FindVisibleEntities(AZStd::vector& visibleEntitiesOut) { visibleEntitiesOut.assign(m_entityVisibilityQuery.Begin(), m_entityVisibilityQuery.End()); } -AzFramework::ScreenPoint EditorViewportWidget::ViewportWorldToScreen(const AZ::Vector3& worldPosition) -{ - return m_renderViewport->ViewportWorldToScreen(worldPosition); -} - QWidget* EditorViewportWidget::GetWidgetForViewportContextMenu() { return this; @@ -2132,7 +2112,7 @@ bool EditorViewportWidget::GetActiveCameraState(AzFramework::CameraState& camera { if (m_pPrimaryViewport == this) { - cameraState = GetCameraState(); + cameraState = m_renderViewport->GetCameraState(); return true; } diff --git a/Code/Editor/EditorViewportWidget.h b/Code/Editor/EditorViewportWidget.h index 0101f2ffef..3d52b2416d 100644 --- a/Code/Editor/EditorViewportWidget.h +++ b/Code/Editor/EditorViewportWidget.h @@ -205,8 +205,6 @@ private: void* GetSystemCursorConstraintWindow() const override; // AzToolsFramework::MainEditorViewportInteractionRequestBus overrides ... - AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) override; - float TerrainHeight(const AZ::Vector2& position) override; bool ShowingWorldSpace() override; QWidget* GetWidgetForViewportContextMenu() override; @@ -293,9 +291,6 @@ private: // This switches the active camera to the next one in the list of (default, all custom cams). void CycleCamera(); - AzFramework::CameraState GetCameraState(); - AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition); - QPoint WidgetToViewport(const QPoint& point) const; QPoint ViewportToWidget(const QPoint& point) const; QSize WidgetToViewport(const QSize& size) const; diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index 5a1b4dc503..9342c17a37 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -1396,7 +1396,7 @@ void SandboxIntegrationManager::ContextMenu_NewEntity() { worldPosition = AzToolsFramework::FindClosestPickIntersection( view->GetViewportId(), AzFramework::ScreenPointFromVector2(m_contextMenuViewPoint), AzToolsFramework::EditorPickRayLength, - GetDefaultEntityPlacementDistance()); + AzToolsFramework::GetDefaultEntityPlacementDistance()); } CreateNewEntityAtPosition(worldPosition); diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp index 613dc0c4e7..437dcead3b 100644 --- a/Code/Editor/Viewport.cpp +++ b/Code/Editor/Viewport.cpp @@ -14,14 +14,11 @@ // Qt #include -// AzCore -#include - // AzQtComponents #include +// AzToolsFramework #include -#include #include #include @@ -41,19 +38,6 @@ #undef LoadCursor #endif -AZ_CVAR( - float, - ed_defaultEntityPlacementDistance, - 10.0f, - nullptr, - AZ::ConsoleFunctorFlags::Null, - "The default distance to place an entity from the camera if no intersection is found"); - -float GetDefaultEntityPlacementDistance() -{ - return ed_defaultEntityPlacementDistance; -} - ////////////////////////////////////////////////////////////////////// // Viewport drag and drop support ////////////////////////////////////////////////////////////////////// @@ -63,7 +47,7 @@ void QtViewport::BuildDragDropContext( { context.m_hitLocation = AzToolsFramework::FindClosestPickIntersection( viewportId, AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(point), AzToolsFramework::EditorPickRayLength, - GetDefaultEntityPlacementDistance()); + AzToolsFramework::GetDefaultEntityPlacementDistance()); } void QtViewport::dragEnterEvent(QDragEnterEvent* event) diff --git a/Code/Editor/Viewport.h b/Code/Editor/Viewport.h index b8c55c7431..a71df6a9cd 100644 --- a/Code/Editor/Viewport.h +++ b/Code/Editor/Viewport.h @@ -87,9 +87,6 @@ enum EStdCursor STD_CURSOR_LAST, }; -//! The default distance an entity is placed from the camera if there is no intersection -SANDBOX_API float GetDefaultEntityPlacementDistance(); - AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING class SANDBOX_API CViewport : public IDisplayViewport diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h index 06db67a05f..99f11c37da 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ActionDispatcher.h @@ -39,6 +39,10 @@ namespace AzManipulatorTestFramework DerivedDispatcherT* MouseLButtonDown(); //! Set the left mouse button up. DerivedDispatcherT* MouseLButtonUp(); + //! Set the middle mouse button down. + DerivedDispatcherT* MouseMButtonDown(); + //! Set the middle mouse button up. + DerivedDispatcherT* MouseMButtonUp(); //! Send a double click event. DerivedDispatcherT* MouseLButtonDoubleClick(); //! Set the keyboard modifier button down. @@ -73,6 +77,8 @@ namespace AzManipulatorTestFramework virtual void CameraStateImpl(const AzFramework::CameraState& cameraState) = 0; virtual void MouseLButtonDownImpl() = 0; virtual void MouseLButtonUpImpl() = 0; + virtual void MouseMButtonDownImpl() = 0; + virtual void MouseMButtonUpImpl() = 0; virtual void MouseLButtonDoubleClickImpl() = 0; virtual void MousePositionImpl(const AzFramework::ScreenPoint& position) = 0; virtual void KeyboardModifierDownImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) = 0; @@ -183,6 +189,22 @@ namespace AzManipulatorTestFramework return static_cast(this); } + template + DerivedDispatcherT* ActionDispatcher::MouseMButtonDown() + { + Log("Mouse middle button down"); + MouseMButtonDownImpl(); + return static_cast(this); + } + + template + DerivedDispatcherT* ActionDispatcher::MouseMButtonUp() + { + Log("Mouse middle button up"); + MouseMButtonUpImpl(); + return static_cast(this); + } + template DerivedDispatcherT* ActionDispatcher::MouseLButtonDoubleClick() { diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h index 5f0179d6ad..66227c692b 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFramework.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -40,7 +41,7 @@ namespace AzManipulatorTestFramework //! Set the angular step. virtual void SetAngularStep(float step) = 0; //! Get the viewport id. - virtual int GetViewportId() const = 0; + virtual AzFramework::ViewportId GetViewportId() const = 0; //! Updates the visibility state. //! Updates which entities are currently visible given the current camera state. virtual void UpdateVisibility() = 0; diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h index 3421116b96..7cef7b635d 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h @@ -30,7 +30,7 @@ namespace AzManipulatorTestFramework private: AZStd::shared_ptr m_customManager; - std::unique_ptr m_viewportInteraction; - std::unique_ptr m_manipulatorManager; + AZStd::unique_ptr m_viewportInteraction; + AZStd::unique_ptr m_manipulatorManager; }; } // namespace AzManipulatorTestFramework diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h index 5d1f606e8c..8a05a15fd9 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h @@ -25,7 +25,7 @@ namespace AzManipulatorTestFramework using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent; public: - explicit ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction); + explicit ImmediateModeActionDispatcher(ManipulatorViewportInteraction& manipulatorViewportInteraction); ~ImmediateModeActionDispatcher(); //! Clear the current event state. @@ -55,13 +55,15 @@ namespace AzManipulatorTestFramework AZStd::chrono::milliseconds EditorViewportInputTimeNow() override; protected: - // ActionDispatcher ... + // ActionDispatcher overrides ... void SetSnapToGridImpl(bool enabled) override; void SetStickySelectImpl(bool enabled) override; void GridSizeImpl(float size) override; void CameraStateImpl(const AzFramework::CameraState& cameraState) override; void MouseLButtonDownImpl() override; void MouseLButtonUpImpl() override; + void MouseMButtonDownImpl() override; + void MouseMButtonUpImpl() override; void MouseLButtonDoubleClickImpl() override; void MousePositionImpl(const AzFramework::ScreenPoint& position) override; void KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) override; @@ -82,7 +84,7 @@ namespace AzManipulatorTestFramework const MouseInteractionEvent* GetMouseInteractionEvent() const; mutable AZStd::unique_ptr m_event; - ManipulatorViewportInteraction& m_viewportManipulatorInteraction; + ManipulatorViewportInteraction& m_manipulatorViewportInteraction; //! Current time that ticks up after each call to EditorViewportInputTimeNow. AZStd::chrono::milliseconds m_timeNow = AZStd::chrono::milliseconds(0); diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h index 3c41b28851..a353140d4c 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h @@ -33,7 +33,7 @@ namespace AzManipulatorTestFramework void SetAngularSnapping(bool enabled) override; void SetGridSize(float size) override; void SetAngularStep(float step) override; - int GetViewportId() const override; + AzFramework::ViewportId GetViewportId() const override; void UpdateVisibility() override; void SetStickySelect(bool enabled) override; AZ::Vector3 DefaultEditorCameraPosition() const override; @@ -60,9 +60,10 @@ namespace AzManipulatorTestFramework void FindVisibleEntities(AZStd::vector& visibleEntities) override; private: + static constexpr AzFramework::ViewportId m_viewportId = 1234; //!< Arbitrary viewport id for manipulator tests. + AzFramework::EntityVisibilityQuery m_entityVisibilityQuery; AZStd::unique_ptr m_nullDebugDisplayRequests; - const int m_viewportId = 1234; // Arbitrary viewport id for manipulator tests AzFramework::CameraState m_cameraState; bool m_gridSnapping = false; bool m_angularSnapping = false; diff --git a/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp b/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp index 5bfe63bd99..aea93ca342 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/ImmediateModeActionDispatcher.cpp @@ -29,8 +29,8 @@ namespace AzManipulatorTestFramework using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier; using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent; - ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction) - : m_viewportManipulatorInteraction(viewportManipulatorInteraction) + ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& manipulatorViewportInteraction) + : m_manipulatorViewportInteraction(manipulatorViewportInteraction) { AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusConnect(); AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::Handler::BusConnect(); @@ -48,34 +48,34 @@ namespace AzManipulatorTestFramework // mouse down and mouse up event, to match the editor behavior we insert this event // to ensure the tests are simulating the same environment as the editor GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); } void ImmediateModeActionDispatcher::SetSnapToGridImpl(const bool enabled) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetGridSnapping(enabled); + m_manipulatorViewportInteraction.GetViewportInteraction().SetGridSnapping(enabled); } void ImmediateModeActionDispatcher::SetStickySelectImpl(const bool enabled) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetStickySelect(enabled); + m_manipulatorViewportInteraction.GetViewportInteraction().SetStickySelect(enabled); } void ImmediateModeActionDispatcher::GridSizeImpl(const float size) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetGridSize(size); + m_manipulatorViewportInteraction.GetViewportInteraction().SetGridSize(size); } void ImmediateModeActionDispatcher::CameraStateImpl(const AzFramework::CameraState& cameraState) { - m_viewportManipulatorInteraction.GetViewportInteraction().SetCameraState(cameraState); + m_manipulatorViewportInteraction.GetViewportInteraction().SetCameraState(cameraState); } void ImmediateModeActionDispatcher::MouseLButtonDownImpl() { ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Down; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); // the mouse position will be the same as the previous event, thus the delta will be 0 MouseMoveAfterButton(); } @@ -83,17 +83,35 @@ namespace AzManipulatorTestFramework void ImmediateModeActionDispatcher::MouseLButtonUpImpl() { GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); // the mouse position will be the same as the previous event, thus the delta will be 0 MouseMoveAfterButton(); } + void ImmediateModeActionDispatcher::MouseMButtonDownImpl() + { + ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Middle); + GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Down; + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + // the mouse position will be the same as the previous event, thus the delta will be 0 + MouseMoveAfterButton(); + } + + void ImmediateModeActionDispatcher::MouseMButtonUpImpl() + { + GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up; + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Middle); + // the mouse position will be the same as the previous event, thus the delta will be 0 + MouseMoveAfterButton(); + } + void ImmediateModeActionDispatcher::MouseLButtonDoubleClickImpl() { GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::DoubleClick; ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left); // the mouse position will be the same as the previous event, thus the delta will be 0 MouseMoveAfterButton(); @@ -101,10 +119,10 @@ namespace AzManipulatorTestFramework void ImmediateModeActionDispatcher::MousePositionImpl(const AzFramework::ScreenPoint& position) { - const auto cameraState = m_viewportManipulatorInteraction.GetViewportInteraction().GetCameraState(); + const auto cameraState = m_manipulatorViewportInteraction.GetViewportInteraction().GetCameraState(); GetMouseInteractionEvent()->m_mouseInteraction.m_mousePick = BuildMousePick(position, cameraState); GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move; - m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); + m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event); } void ImmediateModeActionDispatcher::KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) @@ -144,7 +162,7 @@ namespace AzManipulatorTestFramework { m_event = AZStd::unique_ptr(AZStd::make_unique()); m_event->m_mouseInteraction.m_interactionId.m_viewportId = - m_viewportManipulatorInteraction.GetViewportInteraction().GetViewportId(); + m_manipulatorViewportInteraction.GetViewportInteraction().GetViewportId(); } return m_event.get(); @@ -178,12 +196,12 @@ namespace AzManipulatorTestFramework void ImmediateModeActionDispatcher::ExpectManipulatorBeingInteractedImpl() { - EXPECT_TRUE(m_viewportManipulatorInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); + EXPECT_TRUE(m_manipulatorViewportInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); } void ImmediateModeActionDispatcher::ExpectManipulatorNotBeingInteractedImpl() { - EXPECT_FALSE(m_viewportManipulatorInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); + EXPECT_FALSE(m_manipulatorViewportInteraction.GetManipulatorManager().ManipulatorBeingInteracted()); } ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::ResetEvent() diff --git a/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp b/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp index 08cae0c738..e56f7d6d72 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp @@ -135,20 +135,20 @@ namespace AzManipulatorTestFramework m_angularStep = step; } - int ViewportInteraction::GetViewportId() const + AzFramework::ViewportId ViewportInteraction::GetViewportId() const { return m_viewportId; } AZ::Vector3 ViewportInteraction::ViewportScreenToWorld([[maybe_unused]] const AzFramework::ScreenPoint& screenPosition) { - return AZ::Vector3::CreateZero(); + return AzFramework::ScreenToWorld(screenPosition, m_cameraState); } AzToolsFramework::ViewportInteraction::ProjectedViewportRay ViewportInteraction::ViewportScreenToWorldRay( [[maybe_unused]] const AzFramework::ScreenPoint& screenPosition) { - return {}; + return AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(m_cameraState, screenPosition); } float ViewportInteraction::DeviceScalingFactor() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp index 00f5b1ac47..0c3638412c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.cpp @@ -84,12 +84,12 @@ namespace AzToolsFramework break; case State::Translating: { - if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() && + if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() && mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down && mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Shift() && mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl()) { - SnapVerticesToTerrain(mouseInteraction); + SnapVerticesToSurface(mouseInteraction); return true; } @@ -109,29 +109,23 @@ namespace AzToolsFramework } template - void EditorVertexSelectionBase::SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + void EditorVertexSelectionBase::SnapVerticesToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { ScopedUndoBatch surfaceSnapUndo("Snap to Surface"); ScopedUndoBatch::MarkEntityDirty(GetEntityId()); const int viewportId = mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId; - // get unsnapped terrain position (world space) - AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero(); - ; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); + // get unsnapped surface position (world space) + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection( + viewportId, mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates, EditorPickRayLength, + GetDefaultEntityPlacementDistance()); AZ::Transform worldFromLocal; AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); - // convert to local space - snap if enabled - const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); - const AZ::Vector3 localFinalSurfacePosition = gridSnapParams.m_gridSnap - ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocal, viewportId, gridSnapParams.m_gridSize) - : localFromWorld.TransformPoint(worldSurfacePosition); - + // convert to local space + const AZ::Vector3 localFinalSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition); SetSelectedPosition(localFinalSurfacePosition); OnEntityComponentPropertyChanged(GetEntityComponentIdPair()); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h index 4894a00df6..7e5523f62a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/EditorVertexSelection.h @@ -171,7 +171,7 @@ namespace AzToolsFramework //! Snap the selected vertices to the terrain. //! Note: With a multi-selection the manipulator will be translated to the picked //! terrain position with all vertices moved relative to it. - void SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + void SnapVerticesToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); //! The Actions provided by the EditorVertexSelection while it is active. //! e.g. Vertex deletion, duplication etc. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp index e4f6b3b1ea..5bea383630 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.cpp @@ -110,30 +110,6 @@ namespace AzToolsFramework return unsnappedPosition + CalculateSnappedOffset(unsnappedPosition, snapAxes, snapAxesCount, size); } - AZ::Vector3 CalculateSnappedTerrainPosition( - const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, const int viewportId, const float size) - { - const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); - const AZ::Vector3 localSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition); - - // snap in xy plane - AZ::Vector3 localSnappedSurfacePosition = localSurfacePosition + - CalculateSnappedOffset(localSurfacePosition, AZ::Vector3::CreateAxisX(), size) + - CalculateSnappedOffset(localSurfacePosition, AZ::Vector3::CreateAxisY(), size); - - // find terrain height at xy snapped location - float terrainHeight = 0.0f; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - terrainHeight, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::TerrainHeight, - Vector3ToVector2(worldFromLocal.TransformPoint(localSnappedSurfacePosition))); - - // set snapped z value to terrain height - AZ::Vector3 localTerrainHeight = localFromWorld.TransformPoint(AZ::Vector3(0.0f, 0.0f, terrainHeight)); - localSnappedSurfacePosition.SetZ(localTerrainHeight.GetZ()); - - return localSnappedSurfacePosition; - } - bool GridSnapping(const int viewportId) { bool snapping = false; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h index 660d38ac89..96f49d5276 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSnapping.h @@ -63,11 +63,6 @@ namespace AzToolsFramework AZ::Vector3 CalculateSnappedPosition( const AZ::Vector3& unsnappedPosition, const AZ::Vector3* snapAxes, size_t snapAxesCount, float size); - //! For a given point on the terrain, calculate the closest xy position snapped to the grid - //! (z position is aligned to terrain height, not snapped to z grid) - AZ::Vector3 CalculateSnappedTerrainPosition( - const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, int viewportId, float size); - //! Wrapper for grid snapping and grid size bus calls. GridSnapParameters GridSnapSettings(int viewportId); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp index dd565eb0a8..01b8635406 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace AzToolsFramework { @@ -17,28 +18,16 @@ namespace AzToolsFramework const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, const AZ::Vector3& localStartPosition, - const bool snapping, - const float gridSize, - const int viewportId) + [[maybe_unused]] const bool snapping, + [[maybe_unused]] const float gridSize, + [[maybe_unused]] const int viewportId) { - const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal); - const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse(); - - const AZ::Vector3 localFinalSurfacePosition = snapping - // note: gridSize is not scaled by scaleRecip here as localStartPosition is - // unscaled itself so the position returned by CalculateSnappedTerrainPosition - // must be in the same space (if localStartPosition were also scaled, gridSize - // would need to be multiplied by scaleRecip) - ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize) - : localFromWorldUniform.TransformPoint(worldSurfacePosition); - - // delta/offset between initial vertex position and terrain pick position - const AZ::Vector3 localSurfaceOffset = localFinalSurfacePosition - localStartPosition; + const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); StartInternal startInternal; - startInternal.m_snapOffset = localSurfaceOffset; - startInternal.m_localPosition = localStartPosition + localSurfaceOffset; - startInternal.m_localHitPosition = localFromWorldUniform.TransformVector(worldSurfacePosition); + startInternal.m_snapOffset = AZ::Vector3::CreateZero(); + startInternal.m_localPosition = localStartPosition; + startInternal.m_localHitPosition = localFromWorld.TransformPoint(worldSurfacePosition); return startInternal; } @@ -46,26 +35,19 @@ namespace AzToolsFramework const StartInternal& startInternal, const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, - const bool snapping, - const float gridSize, + [[maybe_unused]] const bool snapping, + [[maybe_unused]] const float gridSize, const ViewportInteraction::KeyboardModifiers keyboardModifiers, - const int viewportId) + [[maybe_unused]] const int viewportId) { - const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal); - const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse(); - - const float scaleRecip = ScaleReciprocal(worldFromLocalUniform); - - const AZ::Vector3 localFinalSurfacePosition = snapping - ? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize * scaleRecip) - : localFromWorldUniform.TransformPoint(worldSurfacePosition); + const AZ::Transform localFromWorld = worldFromLocal.GetInverse(); + const AZ::Vector3 localFinalSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition); Action action; action.m_start.m_localPosition = startInternal.m_localPosition; - action.m_start.m_snapOffset = startInternal.m_snapOffset; + action.m_start.m_snapOffset = AZ::Vector3::CreateZero(); action.m_current.m_localOffset = localFinalSurfacePosition - startInternal.m_localPosition; - // record what modifier keys are held during this action - action.m_modifiers = keyboardModifiers; + action.m_modifiers = keyboardModifiers; // record what modifier keys are held during this action return action; } @@ -78,12 +60,16 @@ namespace AzToolsFramework { SetSpace(worldFromLocal); AttachLeftMouseDownImpl(); + + // only cast rays against objects (entities/meshes etc.) we can actually see + m_rayRequest.m_onlyVisible = true; } void SurfaceManipulator::InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback) { m_onLeftMouseDownCallback = onMouseDownCallback; } + void SurfaceManipulator::InstallLeftMouseUpCallback(const MouseActionCallback& onMouseUpCallback) { m_onLeftMouseUpCallback = onMouseUpCallback; @@ -95,17 +81,30 @@ namespace AzToolsFramework } void SurfaceManipulator::OnLeftMouseDownImpl( - const ViewportInteraction::MouseInteraction& interaction, float /*rayIntersectionDistance*/) + const ViewportInteraction::MouseInteraction& interaction, [[maybe_unused]] float rayIntersectionDistance) { const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace()); - const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); + const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId; - AZ::Vector3 worldSurfacePosition; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, interaction.m_interactionId.m_viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - interaction.m_mousePick.m_screenCoordinates); + const auto& entityComponentIdPairs = EntityComponentIdPairs(); + m_rayRequest.m_entityFilter.m_ignoreEntities.clear(); + m_rayRequest.m_entityFilter.m_ignoreEntities.reserve(entityComponentIdPairs.size()); + AZStd::transform( + entityComponentIdPairs.begin(), entityComponentIdPairs.end(), + AZStd::inserter(m_rayRequest.m_entityFilter.m_ignoreEntities, m_rayRequest.m_entityFilter.m_ignoreEntities.begin()), + [](const AZ::EntityComponentIdPair& entityComponentIdPair) + { + return entityComponentIdPair.GetEntityId(); + }); + + // calculate the start and end of the ray + RefreshRayRequest( + m_rayRequest, ViewportInteraction::ViewportScreenToWorldRay(viewportId, interaction.m_mousePick.m_screenCoordinates), + EditorPickRayLength); + + const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance()); m_startInternal = CalculateManipulationDataStart( worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(), gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize, @@ -123,17 +122,14 @@ namespace AzToolsFramework { if (m_onLeftMouseUpCallback) { - AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero(); - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, interaction.m_interactionId.m_viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - interaction.m_mousePick.m_screenCoordinates); + const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId; - const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); + const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance()); m_onLeftMouseUpCallback(CalculateManipulationDataAction( m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap, - gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId)); + gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, viewportId)); } } @@ -141,13 +137,15 @@ namespace AzToolsFramework { if (m_onMouseMoveCallback) { - AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero(); - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, interaction.m_interactionId.m_viewportId, - &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - interaction.m_mousePick.m_screenCoordinates); + const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId; - const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId); + // update the start and end of the ray + RefreshRayRequest( + m_rayRequest, ViewportInteraction::ViewportScreenToWorldRay(viewportId, interaction.m_mousePick.m_screenCoordinates), + EditorPickRayLength); + + const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); + const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance()); m_onMouseMoveCallback(CalculateManipulationDataAction( m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h index c9121c49cc..091a71d8da 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.h @@ -11,6 +11,7 @@ #include "BaseManipulator.h" #include +#include #include namespace AzToolsFramework @@ -58,10 +59,12 @@ namespace AzToolsFramework Start m_start; Current m_current; ViewportInteraction::KeyboardModifiers m_modifiers; + AZ::Vector3 LocalPosition() const { return m_start.m_localPosition + m_current.m_localOffset; } + AZ::Vector3 LocalPositionOffset() const { return m_current.m_localOffset; @@ -106,6 +109,9 @@ namespace AzToolsFramework MouseActionCallback m_onLeftMouseUpCallback = nullptr; MouseActionCallback m_onMouseMoveCallback = nullptr; + //! Cached ray request initialized at mouse down and updated during mouse move. + AzFramework::RenderGeometry::RayRequest m_rayRequest; + static StartInternal CalculateManipulationDataStart( const AZ::Transform& worldFromLocal, const AZ::Vector3& worldSurfacePosition, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp index 8f8bd3e3f9..df96836bde 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.cpp @@ -64,23 +64,12 @@ namespace AzToolsFramework return circleBoundWidth; } - AZ::Vector3 FindClosestPickIntersection( - AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, const float rayLength, const float defaultDistance) + AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, const float defaultDistance) { - using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus; - AzToolsFramework::ViewportInteraction::ProjectedViewportRay viewportRay{}; - ViewportInteractionRequestBus::EventResult( - viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint); - - AzFramework::RenderGeometry::RayRequest ray; - ray.m_startWorldPosition = viewportRay.origin; - ray.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength; - ray.m_onlyVisible = true; - AzFramework::RenderGeometry::RayResult renderGeometryIntersectionResult; AzFramework::RenderGeometry::IntersectorBus::EventResult( renderGeometryIntersectionResult, AzToolsFramework::GetEntityContextId(), - &AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, ray); + &AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, rayRequest); // attempt a ray intersection with any visible mesh and return the intersection position if successful if (renderGeometryIntersectionResult) @@ -89,7 +78,32 @@ namespace AzToolsFramework } else { - return viewportRay.origin + viewportRay.direction * defaultDistance; + const AZ::Vector3 rayDirection = (rayRequest.m_endWorldPosition - rayRequest.m_startWorldPosition).GetNormalized(); + return rayRequest.m_startWorldPosition + rayDirection * defaultDistance; } } + + void RefreshRayRequest( + AzFramework::RenderGeometry::RayRequest& rayRequest, + const ViewportInteraction::ProjectedViewportRay& viewportRay, + const float rayLength) + { + AZ_Assert(rayLength > 0.0f, "Invalid ray length passed to RefreshRayRequest"); + rayRequest.m_startWorldPosition = viewportRay.origin; + rayRequest.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength; + } + + AZ::Vector3 FindClosestPickIntersection( + const AzFramework::ViewportId viewportId, + const AzFramework::ScreenPoint& screenPoint, + const float rayLength, + const float defaultDistance) + { + AzFramework::RenderGeometry::RayRequest ray; + ray.m_onlyVisible = true; // only consider visible objects + + RefreshRayRequest(ray, ViewportInteraction::ViewportScreenToWorldRay(viewportId, screenPoint), rayLength); + + return FindClosestPickIntersection(ray, defaultDistance); + } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h index aa97eb361e..aec2d3fbca 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h @@ -15,13 +15,19 @@ #include #include #include +#include #include #include namespace AzFramework { struct ScreenPoint; -} + + namespace RenderGeometry + { + struct RayRequest; + } +} // namespace AzFramework namespace AzToolsFramework { @@ -177,6 +183,26 @@ namespace AzToolsFramework //! Type to inherit to implement ViewportInteractionRequests. using ViewportInteractionRequestBus = AZ::EBus; + //! Utility function to return a viewport ray. + inline ProjectedViewportRay ViewportScreenToWorldRay( + const AzFramework::CameraState& cameraState, const AzFramework::ScreenPoint& screenPoint) + { + const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPoint, cameraState); + const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized(); + return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection }; + } + + //! Utility function to return a viewport ray using the ViewportInteractionRequestBus. + inline ProjectedViewportRay ViewportScreenToWorldRay( + const AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint) + { + ProjectedViewportRay viewportRay{}; + ViewportInteractionRequestBus::EventResult( + viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint); + + return viewportRay; + } + //! Interface to return only viewport specific settings (e.g. snapping). class ViewportSettingsRequests { @@ -228,10 +254,6 @@ namespace AzToolsFramework class MainEditorViewportInteractionRequests { public: - //! Given a point in screen space, return the terrain position in world space. - virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0; - //! Return the terrain height given a world position in 2d (xy plane). - virtual float TerrainHeight(const AZ::Vector2& position) = 0; //! Is the user holding a modifier key to move the manipulator space from local to world. virtual bool ShowingWorldSpace() = 0; //! Return the widget to use as the parent for the viewport context menu. @@ -337,9 +359,18 @@ namespace AzToolsFramework //! Performs an intersection test against meshes in the scene, if there is a hit (the ray intersects //! a mesh), that position is returned, otherwise a point projected defaultDistance from the //! origin of the ray will be returned. + //! @note The intersection will only consider visible objects. AZ::Vector3 FindClosestPickIntersection( AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, float rayLength, float defaultDistance); + //! Overload of FindClosestPickIntersection taking a RenderGeometry::RayRequest directly. + //! @note rayRequest must contain a valid ray/line segment (start/endWorldPosition must not be at the same position). + AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, float defaultDistance); + + //! Update the in/out parameter rayRequest based on the latest viewport ray. + void RefreshRayRequest( + AzFramework::RenderGeometry::RayRequest& rayRequest, const ViewportInteraction::ProjectedViewportRay& viewportRay, float rayLength); + //! Maps a mouse interaction event to a ClickDetector event. //! @note Function only cares about up or down events, all other events are mapped to Nil (ignored). AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp index 0a7bed6b18..31ea0c3985 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.cpp @@ -9,6 +9,7 @@ #include "EditorSelectionUtil.h" #include +#include #include #include #include @@ -16,8 +17,21 @@ #include #include +AZ_CVAR( + float, + ed_defaultEntityPlacementDistance, + 10.0f, + nullptr, + AZ::ConsoleFunctorFlags::Null, + "The default distance to place an entity from the camera if no intersection is found"); + namespace AzToolsFramework { + float GetDefaultEntityPlacementDistance() + { + return ed_defaultEntityPlacementDistance; + } + AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot) { if (Centered(pivot)) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h index 5c9f47fdd3..b3a6c6afd4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorSelectionUtil.h @@ -60,6 +60,9 @@ namespace AzToolsFramework //! Wrapper for EBus call to return the DPI scaling for a given viewport. float GetScreenDisplayScaling(int viewportId); + //! The default distance an entity is placed from the camera if there is no intersection. + float GetDefaultEntityPlacementDistance(); + //! A utility to return the center of several points. //! Take several positions and store the min and max of each in //! turn - when all points have been added return the center/midpoint. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index d3540f8c09..d3cfed4665 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -231,8 +231,8 @@ namespace AzToolsFramework { return mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() && mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down && - mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl() && - !mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt(); + !mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt() && + mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl(); } static bool IndividualDitto(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) @@ -243,12 +243,12 @@ namespace AzToolsFramework mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl(); } - static bool SnapTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + static bool SnapSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { return mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() && mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down && - (mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Alt() || - mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl()); + mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Shift() && + mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl(); } static bool ManipulatorDitto( @@ -923,26 +923,6 @@ namespace AzToolsFramework } } - static AZ::Vector3 PickTerrainPosition(const ViewportInteraction::MouseInteraction& mouseInteraction) - { - AZ_PROFILE_FUNCTION(AzToolsFramework); - - const int viewportId = mouseInteraction.m_interactionId.m_viewportId; - // get unsnapped terrain position (world space) - AZ::Vector3 worldSurfacePosition; - ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult( - worldSurfacePosition, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain, - mouseInteraction.m_mousePick.m_screenCoordinates); - - // convert to local space - snap if enabled - const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId); - const AZ::Vector3 finalSurfacePosition = gridSnapParams.m_gridSnap - ? CalculateSnappedTerrainPosition(worldSurfacePosition, AZ::Transform::CreateIdentity(), viewportId, gridSnapParams.m_gridSize) - : worldSurfacePosition; - - return finalSurfacePosition; - } - // is the passed entity id contained with in the entity id list template static bool IsEntitySelectedInternal(AZ::EntityId entityId, const EntityIdContainer& selectedEntityIds) @@ -1286,7 +1266,7 @@ namespace AzToolsFramework m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] + // see comment [ref 1.] above BeginRecordManipulatorCommand(); }); @@ -1321,7 +1301,7 @@ namespace AzToolsFramework m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] + // see comment [ref 1.] above BeginRecordManipulatorCommand(); }); @@ -1343,6 +1323,39 @@ namespace AzToolsFramework EndRecordManipulatorCommand(); }); + // surface + translationManipulators->InstallSurfaceManipulatorMouseDownCallback( + [this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action) + { + BuildSortedEntityIdVectorFromEntityIdMap(m_entityIdManipulators.m_lookups, manipulatorEntityIds->m_entityIds); + + InitializeTranslationLookup(m_entityIdManipulators); + + m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); + m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); + + // see comment [ref 1.] above + BeginRecordManipulatorCommand(); + }); + + translationManipulators->InstallSurfaceManipulatorMouseMoveCallback( + [this, prevModifiers, manipulatorEntityIds](const SurfaceManipulator::Action& action) mutable + { + UpdateTranslationManipulator( + action, manipulatorEntityIds->m_entityIds, m_entityIdManipulators, m_pivotOverrideFrame, prevModifiers, + m_transformChangedInternally, m_spaceCluster.m_spaceLock); + }); + + translationManipulators->InstallSurfaceManipulatorMouseUpCallback( + [this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action) + { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + manipulatorEntityIds->m_entityIds); + + EndRecordManipulatorCommand(); + }); + // transfer ownership m_entityIdManipulators.m_manipulators = AZStd::move(translationManipulators); } @@ -1395,7 +1408,7 @@ namespace AzToolsFramework m_axisPreview.m_translation = m_entityIdManipulators.m_manipulators->GetLocalTransform().GetTranslation(); m_axisPreview.m_orientation = QuaternionFromTransformNoScaling(m_entityIdManipulators.m_manipulators->GetLocalTransform()); - // [ref 1.] + // see comment [ref 1.] above BeginRecordManipulatorCommand(); }); @@ -1867,6 +1880,13 @@ namespace AzToolsFramework if (!m_selectedEntityIds.empty()) { + // try snapping to a surface (mesh) if in Translation mode + if (Input::SnapSurface(mouseInteraction)) + { + PerformSnapToSurface(mouseInteraction); + return false; + } + // group copying/alignment to specific entity - 'ditto' position/orientation for group if (Input::GroupDitto(mouseInteraction) && PerformGroupDitto(entityIdUnderCursor)) { @@ -1879,13 +1899,6 @@ namespace AzToolsFramework return false; } - // try snapping to the terrain (if in Translation mode) and entity wasn't picked - if (Input::SnapTerrain(mouseInteraction)) - { - PerformSnapToTerrain(mouseInteraction); - return false; - } - // set manipulator pivot override translation or orientation (update manipulators) if (Input::ManipulatorDitto(clickOutcome, mouseInteraction)) { @@ -1973,25 +1986,28 @@ namespace AzToolsFramework return false; } - void EditorTransformComponentSelection::PerformSnapToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) + void EditorTransformComponentSelection::PerformSnapToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { - for (AZ::EntityId entityId : m_selectedEntityIds) + for (const AZ::EntityId& entityId : m_selectedEntityIds) { ScopedUndoBatch::MarkEntityDirty(entityId); } if (m_mode == Mode::Translation) { - const AZ::Vector3 finalSurfacePosition = PickTerrainPosition(mouseInteraction.m_mouseInteraction); + const AZ::Vector3 worldPosition = FindClosestPickIntersection( + mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId, + mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates, AzToolsFramework::EditorPickRayLength, + GetDefaultEntityPlacementDistance()); // handle modifier alternatives if (Input::IndividualDitto(mouseInteraction)) { - CopyTranslationToSelectedEntitiesIndividual(finalSurfacePosition); + CopyTranslationToSelectedEntitiesIndividual(worldPosition); } else if (Input::GroupDitto(mouseInteraction)) { - CopyTranslationToSelectedEntitiesGroup(finalSurfacePosition); + CopyTranslationToSelectedEntitiesGroup(worldPosition); } } else if (m_mode == Mode::Rotation) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h index 10f83db739..afc290380b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.h @@ -308,7 +308,7 @@ namespace AzToolsFramework bool PerformGroupDitto(AZ::EntityId entityId); bool PerformIndividualDitto(AZ::EntityId entityId); void PerformManipulatorDitto(AZ::EntityId entityId); - void PerformSnapToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); + void PerformSnapToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction); //! Responsible for keeping the space cluster in sync with the current reference frame. void UpdateSpaceCluster(ReferenceFrame referenceFrame); diff --git a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp index fa5a6b344a..0b3c574e16 100644 --- a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp +++ b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.cpp @@ -8,6 +8,8 @@ #include +#include +#include #include namespace UnitTest @@ -62,4 +64,51 @@ namespace UnitTest { return m_localBounds; } + + void RenderGeometryIntersectionTestComponent::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class()->Version(1); + } + } + + void RenderGeometryIntersectionTestComponent::Activate() + { + BoundsTestComponent::Activate(); + + const AZ::EntityId entityId = GetEntityId(); + AzFramework::EntityContextId contextId = AzFramework::EntityContextId::CreateNull(); + AzFramework::EntityIdContextQueryBus::EventResult(contextId, entityId, &AzFramework::EntityIdContextQueries::GetOwningContextId); + AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusConnect({entityId, contextId}); + } + + void RenderGeometryIntersectionTestComponent::Deactivate() + { + AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusDisconnect(); + BoundsTestComponent::Deactivate(); + } + + AzFramework::RenderGeometry::RayResult RenderGeometryIntersectionTestComponent::RenderGeometryIntersect( + const AzFramework::RenderGeometry::RayRequest& ray) + { + AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity(); + AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); + + AzFramework::RenderGeometry::RayResult rayResult; + + float t = 0.0f; + const AZ::Obb obb = GetLocalBounds().GetTransformedObb(worldFromLocal); + const AZ::Vector3 rayDirection = ray.m_endWorldPosition - ray.m_startWorldPosition; + if (AZ::Intersect::IntersectRayObb(ray.m_startWorldPosition, rayDirection, obb, t)) + { + rayResult.m_worldPosition = ray.m_startWorldPosition + rayDirection * t; + rayResult.m_entityAndComponent = AZ::EntityComponentIdPair(GetEntityId(), GetId()); + rayResult.m_distance = t; + rayResult.m_uv = AZ::Vector2::CreateZero(); + rayResult.m_worldNormal = AZ::Vector3::CreateZero(); + } + + return rayResult; + } } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h index 358a9f810a..2eee3c0a66 100644 --- a/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h +++ b/Code/Framework/AzToolsFramework/Tests/BoundsTestComponent.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -44,4 +45,21 @@ namespace UnitTest AZ::Aabb m_localBounds; //!< Local bounds that can be modified for certain tests (defaults to unit cube). }; + + class RenderGeometryIntersectionTestComponent + : public BoundsTestComponent + , public AzFramework::RenderGeometry::IntersectionRequestBus::Handler + { + public: + AZ_EDITOR_COMPONENT(RenderGeometryIntersectionTestComponent, "{6F46B5BF-60DF-4BDD-9BA7-9658E85B99C2}", BoundsTestComponent); + + static void Reflect(AZ::ReflectContext* context); + + // AZ::Component overrides ... + void Activate() override; + void Deactivate() override; + + // IntersectionRequestBus overrides ... + AzFramework::RenderGeometry::RayResult RenderGeometryIntersect(const AzFramework::RenderGeometry::RayRequest& ray) override; + }; } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp b/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp index f4077e992b..859cc67c41 100644 --- a/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp @@ -1663,7 +1663,7 @@ namespace UnitTest const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityId1); // ensure final world positions match - EXPECT_TRUE(finalEntityTransform.IsClose(finalTransformWorld, 0.01f)); + EXPECT_THAT(finalEntityTransform, IsCloseTolerance(finalTransformWorld, 0.01f)); } TEST_F(EditorTransformComponentSelectionManipulatorTestFixture, TranslatingEntityWithLinearManipulatorNotifiesOnEntityTransformChanged) @@ -2973,4 +2973,176 @@ namespace UnitTest EXPECT_THAT(hoveredEntityIdAccentRemoved, IsTrue()); EXPECT_THAT(hoveredEntityEntityId, Eq(AZ::EntityId(12345))); } + + class EditorTransformComponentSelectionRenderGeometryIntersectionFixture : public ToolsApplicationFixture + { + public: + void SetUpEditorFixtureImpl() override + { + auto* app = GetApplication(); + // register a simple component implementing BoundsRequestBus and EditorComponentSelectionRequestsBus + app->RegisterComponentDescriptor(BoundsTestComponent::CreateDescriptor()); + // register a component implementing RenderGeometry::IntersectionRequestBus + app->RegisterComponentDescriptor(RenderGeometryIntersectionTestComponent::CreateDescriptor()); + + auto createEntityWithGeometryIntersectionFn = [](const char* entityName) + { + AZ::Entity* entity = nullptr; + AZ::EntityId entityId = CreateDefaultEditorEntity(entityName, &entity); + + entity->Deactivate(); + entity->CreateComponent(); + entity->Activate(); + + return entityId; + }; + + m_entityIdGround = createEntityWithGeometryIntersectionFn("Entity1"); + m_entityIdBox = createEntityWithGeometryIntersectionFn("Entity2"); + + if (auto* ground = AzToolsFramework::GetEntityById(m_entityIdGround)->FindComponent()) + { + ground->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-10.0f, -10.0f, -0.5f), AZ::Vector3(10.0f, 10.0f, 0.5f)); + } + + AzToolsFramework::SetWorldTransform(m_entityIdGround, AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, 10.0f, 5.0f))); + + if (auto* box = AzToolsFramework::GetEntityById(m_entityIdBox)->FindComponent()) + { + box->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-0.5f), AZ::Vector3(0.5f)); + } + + AzToolsFramework::SetWorldTransform( + m_entityIdBox, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(45.0f)), AZ::Vector3(0.0f, 10.0f, 7.0f))); + } + + AZ::EntityId m_entityIdGround; + AZ::EntityId m_entityIdBox; + }; + + using EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture = + IndirectCallManipulatorViewportInteractionFixtureMixin; + + TEST_F( + EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture, BoxCanBePlacedOnMeshSurfaceUsingSurfaceManipulator) + { + // camera (go to position format) - 0.00, 20.00, 12.00, -35.00, -180.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(-180.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-35.0f)), + AZ::Vector3(0.0f, 20.0f, 12.0f))); + + // the initial starting position of the entity + const auto initialTransformWorld = AzToolsFramework::GetWorldTransform(m_entityIdBox); + // where the entity should end up (snapped to the larger ground surface) + const auto finalTransformWorld = + AZ::Transform::CreateFromQuaternionAndTranslation(initialTransformWorld.GetRotation(), AZ::Vector3(2.5f, 12.5f, 5.5f)); + + // calculate the position in screen space of the initial position of the entity + const auto initialPositionScreen = AzFramework::WorldToScreen(initialTransformWorld.GetTranslation(), m_cameraState); + // calculate the position in screen space of the final position of the entity + const auto finalPositionScreen = AzFramework::WorldToScreen(finalTransformWorld.GetTranslation(), m_cameraState); + + // select the entity (this will cause the manipulators to appear in EditorTransformComponentSelection) + AzToolsFramework::SelectEntity(m_entityIdBox); + + // press and drag the mouse (starting where the surface manipulator is) + m_actionDispatcher->CameraState(m_cameraState) + ->MousePosition(initialPositionScreen) + ->MouseLButtonDown() + ->MousePosition(finalPositionScreen) + ->MouseLButtonUp(); + + // read back the position of the entity now + const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityIdBox); + + // ensure final world positions match + EXPECT_THAT(finalEntityTransform, IsCloseTolerance(finalTransformWorld, 0.01f)); + } + + TEST_F( + EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture, + SurfaceManipulatorFollowsMouseAtDefaultEditorDistanceFromCameraWhenNoMeshIntersection) + { + // camera (go to position format) - 0.00, 25.00, 12.00, 0.00, -180.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(-180.0f)), AZ::Vector3(0.0f, 25.0f, 12.0f))); + + // the initial starting position of the entity + const auto initialTransformWorld = AzToolsFramework::GetWorldTransform(m_entityIdBox); + // where the entity should end up (default distance away from the camera/near clip under where the mouse is) + const auto finalTransformWorld = + AZ::Transform::CreateFromQuaternionAndTranslation(initialTransformWorld.GetRotation(), AZ::Vector3(0.0f, 14.9f, 12.0f)); + + // calculate the position in screen space of the initial position of the entity + const auto initialPositionScreen = AzFramework::WorldToScreen(initialTransformWorld.GetTranslation(), m_cameraState); + // calculate the position in screen space of the final position of the entity + const auto finalPositionScreen = AzFramework::WorldToScreen(finalTransformWorld.GetTranslation(), m_cameraState); + + // select the entity (this will cause the manipulators to appear in EditorTransformComponentSelection) + AzToolsFramework::SelectEntity(m_entityIdBox); + + // press and drag the mouse (starting where the surface manipulator is) + m_actionDispatcher->CameraState(m_cameraState) + ->MousePosition(initialPositionScreen) + ->MouseLButtonDown() + ->MousePosition(finalPositionScreen) + ->MouseLButtonUp(); + + // read back the position of the entity now + const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityIdBox); + + const auto viewportRay = AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(m_cameraState, initialPositionScreen); + const auto distanceAway = (finalEntityTransform.GetTranslation() - viewportRay.origin).GetLength(); + + // ensure final world positions match + EXPECT_THAT(finalEntityTransform, IsCloseTolerance(finalTransformWorld, 0.01f)); + // ensure distance away is what we expect + EXPECT_NEAR(distanceAway, AzToolsFramework::GetDefaultEntityPlacementDistance(), 0.001f); + } + + TEST_F( + EditorTransformComponentSelectionRenderGeometryIntersectionManipulatorFixture, + MiddleMouseButtonWithShiftAndCtrlHeldOnMeshSurfaceWillSnapSelectedEntityToIntersectionPoint) + { + // camera (go to position format) - 21.00, 8.00, 11.00, -22.00, 150.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(150.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-22.0f)), + AZ::Vector3(21.0f, 8.0f, 11.0f))); + + // position the ground entity + AzToolsFramework::SetWorldTransform( + m_entityIdGround, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(40.0f)) * AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(60.0f)), + AZ::Vector3(14.0f, -6.0f, 5.0f))); + + // select the other entity (a 1x1x1 box) + AzToolsFramework::SelectEntity(m_entityIdBox); + + // expected world position (value taken from editor scenario) + const auto expectedWorldPosition = AZ::Vector3(13.606657f, -2.6753534f, 5.9827675f); + const auto screenPosition = AzFramework::WorldToScreen(expectedWorldPosition, m_cameraState); + + // perform snap action + m_actionDispatcher->CameraState(m_cameraState) + ->MousePosition(screenPosition) + ->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Control) + ->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift) + ->MouseMButtonDown(); + + // read back the current entity transform after placement + const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityIdBox); + EXPECT_THAT(finalEntityTransform.GetTranslation(), IsCloseTolerance(expectedWorldPosition, 0.01f)); + } } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp b/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp index 93010aa63d..228dea6b7c 100644 --- a/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/EditorVertexSelectionTests.cpp @@ -10,22 +10,23 @@ #include #include #include +#include +#include +#include +#include +#include #include #include +#include #include #include #include #include #include #include -#include -#include -#include -#include -#include #include -using namespace AzToolsFramework; +#include namespace UnitTest { @@ -42,20 +43,65 @@ namespace UnitTest void Disconnect(); // FixedVerticesRequestBus/VariableVerticesRequestBus ... - bool GetVertex(size_t index, AZ::Vector3& vertex) const override { return m_vertexContainer.GetVertex(index, vertex); } - bool UpdateVertex(size_t index, const AZ::Vector3& vertex) override { return m_vertexContainer.UpdateVertex(index, vertex); }; - void AddVertex(const AZ::Vector3& vertex) override { m_vertexContainer.AddVertex(vertex); } - bool InsertVertex(size_t index, const AZ::Vector3& vertex) override { return m_vertexContainer.InsertVertex(index, vertex); } - bool RemoveVertex(size_t index) override { return m_vertexContainer.RemoveVertex(index); } - void SetVertices(const AZStd::vector& vertices) override { m_vertexContainer.SetVertices(vertices); }; - void ClearVertices() override { m_vertexContainer.Clear(); } - size_t Size() const override { return m_vertexContainer.Size(); } - bool Empty() const override { return m_vertexContainer.Empty(); } + bool GetVertex(size_t index, AZ::Vector3& vertex) const override; + bool UpdateVertex(size_t index, const AZ::Vector3& vertex) override; + void AddVertex(const AZ::Vector3& vertex) override; + bool InsertVertex(size_t index, const AZ::Vector3& vertex) override; + bool RemoveVertex(size_t index) override; + void SetVertices(const AZStd::vector& vertices) override; + void ClearVertices() override; + size_t Size() const override; + bool Empty() const override; private: AZ::VertexContainer m_vertexContainer; }; + bool TestVariableVerticesVertexContainer::GetVertex(size_t index, AZ::Vector3& vertex) const + { + return m_vertexContainer.GetVertex(index, vertex); + } + + bool TestVariableVerticesVertexContainer::UpdateVertex(size_t index, const AZ::Vector3& vertex) + { + return m_vertexContainer.UpdateVertex(index, vertex); + } + + void TestVariableVerticesVertexContainer::AddVertex(const AZ::Vector3& vertex) + { + m_vertexContainer.AddVertex(vertex); + } + + bool TestVariableVerticesVertexContainer::InsertVertex(size_t index, const AZ::Vector3& vertex) + { + return m_vertexContainer.InsertVertex(index, vertex); + } + + bool TestVariableVerticesVertexContainer::RemoveVertex(size_t index) + { + return m_vertexContainer.RemoveVertex(index); + } + + void TestVariableVerticesVertexContainer::SetVertices(const AZStd::vector& vertices) + { + m_vertexContainer.SetVertices(vertices); + } + + void TestVariableVerticesVertexContainer::ClearVertices() + { + m_vertexContainer.Clear(); + } + + size_t TestVariableVerticesVertexContainer::Size() const + { + return m_vertexContainer.Size(); + } + + bool TestVariableVerticesVertexContainer::Empty() const + { + return m_vertexContainer.Empty(); + } + void TestVariableVerticesVertexContainer::Connect(const AZ::EntityId entityId) { AZ::VariableVerticesRequestBus::Handler::BusConnect(entityId); @@ -68,17 +114,18 @@ namespace UnitTest AZ::VariableVerticesRequestBus::Handler::BusDisconnect(); } - class TestEditorVertexSelectionVariable - : public EditorVertexSelectionVariable + class TestEditorVertexSelectionVariable : public AzToolsFramework::EditorVertexSelectionVariable { public: AZ_CLASS_ALLOCATOR(TestEditorVertexSelectionVariable, AZ::SystemAllocator, 0) - void ShowVertexDeletionWarning() override { /*noop*/ } + void ShowVertexDeletionWarning() override + { + // noop + } }; - class EditorVertexSelectionFixture - : public ToolsApplicationFixture + class EditorVertexSelectionFixture : public ToolsApplicationFixture { public: void SetUpEditorFixtureImpl() override @@ -112,26 +159,25 @@ namespace UnitTest void EditorVertexSelectionFixture::RecreateVertexSelection() { + namespace aztf = AzToolsFramework; m_vertexSelection.Create( - AZ::EntityComponentIdPair(m_entityId, TestComponentId), - g_mainManipulatorManagerId, AZStd::make_unique(), - TranslationManipulators::Dimensions::Three, ConfigureTranslationManipulatorAppearance3d); + AZ::EntityComponentIdPair(m_entityId, TestComponentId), aztf::g_mainManipulatorManagerId, + AZStd::make_unique(), aztf::TranslationManipulators::Dimensions::Three, + aztf::ConfigureTranslationManipulatorAppearance3d); } void EditorVertexSelectionFixture::PopulateVertices() { for (size_t vertIndex = 0; vertIndex < EditorVertexSelectionFixture::VertexCount; ++vertIndex) { - InsertVertexAfter( - AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0, AZ::Vector3::CreateZero()); + AzToolsFramework::InsertVertexAfter(AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0, AZ::Vector3::CreateZero()); } } void EditorVertexSelectionFixture::ClearVertices() { for (size_t vertIndex = 0; vertIndex < EditorVertexSelectionFixture::VertexCount; ++vertIndex) { - SafeRemoveVertex( - AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0); + AzToolsFramework::SafeRemoveVertex(AZ::EntityComponentIdPair(m_entityId, TestComponentId), 0); } } @@ -188,7 +234,7 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // When // just provide a placeholder mouse interaction event in this case - m_vertexSelection.SnapVerticesToTerrain(ViewportInteraction::MouseInteractionEvent{}); + m_vertexSelection.SnapVerticesToSurface(AzToolsFramework::ViewportInteraction::MouseInteractionEvent{}); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -197,8 +243,7 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// } - using EditorVertexSelectionManipulatorFixture = - IndirectCallManipulatorViewportInteractionFixtureMixin; + using EditorVertexSelectionManipulatorFixture = IndirectCallManipulatorViewportInteractionFixtureMixin; TEST_F(EditorVertexSelectionManipulatorFixture, CannotDeleteAllVertices) { @@ -206,25 +251,23 @@ namespace UnitTest const auto entityComponentIdPair = AZ::EntityComponentIdPair(m_entityId, TestComponentId); - const float horizontalPositions[] = {-1.5f, -0.5f, 0.5f, 1.5f}; - for (size_t vertIndex = 0; vertIndex < std::size(horizontalPositions); ++vertIndex) + const float horizontalPositions[] = { -1.5f, -0.5f, 0.5f, 1.5f }; + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) { - InsertVertexAfter( - entityComponentIdPair, vertIndex, AZ::Vector3(horizontalPositions[vertIndex], 5.0f, 0.0f)); + AzToolsFramework::InsertVertexAfter(entityComponentIdPair, vertIndex, AZ::Vector3(horizontalPositions[vertIndex], 5.0f, 0.0f)); } - // rebuild the vertex selection after adding the new verts + // rebuild the vertex selection after adding the new vertices RecreateVertexSelection(); // build a vector of the vertex positions in screen space AZStd::vector vertexScreenPositions; - for (size_t vertIndex = 0; vertIndex < std::size(horizontalPositions); ++vertIndex) + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) { - AZ::Vector3 localVertex; + AZ::Vector3 localVertex = AZ::Vector3::CreateZero(); bool found = false; AZ::FixedVerticesRequestBus::EventResult( - found, m_entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, - vertIndex, localVertex); + found, m_entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertIndex, localVertex); if (found) { @@ -267,9 +310,9 @@ namespace UnitTest const auto entityComponentIdPair = AZ::EntityComponentIdPair(m_entityId, TestComponentId); // add a single vertex (in front of the camera) - InsertVertexAfter(entityComponentIdPair, 0, AZ::Vector3::CreateAxisY(5.0f)); + AzToolsFramework::InsertVertexAfter(entityComponentIdPair, 0, AZ::Vector3::CreateAxisY(5.0f)); - // rebuild the vertex selection after adding the new verts + // rebuild the vertex selection after adding the new vertices RecreateVertexSelection(); AzFramework::ScreenPoint vertexScreenPosition; @@ -300,4 +343,132 @@ namespace UnitTest // deleting the last vertex through a manipulator is disallowed - size should remain the same EXPECT_THAT(vertexCountAfter, Eq(1)); } + + static AZ::EntityId CreateEntityForVertexIntersectionPlacement(EditorVertexSelectionManipulatorFixture& fixture) + { + auto* app = fixture.GetApplication(); + app->RegisterComponentDescriptor(BoundsTestComponent::CreateDescriptor()); + app->RegisterComponentDescriptor(RenderGeometryIntersectionTestComponent::CreateDescriptor()); + + AZ::Entity* entityGround = nullptr; + AZ::EntityId entityIdGround = CreateDefaultEditorEntity("EntityGround", &entityGround); + + entityGround->Deactivate(); + auto ground = entityGround->CreateComponent(); + entityGround->Activate(); + + ground->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-10.0f, -10.0f, -0.5f), AZ::Vector3(10.0f, 10.0f, 0.5f)); + + return entityIdGround; + } + + static AZStd::vector SetupVertices( + const AZ::EntityId entityId, EditorVertexSelectionManipulatorFixture& fixture) + { + const auto entityComponentIdPair = AZ::EntityComponentIdPair(entityId, TestComponentId); + const float horizontalPositions[] = { -3.0f, -1.0f, 1.0f, 3.0f }; + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) + { + AzToolsFramework::InsertVertexAfter(entityComponentIdPair, vertIndex, AZ::Vector3(horizontalPositions[vertIndex], 0.0f, 0.0f)); + } + + // rebuild the vertex selection after adding the new vertices + fixture.RecreateVertexSelection(); + + // build a vector of the vertex positions in screen space + AZStd::vector vertexScreenPositions; + for (size_t vertIndex = 0; vertIndex < AZStd::size(horizontalPositions); ++vertIndex) + { + AZ::Vector3 localVertex; + bool found = false; + AZ::FixedVerticesRequestBus::EventResult( + found, entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, vertIndex, localVertex); + + if (found) + { + const AZ::Vector3 worldVertex = AzToolsFramework::GetWorldTransform(entityId).TransformPoint(localVertex); + vertexScreenPositions.push_back(AzFramework::WorldToScreen(worldVertex, fixture.m_cameraState)); + } + } + + return vertexScreenPositions; + } + + AzToolsFramework::ViewportInteraction::MouseInteractionEvent BuildMiddleMouseDownEvent( + const AzFramework::ScreenPoint& screenPosition, const AzFramework::ViewportId viewportId) + { + AzToolsFramework::ViewportInteraction::MousePick mousePick; + mousePick.m_screenCoordinates = screenPosition; + + AzToolsFramework::ViewportInteraction::MouseInteraction mouseInteraction; + mouseInteraction.m_interactionId.m_cameraId = AZ::EntityId(); + mouseInteraction.m_interactionId.m_viewportId = viewportId; + mouseInteraction.m_mouseButtons = + AzToolsFramework::ViewportInteraction::MouseButtonsFromButton(AzToolsFramework::ViewportInteraction::MouseButton::Middle); + mouseInteraction.m_mousePick = mousePick; + mouseInteraction.m_keyboardModifiers = AzToolsFramework::ViewportInteraction::KeyboardModifiers( + static_cast(AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift) | + static_cast(AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl)); + + return AzToolsFramework::ViewportInteraction::MouseInteractionEvent( + mouseInteraction, AzToolsFramework::ViewportInteraction::MouseEvent::Down, /*captured=*/false); + } + + TEST_F(EditorVertexSelectionManipulatorFixture, VertexPlacedWhereIntersectionPointIsFoundWithCustomReferenceSpace) + { + const AZ::EntityId entityIdGround = CreateEntityForVertexIntersectionPlacement(*this); + + // position ground + AzToolsFramework::SetWorldTransform( + entityIdGround, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-20.0f)) * AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(-40.0f)) * + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(60.0f)), + AZ::Vector3(14.0f, -6.0f, 5.0f))); + + // camera (go to position format) - 12.00, 18.00, 16.00, -38.00, -175.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(-175.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-38.0f)), + AZ::Vector3(12.0f, 18.0f, 16.0f))); + + // create orientated and scaled transform for vertex selection entity transform + auto vertexSelectionTransform = AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(45.0f)), AZ::Vector3(14.0f, 7.0f, 5.0f)); + vertexSelectionTransform.MultiplyByUniformScale(3.0f); + + // set the initial starting position of the vertex selection + AzToolsFramework::SetWorldTransform(m_entityId, vertexSelectionTransform); + + auto vertexScreenPositions = SetupVertices(m_entityId, *this); + + // press and drag the mouse (starting where the surface manipulator is) + // select each vertex (by holding ctrl) + m_actionDispatcher->CameraState(m_cameraState)->MousePosition(vertexScreenPositions[0])->MouseLButtonDown()->MouseLButtonUp(); + + const auto finalPositionWorld = AZ::Vector3(14.3573294f, -8.94695091f, 7.08627319f); + // calculate the position in screen space of the final position of the entity + const auto finalPositionScreen = AzFramework::WorldToScreen(finalPositionWorld, m_cameraState); + + auto middleMouseDownEvent = + BuildMiddleMouseDownEvent(finalPositionScreen, m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId()); + + // explicitly handle mouse event in vertex selection instance + m_vertexSelection.HandleMouse(middleMouseDownEvent); + + // read back the position of the vertex now + AZ::Vector3 localVertex = AZ::Vector3::CreateZero(); + bool found = false; + AZ::FixedVerticesRequestBus::EventResult( + found, m_entityId, &AZ::FixedVerticesRequestBus::Handler::GetVertex, 0, localVertex); + + // transform to world space + const AZ::Vector3 worldVertex = vertexSelectionTransform.TransformPoint(localVertex); + + EXPECT_THAT(found, ::testing::IsTrue()); + // ensure final world positions match + EXPECT_THAT(worldVertex, IsCloseTolerance(finalPositionWorld, 0.01f)); + } } // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp new file mode 100644 index 0000000000..fdcc8553f2 --- /dev/null +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportInteractionTests.cpp @@ -0,0 +1,76 @@ +/* + * 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 + +namespace UnitTest +{ + class IndirectCallViewportInteractionIntersectionFixture : public ToolsApplicationFixture + { + public: + void SetUpEditorFixtureImpl() override + { + auto* app = GetApplication(); + // register a simple component implementing BoundsRequestBus and EditorComponentSelectionRequestsBus + app->RegisterComponentDescriptor(BoundsTestComponent::CreateDescriptor()); + // register a component implementing RenderGeometry::IntersectionRequestBus + app->RegisterComponentDescriptor(RenderGeometryIntersectionTestComponent::CreateDescriptor()); + + AZ::Entity* entityGround = nullptr; + m_entityIdGround = CreateDefaultEditorEntity("EntityGround", &entityGround); + + entityGround->Deactivate(); + auto ground = entityGround->CreateComponent(); + entityGround->Activate(); + + ground->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-10.0f, -10.0f, -0.5f), AZ::Vector3(10.0f, 10.0f, 0.5f)); + } + + AZ::EntityId m_entityIdGround; + }; + + using IndirectCallManipulatorViewportInteractionIntersectionFixture = + IndirectCallManipulatorViewportInteractionFixtureMixin; + + TEST_F(IndirectCallManipulatorViewportInteractionIntersectionFixture, FindClosestPickIntersectionReturnsExpectedSurfacePoint) + { + // camera - 21.00, 8.00, 11.00, -22.00, 150.00 + m_cameraState.m_viewportSize = AZ::Vector2(1280.0f, 720.0f); + AzFramework::SetCameraTransform( + m_cameraState, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(150.0f)) * AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-22.0f)), + AZ::Vector3(21.0f, 8.0f, 11.0f))); + + m_actionDispatcher->CameraState(m_cameraState); + + AzToolsFramework::SetWorldTransform( + m_entityIdGround, + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(40.0f)) * AZ::Matrix3x3::CreateRotationZ(AZ::DegToRad(60.0f)), + AZ::Vector3(14.0f, -6.0f, 5.0f))); + + // expected world position (value taken from editor scenario) + const auto expectedWorldPosition = AZ::Vector3(13.606657f, -2.6753534f, 5.9827675f); + const auto screenPosition = AzFramework::WorldToScreen(expectedWorldPosition, m_cameraState); + + // perform ray intersection against mesh + const auto worldIntersectionPoint = AzToolsFramework::FindClosestPickIntersection( + m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId(), screenPosition, + AzToolsFramework::EditorPickRayLength, AzToolsFramework::GetDefaultEntityPlacementDistance()); + + EXPECT_THAT(worldIntersectionPoint, IsCloseTolerance(expectedWorldPosition, 0.01f)); + } +} // namespace UnitTest diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 9e052de983..8e0297fb1f 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -136,5 +136,6 @@ set(FILES Viewport/ViewportUiDisplayTests.cpp Viewport/ViewportUiManagerTests.cpp Viewport/ViewportUiWidgetManagerTests.cpp + Viewport/ViewportInteractionTests.cpp Visibility/EditorVisibilityTests.cpp ) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp index 1a015c167c..7ae3175e03 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ViewportInteractionImpl.cpp @@ -50,10 +50,7 @@ namespace AtomToolsFramework AzToolsFramework::ViewportInteraction::ProjectedViewportRay ViewportInteractionImpl::ViewportScreenToWorldRay( const AzFramework::ScreenPoint& screenPosition) { - const AzFramework::CameraState cameraState = GetCameraState(); - const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPosition, cameraState); - const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized(); - return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection }; + return AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(GetCameraState(), screenPosition); } float ViewportInteractionImpl::DeviceScalingFactor() From 768a196b63c45b1d09fc2c43a6b1068ab22212f6 Mon Sep 17 00:00:00 2001 From: rgba16f <82187279+rgba16f@users.noreply.github.com> Date: Tue, 30 Nov 2021 10:11:26 -0600 Subject: [PATCH 27/72] Add a way to set the vsync_interval CVar from code (#5813) * Add a way to set the render vsync from code Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> * Update change with PR feedback. Missing whitespace plus a comment on why the assignment is outside the value changed check Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> --- .../AzCore/AzCore/Console/ConsoleDataWrapper.inl | 9 +++++++++ .../AzFramework/AzFramework/Windowing/NativeWindow.cpp | 7 +++++++ .../AzFramework/AzFramework/Windowing/NativeWindow.h | 1 + .../AzFramework/AzFramework/Windowing/WindowBus.h | 4 ++++ .../AzFramework/Tests/Mocks/MockWindowRequests.h | 1 + .../AtomToolsFramework/Viewport/RenderViewportWidget.h | 1 + .../Code/Source/Viewport/RenderViewportWidget.cpp | 7 +++++++ 7 files changed, 30 insertions(+) diff --git a/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl b/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl index 46774f23b2..b3a59d287d 100644 --- a/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl +++ b/Code/Framework/AzCore/AzCore/Console/ConsoleDataWrapper.inl @@ -32,7 +32,16 @@ namespace AZ template inline void ConsoleDataWrapper::operator =(const BASE_TYPE& rhs) { + const BASE_TYPE currentValue = this->m_value; + // Do the value assignment outside new value check. + // Client code can supply a type for m_value that overrides the operator= function and trigger side effects + // in the operator= function body. Doing the assignment outside the value change check avoids those side + // effects not being triggered because AzCore believes the value wouldn't change. this->m_value = rhs; + if (currentValue != rhs) + { + InvokeCallback(); + } } template diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp index c89d12a8ae..bb3c5e4388 100644 --- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp +++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp @@ -143,6 +143,13 @@ namespace AzFramework return vsync_interval; } + bool NativeWindow::SetSyncInterval(uint32_t newSyncInterval) + { + vsync_interval = newSyncInterval; + return true; + } + + /*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow() { NativeWindowHandle defaultWindowHandle = nullptr; diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h index 0eb699475f..9c844034cb 100644 --- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h +++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h @@ -132,6 +132,7 @@ namespace AzFramework void ToggleFullScreenState() override; float GetDpiScaleFactor() const override; uint32_t GetSyncInterval() const override; + bool SetSyncInterval(uint32_t newSyncInterval) override; uint32_t GetDisplayRefreshRate() const override; //! Get the full screen state of the default window. diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h index d3bd0ce82c..faae925580 100644 --- a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h +++ b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h @@ -78,6 +78,10 @@ namespace AzFramework //! Returns the sync interval which tells the drivers the number of v-blanks to synchronize with virtual uint32_t GetSyncInterval() const = 0; + //! Sets the sync interval which tells the drivers the number of v-blanks to synchronize with + //! Returns if the sync interval was succesfully set + virtual bool SetSyncInterval(uint32_t newSyncInterval) = 0; + //! Returns the refresh rate of the main display virtual uint32_t GetDisplayRefreshRate() const = 0; }; diff --git a/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h b/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h index 63f73d0b28..a166df19b4 100644 --- a/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h +++ b/Code/Framework/AzFramework/Tests/Mocks/MockWindowRequests.h @@ -36,6 +36,7 @@ namespace UnitTest MOCK_METHOD0(ToggleFullScreenState, void()); MOCK_CONST_METHOD0(GetDpiScaleFactor, float()); MOCK_CONST_METHOD0(GetSyncInterval, uint32_t()); + MOCK_METHOD1(SetSyncInterval, bool(uint32_t)); MOCK_CONST_METHOD0(GetDisplayRefreshRate, uint32_t()); }; } // namespace UnitTest diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h index 45838a5378..3393897936 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h @@ -116,6 +116,7 @@ namespace AtomToolsFramework void ToggleFullScreenState() override; float GetDpiScaleFactor() const override; uint32_t GetSyncInterval() const override; + bool SetSyncInterval(uint32_t newSyncInterval) override; uint32_t GetDisplayRefreshRate() const override; protected: diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 759f939382..f6efdc57b8 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -395,4 +395,11 @@ namespace AtomToolsFramework { return 1; } + + // Editor ignores requests to change the sync interval + bool RenderViewportWidget::SetSyncInterval(uint32_t /*ignored*/) + { + return false; + } + } //namespace AtomToolsFramework From 4dd9e94bc34c3108bad5b8203eebae8ec181b94a Mon Sep 17 00:00:00 2001 From: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 21:50:25 +0530 Subject: [PATCH 28/72] Add tests for deleting an entity from the level and from another prefab (#5839) * Added tests for deleting entity under level and other prefabs Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Added class comments and improved variable names Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Called the reflect function of PrefabFocusHandler from PrefabSystemComponent Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> * Added function comments and made an if statement to be one line Signed-off-by: srikappa-amzn <82230713+srikappa-amzn@users.noreply.github.com> --- .../editor_entity_utils.py | 11 ++++ .../Gem/PythonTests/Prefab/TestSuite_Main.py | 8 +++ .../DeleteEntity_UnderAnotherPrefab.py | 52 +++++++++++++++++++ .../DeleteEntity_UnderLevelPrefab.py | 37 +++++++++++++ .../Prefab/PrefabFocusHandler.cpp | 14 +++++ .../Prefab/PrefabFocusHandler.h | 8 +-- .../Prefab/PrefabFocusPublicInterface.h | 14 +++++ .../Prefab/PrefabSystemComponent.cpp | 1 + 8 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py create mode 100644 AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 59e454479c..309601b0ba 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -459,3 +459,14 @@ class EditorEntity: """ new_translation = convert_to_azvector3(new_translation) azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalTranslation", self.id, new_translation) + + # Use this only when prefab system is enabled as it will fail otherwise. + def focus_on_owning_prefab(self) -> None: + """ + Focuses on the owning prefab instance of the given entity. + :param entity: The entity used to fetch the owning prefab to focus on. + """ + + assert self.id.isValid(), "A valid entity id is required to focus on its owning prefab." + focus_prefab_result = azlmbr.prefab.PrefabFocusPublicRequestBus(bus.Broadcast, "FocusOnOwningPrefab", self.id) + assert focus_prefab_result.IsSuccess(), f"Prefab operation 'FocusOnOwningPrefab' failed. Error: {focus_prefab_result.GetError()}" diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py index c1d4836342..6e1f94d358 100644 --- a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py @@ -61,3 +61,11 @@ class TestAutomation(TestAutomationBase): def test_CreatePrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform): from Prefab.tests.create_prefab import CreatePrefab_UnderAnotherPrefab as test_module self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False) + + def test_DeleteEntity_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform): + from Prefab.tests.delete_entity import DeleteEntity_UnderAnotherPrefab as test_module + self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False) + + def test_DeleteEntity_UnderLevelPrefab(self, request, workspace, editor, launcher_platform): + from Prefab.tests.delete_entity import DeleteEntity_UnderLevelPrefab as test_module + self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False) diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py new file mode 100644 index 0000000000..deaaaedf30 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py @@ -0,0 +1,52 @@ +""" +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 +""" + +def DeleteEntity_UnderAnotherPrefab(): + """ + Test description: + - Creates an entity. + - Creates a prefab out of the above entity. + - Focuses on the created prefab and destroys the entity within. + Checks that the entity is correctly destroyed. + """ + + from editor_python_test_tools.editor_entity_utils import EditorEntity + from editor_python_test_tools.prefab_utils import Prefab + + import Prefab.tests.PrefabTestUtils as prefab_test_utils + + prefab_test_utils.open_base_tests_level() + + PREFAB_FILE_NAME = 'some_prefab' + + # Creates a new entity at the root level + entity = EditorEntity.create_editor_entity() + assert entity.id.IsValid(), "Couldn't create entity." + + # Asserts if prefab creation doesn't succeed + child_prefab, child_instance = Prefab.create_prefab([entity], PREFAB_FILE_NAME) + child_entity_ids_inside_prefab = child_instance.get_direct_child_entities() + assert len( + child_entity_ids_inside_prefab) == 1, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \ + f" when there should have been just 1 entity" + + child_entity_inside_prefab = child_entity_ids_inside_prefab[0] + child_entity_inside_prefab.focus_on_owning_prefab() + + child_entity_inside_prefab.delete() + + # Wait till prefab propagation finishes before validating entity deletion. + azlmbr.legacy.general.idle_wait_frames(1) + + child_entity_ids_inside_prefab = child_instance.get_direct_child_entities() + assert len( + child_entity_ids_inside_prefab) == 0, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \ + f" when there should have been 0 entities" + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(DeleteEntity_UnderAnotherPrefab) diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py new file mode 100644 index 0000000000..807427718c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py @@ -0,0 +1,37 @@ +""" +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 +""" + +def DeleteEntity_UnderLevelPrefab(): + """ + Test description: + - Creates an entity. + - Destroys the created entity. + Checks that the entity is correctly destroyed. + """ + + from editor_python_test_tools.editor_entity_utils import EditorEntity + import Prefab.tests.PrefabTestUtils as prefab_test_utils + + prefab_test_utils.open_base_tests_level() + + # Creates a new Entity at the root level + # Asserts if creation didn't succeed + entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0), name = "TestEntity") + assert entity.id.IsValid(), "Couldn't create entity" + + level_container_entity = EditorEntity(entity.get_parent_id()) + entity.delete() + + # Wait till prefab propagation finishes before validating entity deletion. + azlmbr.legacy.general.idle_wait_frames(1) + level_container_child_entities_count = len(level_container_entity.get_children_ids()) + assert level_container_child_entities_count == 0, f"The level still has {level_container_child_entities_count}" \ + f" children when it should have 0." + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(DeleteEntity_UnderLevelPrefab) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp index f20c11a1d8..2ab68bfc10 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp @@ -34,10 +34,12 @@ namespace AzToolsFramework::Prefab PrefabPublicNotificationBus::Handler::BusConnect(); AZ::Interface::Register(this); AZ::Interface::Register(this); + PrefabFocusPublicRequestBus::Handler::BusConnect(); } PrefabFocusHandler::~PrefabFocusHandler() { + PrefabFocusPublicRequestBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); AZ::Interface::Unregister(this); PrefabPublicNotificationBus::Handler::BusDisconnect(); @@ -45,6 +47,18 @@ namespace AzToolsFramework::Prefab EditorEntityInfoNotificationBus::Handler::BusDisconnect(); } + void PrefabFocusHandler::Reflect(AZ::ReflectContext* context) + { + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context); behaviorContext) + { + behaviorContext->EBus("PrefabFocusPublicRequestBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) + ->Attribute(AZ::Script::Attributes::Category, "Prefab") + ->Attribute(AZ::Script::Attributes::Module, "prefab") + ->Event("FocusOnOwningPrefab", &PrefabFocusPublicInterface::FocusOnOwningPrefab); + } + } + void PrefabFocusHandler::InitializeEditorInterfaces() { m_containerEntityInterface = AZ::Interface::Get(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h index 2e23059a01..b02106d69d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h @@ -30,8 +30,8 @@ namespace AzToolsFramework::Prefab //! Handles Prefab Focus mode, determining which prefab file entity changes will target. class PrefabFocusHandler final - : private PrefabFocusInterface - , private PrefabFocusPublicInterface + : public PrefabFocusPublicRequestBus::Handler + , private PrefabFocusInterface , private PrefabPublicNotificationBus::Handler , private EditorEntityContextNotificationBus::Handler , private EditorEntityInfoNotificationBus::Handler @@ -42,13 +42,15 @@ namespace AzToolsFramework::Prefab PrefabFocusHandler(); ~PrefabFocusHandler(); + static void Reflect(AZ::ReflectContext* context); + // PrefabFocusInterface overrides ... void InitializeEditorInterfaces() override; PrefabFocusOperationResult FocusOnPrefabInstanceOwningEntityId(AZ::EntityId entityId) override; TemplateId GetFocusedPrefabTemplateId(AzFramework::EntityContextId entityContextId) const override; InstanceOptionalReference GetFocusedPrefabInstance(AzFramework::EntityContextId entityContextId) const override; - // PrefabFocusPublicInterface overrides ... + // PrefabFocusPublicInterface and PrefabFocusPublicRequestBus overrides ... PrefabFocusOperationResult FocusOnOwningPrefab(AZ::EntityId entityId) override; PrefabFocusOperationResult FocusOnParentOfFocusedPrefab(AzFramework::EntityContextId entityContextId) override; PrefabFocusOperationResult FocusOnPathIndex(AzFramework::EntityContextId entityContextId, int index) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h index 2fc9ef6b9a..2c0e95f1cc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusPublicInterface.h @@ -58,4 +58,18 @@ namespace AzToolsFramework::Prefab virtual const int GetPrefabFocusPathLength(AzFramework::EntityContextId entityContextId) const = 0; }; + /** + * The primary purpose of this bus is to facilitate writing automated tests for prefab focus mode. + * If you would like to integrate prefabs focus mode into your system, please call PrefabFocusPublicInterface + * for better performance. + */ + class PrefabFocusPublicRequests + : public AZ::EBusTraits + { + public: + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + }; + + using PrefabFocusPublicRequestBus = AZ::EBus; + } // namespace AzToolsFramework::Prefab diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 62d7a6ac1d..ed16606413 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -60,6 +60,7 @@ namespace AzToolsFramework AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor::Reflect(context); AzToolsFramework::Prefab::PrefabConversionUtils::EditorInfoRemover::Reflect(context); PrefabPublicRequestHandler::Reflect(context); + PrefabFocusHandler::Reflect(context); PrefabLoader::Reflect(context); PrefabSystemScriptingHandler::Reflect(context); From 12efc846325422137e3dce89b396842912a0f6b6 Mon Sep 17 00:00:00 2001 From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:27:27 -0800 Subject: [PATCH 29/72] [development] minor Profiler gem fixes (#5473) Fixed incorrect frame boundary guess when loading a profile capture Added some missing default initializers Removed implicit dependency on Atom timing marker constants Fixed issue with small visualizer viewport bounds when loading a saved capture Signed-off-by: AMZN-ScottR 24445312+AMZN-ScottR@users.noreply.github.com --- .../Statistics/StatisticalProfilerProxy.h | 16 ++++++++ .../AzCore/Statistics/StatisticsManager.h | 14 ++++++- Gems/Profiler/Code/Source/CpuProfilerImpl.h | 2 +- .../Profiler/Code/Source/ImGuiCpuProfiler.cpp | 41 +++++++++++-------- Gems/Profiler/Code/Source/ImGuiCpuProfiler.h | 7 ++-- 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h b/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h index 278b2ecc98..7fae0ca354 100644 --- a/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h +++ b/Code/Framework/AzCore/AzCore/Statistics/StatisticalProfilerProxy.h @@ -157,6 +157,22 @@ namespace AZ::Statistics } } + void GetAllStatistics(AZStd::vector& stats) + { + for (auto& iter : m_profilers) + { + iter.second.m_profiler.GetStatsManager().GetAllStatistics(stats); + } + } + + void GetAllStatisticsOfUnits(AZStd::vector& stats, const char* units) + { + for (auto& iter : m_profilers) + { + iter.second.m_profiler.GetStatsManager().GetAllStatisticsOfUnits(stats, units); + } + } + private: struct ProfilerInfo { diff --git a/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h b/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h index 5984701f4e..dc97de40c1 100644 --- a/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h +++ b/Code/Framework/AzCore/AzCore/Statistics/StatisticsManager.h @@ -56,13 +56,25 @@ namespace AZ void GetAllStatistics(AZStd::vector& vector) { - for (auto const& it : m_statistics) + for (const auto& it : m_statistics) { NamedRunningStatistic* stat = it.second; vector.push_back(stat); } } + void GetAllStatisticsOfUnits(AZStd::vector& vector, const char* units) + { + for (const auto& it : m_statistics) + { + NamedRunningStatistic* stat = it.second; + if (stat->GetUnits() == units) + { + vector.push_back(stat); + } + } + } + //! Helper method to apply units to statistics with empty units string. AZ::u32 ApplyUnits(const AZStd::string& units) { diff --git a/Gems/Profiler/Code/Source/CpuProfilerImpl.h b/Gems/Profiler/Code/Source/CpuProfilerImpl.h index 6611fbd1e5..c97e45e69c 100644 --- a/Gems/Profiler/Code/Source/CpuProfilerImpl.h +++ b/Gems/Profiler/Code/Source/CpuProfilerImpl.h @@ -150,7 +150,7 @@ namespace Profiler AZStd::mutex m_continuousCaptureEndingMutex; - AZStd::atomic_bool m_continuousCaptureInProgress; + AZStd::atomic_bool m_continuousCaptureInProgress = false; // Stores multiple frames of profiling data, size is controlled by MaxFramesToSave. Flushed when EndContinuousCapture is called. // Ring buffer so that we can have fast append of new data + removal of old profiling data with good cache locality. diff --git a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp index 26c2f9f974..1cb13fe4ac 100644 --- a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp +++ b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.cpp @@ -23,9 +23,13 @@ #include #include #include +#include namespace Profiler { + constexpr AZStd::sys_time_t ProfilerViewEdgePadding = 5000; + constexpr size_t InitialCpuTimingStatsAllocation = 8; + namespace CpuProfilerImGuiHelper { float TicksToMs(double ticks) @@ -435,6 +439,11 @@ namespace Profiler m_tableData.clear(); m_groupRegionMap.clear(); + // Since we don't serialize the frame boundaries, we will use "Component application simulation tick" from + // ComponentApplication::Tick as a heuristic. + static const AZ::Name::Hash frameBoundaryHash = AZ::Name("Component application simulation tick").GetHash(); + + AZStd::sys_time_t frameTime = 0; for (const auto& entry : deserializedData) { const auto [groupNameItr, wasGroupNameInserted] = m_deserializedStringPool.emplace(entry.m_groupName.GetCStr()); @@ -445,10 +454,12 @@ namespace Profiler const CachedTimeRegion newRegion(*groupRegionNameItr, entry.m_stackDepth, entry.m_startTick, entry.m_endTick); m_savedData[entry.m_threadId].push_back(newRegion); - // Since we don't serialize the frame boundaries, we need to use the RPI's OnSystemTick event as a heuristic. - const static AZ::Name frameBoundaryName = AZ::Name("RPISystem: OnSystemTick"); - if (entry.m_regionName == frameBoundaryName) + if (entry.m_regionName.GetHash() == frameBoundaryHash) { + if (!m_frameEndTicks.empty()) + { + frameTime = entry.m_endTick - m_frameEndTicks.back(); + } m_frameEndTicks.push_back(entry.m_endTick); } @@ -462,9 +473,9 @@ namespace Profiler m_groupRegionMap[*groupNameItr][*regionNameItr].RecordRegion(newRegion, entry.m_threadId); } - // Update viewport bounds with some added UX fudge factor - m_viewportStartTick = deserializedData.back().m_startTick - 1000; - m_viewportEndTick = deserializedData.back().m_endTick + 1000; + // Update viewport bounds to the estimated final frame time with some padding + m_viewportStartTick = m_frameEndTicks.back() - frameTime - ProfilerViewEdgePadding; + m_viewportEndTick = m_frameEndTicks.back() + ProfilerViewEdgePadding; // Invariant: each vector in m_savedData must be sorted so that we can efficiently cull region data. for (auto& [threadId, singleThreadData] : m_savedData) @@ -642,21 +653,13 @@ namespace Profiler m_cpuTimingStatisticsWhenPause.clear(); if (auto statsProfiler = AZ::Interface::Get(); statsProfiler) { - auto& rhiMetrics = statsProfiler->GetProfiler(AZ_CRC_CE("RHI")); - - const NamedRunningStatistic* frameTimeMetric = rhiMetrics.GetStatistic(AZ_CRC_CE("Frame to Frame Time")); - if (frameTimeMetric) - { - m_frameToFrameTime = static_cast(frameTimeMetric->GetMostRecentSample()); - } - AZStd::vector statistics; - rhiMetrics.GetStatsManager().GetAllStatistics(statistics); + statistics.reserve(InitialCpuTimingStatsAllocation); + statsProfiler->GetAllStatisticsOfUnits(statistics, "clocks"); for (NamedRunningStatistic* stat : statistics) { m_cpuTimingStatisticsWhenPause.push_back({ stat->GetName(), stat->GetMostRecentSample() }); - stat->Reset(); } } } @@ -731,7 +734,11 @@ namespace Profiler void ImGuiCpuProfiler::CullFrameData() { - const AZStd::sys_time_t deleteBeforeTick = AZStd::GetTimeNowTicks() - m_frameToFrameTime * m_framesToCollect; + const AZ::TimeUs delta = AZ::GetRealTickDeltaTimeUs(); + const float deltaTimeInSeconds = AZ::TimeUsToSeconds(delta); + const AZStd::sys_time_t frameToFrameTime = static_cast(deltaTimeInSeconds * AZStd::GetTimeTicksPerSecond()); + + const AZStd::sys_time_t deleteBeforeTick = AZStd::GetTimeNowTicks() - frameToFrameTime * m_framesToCollect; // Remove old frame boundary data auto firstBoundaryToKeepItr = AZStd::upper_bound(m_frameEndTicks.begin(), m_frameEndTicks.end(), deleteBeforeTick); diff --git a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h index 2e01b8fd6b..d5d27632f8 100644 --- a/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h +++ b/Gems/Profiler/Code/Source/ImGuiCpuProfiler.h @@ -89,7 +89,7 @@ namespace Profiler struct CpuTimingEntry { const AZStd::string& m_name; - double m_executeDuration; + double m_executeDuration = 0; }; ImGuiCpuProfiler() = default; @@ -175,8 +175,8 @@ namespace Profiler AZ::u64 m_savedRegionCount = 0; // Viewport tick bounds, these are used to convert tick space -> screen space and cull so we only draw onscreen objects - AZStd::sys_time_t m_viewportStartTick; - AZStd::sys_time_t m_viewportEndTick; + AZStd::sys_time_t m_viewportStartTick = 0; + AZStd::sys_time_t m_viewportEndTick = 0; // Map to store each thread's TimeRegions, individual vectors are sorted by start tick // note: we use size_t as a proxy for thread_id because native_thread_id_type differs differs from @@ -215,7 +215,6 @@ namespace Profiler // Last captured CPU timing statistics AZStd::vector m_cpuTimingStatisticsWhenPause; - AZStd::sys_time_t m_frameToFrameTime{}; AZ::IO::FixedMaxPath m_lastCapturedFilePath; From 6cb53891edcac615074ce495762e2a77957dd385 Mon Sep 17 00:00:00 2001 From: Roman <69218254+amzn-rhhong@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:32:11 -0800 Subject: [PATCH 30/72] Store camera settings (#6013) * load and save camera options Signed-off-by: rhhong * CR feedback Signed-off-by: rhhong --- .../Tools/EMStudio/AnimViewportToolBar.cpp | 28 +++++++++++++++++++ .../Code/Tools/EMStudio/AnimViewportToolBar.h | 4 ++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp index 7bb8d49418..0cf6dd70b3 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.cpp @@ -8,8 +8,10 @@ #include #include +#include #include #include +#include #include #include @@ -109,6 +111,13 @@ namespace EMStudio cameraButton->setIcon(QIcon(":/EMotionFXAtom/Camera_category.svg")); addWidget(cameraButton); } + + LoadSettings(); + } + + AnimViewportToolBar::~AnimViewportToolBar() + { + SaveSettings(); } void AnimViewportToolBar::CreateViewOptionEntry( @@ -144,4 +153,23 @@ namespace EMStudio } } } + + void AnimViewportToolBar::LoadSettings() + { + AZStd::string renderFlagsFilename(EMStudioManager::GetInstance()->GetAppDataFolder()); + renderFlagsFilename += "AnimViewportRenderFlags.cfg"; + QSettings settings(renderFlagsFilename.c_str(), QSettings::IniFormat, this); + + const bool isChecked = settings.value("CameraFollowUp", false).toBool(); + m_followCharacterAction->setChecked(isChecked); + } + + void AnimViewportToolBar::SaveSettings() + { + AZStd::string renderFlagsFilename(EMStudioManager::GetInstance()->GetAppDataFolder()); + renderFlagsFilename += "AnimViewportRenderFlags.cfg"; + QSettings settings(renderFlagsFilename.c_str(), QSettings::IniFormat, this); + + settings.setValue("CameraFollowUp", m_followCharacterAction->isChecked()); + } } // namespace EMStudio diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h index 1443c54ee9..98b07f07dd 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportToolBar.h @@ -22,9 +22,11 @@ namespace EMStudio { public: AnimViewportToolBar(QWidget* parent = nullptr); - ~AnimViewportToolBar() = default; + ~AnimViewportToolBar(); void SetRenderFlags(EMotionFX::ActorRenderFlagBitset renderFlags); + void LoadSettings(); + void SaveSettings(); private: void CreateViewOptionEntry( From aab6e33d3032531b18acd68407c627c34a66057f Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:41:27 -0800 Subject: [PATCH 31/72] Non unity build fix Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp index 262ea8c061..7ebbd4bc6d 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeUtils.cpp @@ -12,6 +12,7 @@ #include #include +#include #include namespace ScriptCanvasEditor::Nodes From 3a1e6744fbcd69d16a7314a51248f540b0efa3ad Mon Sep 17 00:00:00 2001 From: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:47:21 -0800 Subject: [PATCH 32/72] Save Data linux support (#6014) Implementation of SaveData for Linux Signed-off-by: Steve Pham <82231385+spham-amzn@users.noreply.github.com> --- .../Platform/Linux/AzTest_Traits_Linux.h | 2 - .../Linux/SaveData_SystemComponent_Linux.cpp | 173 ++++++++++++++++++ .../Platform/Linux/platform_linux_files.cmake | 2 +- 3 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp diff --git a/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h b/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h index d9b48b7835..755888e1d9 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h +++ b/Code/Framework/AzTest/AzTest/Platform/Linux/AzTest_Traits_Linux.h @@ -13,8 +13,6 @@ #define AZ_TRAIT_UNIT_TEST_ENTITY_ID_GEN_TEST_COUNT 10000 #define AZ_TRAIT_UNIT_TEST_DILLER_TRIGGER_EVENT_COUNT 100000 -#define AZ_TRAIT_DISABLE_ALL_SAVE_DATA_TESTS true - #define AZ_TRAIT_DISABLE_FAILED_AP_CONNECTION_TESTS true #define AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS true diff --git a/Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp b/Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp new file mode 100644 index 0000000000..caa9e9bf54 --- /dev/null +++ b/Gems/SaveData/Code/Source/Platform/Linux/SaveData_SystemComponent_Linux.cpp @@ -0,0 +1,173 @@ +/* + * 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 + +//////////////////////////////////////////////////////////////////////////////////////////////////// +namespace SaveData +{ + //////////////////////////////////////////////////////////////////////////////////////////////// + //! Platform specific implementation for the save data system component on Linux + class SaveDataSystemComponentLinux : public SaveDataSystemComponent::Implementation + { + public: + //////////////////////////////////////////////////////////////////////////////////////////// + static constexpr const char* DefaultSaveDataDirectoryName = "SaveData"; + + //////////////////////////////////////////////////////////////////////////////////////////// + // Allocator + AZ_CLASS_ALLOCATOR(SaveDataSystemComponentLinux, AZ::SystemAllocator, 0); + + //////////////////////////////////////////////////////////////////////////////////////////// + //! Constructor + //! \param[in] saveDataSystemComponent Reference to the parent being implemented + SaveDataSystemComponentLinux(SaveDataSystemComponent& saveDataSystemComponent); + + //////////////////////////////////////////////////////////////////////////////////////////// + //! Destructor + ~SaveDataSystemComponentLinux() override; + + protected: + //////////////////////////////////////////////////////////////////////////////////////////// + //! \ref SaveData::SaveDataSystemComponent::Implementation::SaveDataBuffer + void SaveDataBuffer(const SaveDataRequests::SaveDataBufferParams& saveDataBufferParams) override; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! \ref SaveData::SaveDataSystemComponent::Implementation::LoadDataBuffer + void LoadDataBuffer(const SaveDataRequests::LoadDataBufferParams& loadDataBufferParams) override; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! \ref SaveData::SaveDataSystemComponent::Implementation::SetSaveDataDirectoryPath + void SetSaveDataDirectoryPath(const char* saveDataDirectoryPath) override; + + private: + //////////////////////////////////////////////////////////////////////////////////////////// + //! Convenience function to construct the full save data file path. + //! \param[in] dataBufferName The name of the save data buffer. + //! \param[in] localUserId The local user id the save data buffer is associated with. + AZ::IO::Path GetSaveDataFilePath(const AZStd::string& dataBufferName, + AzFramework::LocalUserId localUserId); + + //////////////////////////////////////////////////////////////////////////////////////////// + //! The absolute path to the application's save data dircetory. + AZ::IO::Path m_saveDataDirectoryPathAbsolute; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////// + AZ::IO::Path GetDefaultLinuxUserSaveDataPath() + { + // First priority for the home directory is the 'HOME' environment variable + const char* homeDir = getenv("HOME"); + if (homeDir == nullptr) + { + // If the 'HOME' environment variable is not set, then retrieve it from the 'getpwuid' + // system call + auto uid = getuid(); + auto pwuid = getpwuid(uid); + homeDir = pwuid->pw_dir; + } + + AZ_Assert(homeDir, "Unable to determine home directory for current Linux user"); + if (homeDir == nullptr) + { + homeDir = "/tmp"; + } + + AZ::IO::Path homePath {homeDir}; + + // $HOME/.local/share is the standard directory where user data is stored on Ubuntu + return homePath / ".local" / "share"; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + AZStd::string GetExecutableName() + { + char moduleFileName[AZ_MAX_PATH_LEN]; + AZ::Utils::GetExecutablePath(moduleFileName, AZ_MAX_PATH_LEN); + + AZ::IO::Path executableFullPath {moduleFileName}; + AZStd::string moduleFileNameString {executableFullPath.Filename().Native()}; + return moduleFileNameString; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + SaveDataSystemComponent::Implementation* SaveDataSystemComponent::Implementation::Create(SaveDataSystemComponent& saveDataSystemComponent) + { + return aznew SaveDataSystemComponentLinux(saveDataSystemComponent); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + SaveDataSystemComponentLinux::SaveDataSystemComponentLinux(SaveDataSystemComponent& saveDataSystemComponent) + : SaveDataSystemComponent::Implementation(saveDataSystemComponent) + , m_saveDataDirectoryPathAbsolute(GetDefaultLinuxUserSaveDataPath() / + GetExecutableName().c_str() / + DefaultSaveDataDirectoryName) + { + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + SaveDataSystemComponentLinux::~SaveDataSystemComponentLinux() + { + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + void SaveDataSystemComponentLinux::SaveDataBuffer(const SaveDataRequests::SaveDataBufferParams& saveDataBufferParams) + { + const AZStd::string absoluteFilePath = GetSaveDataFilePath(saveDataBufferParams.dataBufferName, + saveDataBufferParams.localUserId).c_str(); + SaveDataBufferToFileSystem(saveDataBufferParams, absoluteFilePath); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + void SaveDataSystemComponentLinux::LoadDataBuffer(const SaveDataRequests::LoadDataBufferParams& loadDataBufferParams) + { + const AZStd::string absoluteFilePath = GetSaveDataFilePath(loadDataBufferParams.dataBufferName, + loadDataBufferParams.localUserId).c_str(); + LoadDataBufferFromFileSystem(loadDataBufferParams, absoluteFilePath); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + void SaveDataSystemComponentLinux::SetSaveDataDirectoryPath(const char* saveDataDirectoryPath) + { + AZ::IO::Path saveDataDirectoryBasicPath { saveDataDirectoryPath }; + + if (saveDataDirectoryBasicPath.IsAbsolute()) + { + m_saveDataDirectoryPathAbsolute = saveDataDirectoryBasicPath; + } + else + { + m_saveDataDirectoryPathAbsolute = GetDefaultLinuxUserSaveDataPath() / saveDataDirectoryBasicPath; + } + + AZ_Assert(!m_saveDataDirectoryPathAbsolute.empty(), "Cannot set an empty save data directory path."); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + AZ::IO::Path SaveDataSystemComponentLinux::GetSaveDataFilePath(const AZStd::string& dataBufferName, + AzFramework::LocalUserId localUserId) + { + AZ::IO::Path saveDataFilePath = m_saveDataDirectoryPathAbsolute; + if (localUserId != AzFramework::LocalUserIdNone) + { + saveDataFilePath /= AZStd::string::format("User_%u", localUserId); + } + saveDataFilePath /= dataBufferName; + return saveDataFilePath; + } +} // namespace SaveData diff --git a/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake b/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake index 2ef4de6b91..42209a111c 100644 --- a/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake +++ b/Gems/SaveData/Code/Source/Platform/Linux/platform_linux_files.cmake @@ -7,7 +7,7 @@ # set(FILES - ../Common/Unimplemented/SaveData_SystemComponent_Unimplemented.cpp + SaveData_SystemComponent_Linux.cpp SaveData_Traits_Platform.h SaveData_Traits_Linux.h ) From 1f13a5bbf244517ceebafd476e80bac75ed3b625 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Tue, 30 Nov 2021 10:48:39 -0600 Subject: [PATCH 33/72] Removed include/LmbrCentral/Rendering/RenderNodeBus.h that was red-coded. Signed-off-by: Chris Galvan --- Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake index 67f526cf21..a3bc87a620 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_headers_files.cmake @@ -36,7 +36,6 @@ set(FILES include/LmbrCentral/Rendering/MaterialHandle.h include/LmbrCentral/Rendering/MeshAsset.h include/LmbrCentral/Rendering/MeshModificationBus.h - include/LmbrCentral/Rendering/RenderNodeBus.h include/LmbrCentral/Rendering/GiRegistrationBus.h include/LmbrCentral/Rendering/RenderBoundsBus.h include/LmbrCentral/Scripting/EditorTagComponentBus.h From dc3c1266624dab7871f7c09b9118139e659c4a3a Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:30:00 -0600 Subject: [PATCH 34/72] GetSurfacePoint - expose to BehaviorContext (#6017) * Fix GetSurfacePoint exposure to BehaviorContext. The previous way of exposing it made it unusable from ScriptCanvas, since the public API uses an "out" parameter. This introduces a private variation of the API that returns the value instead, so that it functions correctly in Script Canvas. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added descriptive comment. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Addressed PR feedback. Fixed comment spacing and renamed private methods to remove the need for the typecast. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../Terrain/TerrainDataRequestBus.cpp | 5 ++- .../Terrain/TerrainDataRequestBus.h | 41 ++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp index 561408db20..f803e73462 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.cpp @@ -26,10 +26,11 @@ namespace AzFramework::Terrain ->Event("GetSurfaceWeights", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeights) ->Event("GetSurfaceWeightsFromVector2", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeightsFromVector2) + ->Event("GetIsHole", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHole) ->Event("GetIsHoleFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHoleFromFloats) - ->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePoint) + ->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePoint) ->Event("GetSurfacePointFromVector2", - &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePointFromVector2) + &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePointFromVector2) ->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb) ->Event("GetTerrainHeightQueryResolution", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution) diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h index 30a2f8e044..4c73ddd770 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h @@ -52,8 +52,8 @@ namespace AzFramework virtual void SetTerrainAabb(const AZ::Aabb& worldBounds) = 0; //! Returns terrains height in meters at location x,y. - //! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will become false, - //! otherwise *terrainExistsPtr will become true. + //! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside + //! a terrain HOLE then *terrainExistsPtr will become false, otherwise *terrainExistsPtr will become true. virtual float GetHeight(const AZ::Vector3& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; virtual float GetHeightFromVector2( const AZ::Vector2& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; @@ -68,8 +68,7 @@ namespace AzFramework // Given an XY coordinate, return the surface normal. //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a - //! terrain HOLE then *terrainExistsPtr will be set to false, - //! otherwise *terrainExistsPtr will be set to true. + //! terrain HOLE then *terrainExistsPtr will be set to false, otherwise *terrainExistsPtr will be set to true. virtual AZ::Vector3 GetNormal( const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; virtual AZ::Vector3 GetNormalFromVector2( @@ -78,8 +77,8 @@ namespace AzFramework float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; //! Given an XY coordinate, return the max surface type and weight. - //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will be set to false, - //! otherwise *terrainExistsPtr will be set to true. + //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside + //! a terrain HOLE then *terrainExistsPtr will be set to false, otherwise *terrainExistsPtr will be set to true. virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight( const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromVector2( @@ -87,8 +86,8 @@ namespace AzFramework virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromFloats( float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; - //! Given an XY coordinate, return the set of surface types and weights. The Vector3 input position version is defined to ignore - //! the input Z value. + //! Given an XY coordinate, return the set of surface types and weights. The Vector3 input position version is defined to + //! ignore the input Z value. virtual void GetSurfaceWeights( const AZ::Vector3& inPosition, SurfaceData::SurfaceTagWeightList& outSurfaceWeights, @@ -106,13 +105,14 @@ namespace AzFramework Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const = 0; - //! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats. + //! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use + //! GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats. //! Not available in the behavior context. //! Returns nullptr if the position is inside a hole or outside of the terrain boundaries. virtual const char* GetMaxSurfaceName( const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0; - //! Given an XY coordinate, return all terrain information at that location. The Vector3 input position version is defined + //! Given an XY coordinate, return all terrain information at that location. The Vector3 input position version is defined //! to ignore the input Z value. virtual void GetSurfacePoint( const AZ::Vector3& inPosition, @@ -130,6 +130,27 @@ namespace AzFramework SurfaceData::SurfacePoint& outSurfacePoint, Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const = 0; + + private: + // Private variations of the GetSurfacePoint API exposed to BehaviorContext that returns a value instead of + // using an "out" parameter. The "out" parameter is useful for reusing memory allocated in SurfacePoint when + // using the public API, but can't easily be used from Script Canvas. + SurfaceData::SurfacePoint BehaviorContextGetSurfacePoint( + const AZ::Vector3& inPosition, + Sampler sampleFilter = Sampler::DEFAULT) const + { + SurfaceData::SurfacePoint result; + GetSurfacePoint(inPosition, result, sampleFilter); + return result; + } + SurfaceData::SurfacePoint BehaviorContextGetSurfacePointFromVector2( + const AZ::Vector2& inPosition, + Sampler sampleFilter = Sampler::DEFAULT) const + { + SurfaceData::SurfacePoint result; + GetSurfacePointFromVector2(inPosition, result, sampleFilter); + return result; + } }; using TerrainDataRequestBus = AZ::EBus; From 879012b1ae67714e028cf00454844bf552278c11 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:03:46 -0600 Subject: [PATCH 35/72] Added the --regset-file option for setreg file loading (#5768) The SettingsRegistryMergeUtils.cpp now supports specifying a path to a JSON Merge Patch formated settings registry file via the --regset-file option. The option supports specify an anchor key to merge the settings underneath that is separated from the filepath via "::" Ex. `--regset-file="Registry/custom.setreg::/Custom/Anchor"` An AZ::Console command of "sr_regset-file" has also been added to allow merging of a setting registry file as well. closes #5767 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/IO/Path/Path.h | 3 +- Code/Framework/AzCore/AzCore/IO/Path/Path.inl | 6 ++- .../Settings/SettingsRegistryConsoleUtils.cpp | 40 +++++++++++++++++-- .../Settings/SettingsRegistryConsoleUtils.h | 11 +++-- .../Settings/SettingsRegistryMergeUtils.cpp | 35 +++++++++++++--- .../SettingsRegistryMergeUtilsTests.cpp | 16 ++++++++ 6 files changed, 96 insertions(+), 15 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.h b/Code/Framework/AzCore/AzCore/IO/Path/Path.h index 355d9ddedb..094dee16f2 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.h +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.h @@ -78,7 +78,8 @@ namespace AZ::IO // native format observers //! Returns string_view stored within the PathView - constexpr AZStd::string_view Native() const noexcept; + constexpr const AZStd::string_view& Native() const noexcept; + constexpr AZStd::string_view& Native() noexcept; //! Conversion operator to retrieve string_view stored within the PathView constexpr explicit operator AZStd::string_view() const noexcept; diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl index 1d654c1502..5ac15fc728 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl @@ -101,7 +101,11 @@ namespace AZ::IO } // native format observers - constexpr auto PathView::Native() const noexcept -> AZStd::string_view + constexpr auto PathView::Native() const noexcept -> const AZStd::string_view& + { + return m_path; + } + constexpr auto PathView::Native() noexcept -> AZStd::string_view& { return m_path; } diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp index 7a8ab85ce3..e5f87f4e7f 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ namespace AZ::SettingsRegistryConsoleUtils combinedKeyValueCommand.c_str()); AZ::Debug::Trace::Output("SettingsRegistry", setOutput.c_str()); } - }; + } static void ConsoleRemoveSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs) { @@ -57,7 +58,7 @@ namespace AZ::SettingsRegistryConsoleUtils AZ::Debug::Trace::Output("SettingsRegistry", removeOutput.c_str()); } } - }; + } static void ConsoleDumpSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs) { @@ -88,13 +89,39 @@ namespace AZ::SettingsRegistryConsoleUtils } AZ::Debug::Trace::Output("SettingsRegistry", outputString.c_str()); - }; + } static void ConsoleDumpAllSettingsRegistryValues(SettingsRegistryInterface& settingsRegistry, [[maybe_unused]] const ConsoleCommandContainer& commandArgs) { ConsoleDumpSettingsRegistryValue(settingsRegistry, { "" }); - }; + } + + static void ConsoleMergeFileToSettingsRegistry(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs) + { + if (commandArgs.empty()) + { + AZ_Error("SettingsRegistryConsoleUtils", false, "Command %s requires a argument to locate json file to merge", + SettingsRegistryMergeFile); + return; + } + + auto commandArgumentsIter = commandArgs.begin(); + // Extract the JSON pointer path from the argument list + AZStd::string_view filePath{ *commandArgumentsIter++ }; + AZ::SettingsRegistryInterface::FixedValueString jsonAnchorPath; + AZ::StringFunc::Join(jsonAnchorPath, commandArgumentsIter, commandArgs.end(), ' '); + + const auto mergeFormat = AZ::IO::PathView(filePath).Extension() != ".setregpatch" ? AZ::SettingsRegistryInterface::Format::JsonMergePatch : AZ::SettingsRegistryInterface::Format::JsonPatch; + if (settingsRegistry.MergeSettingsFile(filePath, mergeFormat, jsonAnchorPath)) + { + const auto mergeFileOutput = AZ::SettingsRegistryInterface::FixedValueString::format( + R"(Merged json file "%*.s" anchored to json path "%s" into the global settings registry)" "\n", + AZ_STRING_ARG(filePath), jsonAnchorPath.c_str()); + AZ::Debug::Trace::Output("SettingsRegistry", mergeFileOutput.c_str()); + } + } + [[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole) { @@ -115,6 +142,11 @@ namespace AZ::SettingsRegistryConsoleUtils resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryDumpAll, R"(Dumps all values from the global settings registry)" "\n", ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleDumpAllSettingsRegistryValues); + resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryMergeFile, + R"(Merges File into the global settings registry)" "\n" + R"(@param file-path - path to JSON formatted file to merge)" "\n" + R"(@param anchor-path - JSON path to anchor merge operation. Defaults to "")" "\n", + ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleMergeFileToSettingsRegistry); return resultHandle; } diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h index ba0d552dde..1807a27604 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h @@ -14,15 +14,16 @@ namespace AZ::SettingsRegistryConsoleUtils { - //! Only 4 console command are registered for the settings registry - //! "regset", "regremove", "regdump", "regdumpall" + //! The following console command are registered for the settings registry + //! "regset", "regremove", "regdump", "regdumpall", "regset-file" //! The value should be increased if more commands are needed - inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 4; + inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 5; inline constexpr const char* SettingsRegistrySet = "sr_regset"; inline constexpr const char* SettingsRegistryRemove = "sr_regremove"; inline constexpr const char* SettingsRegistryDump = "sr_regdump"; inline constexpr const char* SettingsRegistryDumpAll = "sr_regdumpall"; + inline constexpr const char* SettingsRegistryMergeFile = "sr_regset-file"; // RAII structure which owns the instances of the Settings Registry Console commands // registered with an AZ Console @@ -51,6 +52,10 @@ namespace AZ::SettingsRegistryConsoleUtils //! //! "sr_regdumpall" accepts 0 arguments and dumps the entire settings registry //! NOTE: this might result in a large amount of output to the console + //! + //! "sr_regset-file" accepts 1 or 2 arguments - [] + //! Merges the json formatted file into the settings registry underneath the root anchor "" + //! or if supplied [[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole); } diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index 975217a131..eed0112ad1 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -19,9 +19,6 @@ #include #include #include -#include -#include -#include #include #include @@ -983,7 +980,7 @@ namespace AZ::SettingsRegistryMergeUtils // code in the loop makes calls that mutates the `commandLine` instance, invalidating the iterators. Making a copy // ensures that the iterators remain valid. // NOLINTNEXTLINE(performance-unnecessary-value-param) - void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands) + void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeRegdumpCommands) { // Iterate over all the command line options in order to parse the --regset and --regremove // arguments in the order they were supplied @@ -998,18 +995,44 @@ namespace AZ::SettingsRegistryMergeUtils continue; } } + else if (commandArgument.m_option == "regset-file") + { + AZStd::string_view fileArg(commandArgument.m_value); + AZStd::string_view jsonAnchorPath; + // double colons is treated as the separator for an anchor path + // single colon cannot be used as it is used in Windows paths + if (auto anchorPathIndex = AZ::StringFunc::Find(fileArg, "::"); + anchorPathIndex != AZStd::string_view::npos) + { + jsonAnchorPath = fileArg.substr(anchorPathIndex + 2); + fileArg = fileArg.substr(0, anchorPathIndex); + } + if (!fileArg.empty()) + { + AZ::IO::PathView filePath(fileArg); + const auto mergeFormat = filePath.Extension() != ".setregpatch" + ? AZ::SettingsRegistryInterface::Format::JsonMergePatch + : AZ::SettingsRegistryInterface::Format::JsonPatch; + if (!registry.MergeSettingsFile(filePath.Native(), mergeFormat, jsonAnchorPath)) + { + AZ_Warning("SettingsRegistryMergeUtils", false, R"(Merging of file "%.*s" to the Settings Registry has failed at anchor "%.*s".)", + AZ_STRING_ARG(filePath.Native()), AZ_STRING_ARG(jsonAnchorPath)); + continue; + } + } + } else if (commandArgument.m_option == "regremove") { if (!registry.Remove(commandArgument.m_value)) { AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to remove value at JSON Pointer %s for --regremove.", - commandArgument.m_value.data()); + commandArgument.m_value.c_str()); continue; } } } - if (executeCommands) + if (executeRegdumpCommands) { constexpr bool prettifyOutput = true; const size_t regdumpSwitchValues = commandLine.GetNumSwitchValues("regdump"); diff --git a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp index 00a18f7682..485593a699 100644 --- a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp +++ b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryMergeUtilsTests.cpp @@ -539,6 +539,22 @@ tags=tools,renderer,metal)" EXPECT_STREQ("Bat", commandLine.GetMiscValue(2).c_str()); } + TEST_F(SettingsRegistryMergeUtilsCommandLineFixture, RegsetFileArgument_DoesNotMergeNUL) + { + AZStd::string regsetFile = AZ::IO::SystemFile::GetNullFilename(); + AZ::CommandLine commandLine; + commandLine.Parse({ "--regset-file", regsetFile }); + + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false); + + // Add a settings path to anchor loaded settings underneath + regsetFile = AZStd::string::format("%s::/AnchorPath/Of/Settings", AZ::IO::SystemFile::GetNullFilename()); + commandLine.Parse({ "--regset-file", regsetFile }); + + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false); + EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/AnchorPath/Of/Settings")); + } + using SettingsRegistryAncestorDescendantOrEqualPathFixture = SettingsRegistryMergeUtilsCommandLineFixture; TEST_F(SettingsRegistryAncestorDescendantOrEqualPathFixture, ValidateThatAncestorOrDescendantOrPathWithTheSameValue_Succeeds) From d600b1c9fd6659f79ef15fc3eba481b43b51f28c Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 11:10:00 -0800 Subject: [PATCH 36/72] Adding GetBool method to CmdLineArg Signed-off-by: Gene Walters --- Code/Legacy/CryCommon/ICmdLine.h | 8 ++++++++ Code/Legacy/CrySystem/CmdLineArg.cpp | 17 +++++++++++++++++ Code/Legacy/CrySystem/CmdLineArg.h | 1 + 3 files changed, 26 insertions(+) diff --git a/Code/Legacy/CryCommon/ICmdLine.h b/Code/Legacy/CryCommon/ICmdLine.h index 6071671b02..80561fd85c 100644 --- a/Code/Legacy/CryCommon/ICmdLine.h +++ b/Code/Legacy/CryCommon/ICmdLine.h @@ -71,6 +71,14 @@ public: // The value of the argument as integer number. virtual const int GetIValue() const = 0; // + + // Description: + // Retrieve the value of the argument. + // Arguments: + // cmdLineValue. The cmdline value will be filled out if a valid boolean is found. + // Return Value: + // Returns true if the cmdline arg is actually a boolean string matching "true" or "false"; otherwise return false. + virtual const bool GetBoolValue(bool& cmdLineValue) const = 0; }; // Command line interface diff --git a/Code/Legacy/CrySystem/CmdLineArg.cpp b/Code/Legacy/CrySystem/CmdLineArg.cpp index 79d23ddae7..554e734055 100644 --- a/Code/Legacy/CrySystem/CmdLineArg.cpp +++ b/Code/Legacy/CrySystem/CmdLineArg.cpp @@ -42,5 +42,22 @@ const int CCmdLineArg::GetIValue() const { return atoi(m_value.c_str()); } +const bool CCmdLineArg::GetBoolValue(bool& cmdLineValue) const +{ + AZStd::string lowercaseValue(m_value); + AZStd::to_lower(lowercaseValue.begin(), lowercaseValue.end()); + if (lowercaseValue == "true") + { + cmdLineValue = true; + return true; + } + if (lowercaseValue == "false") + { + cmdLineValue = false; + return true; + } + + return false; +} diff --git a/Code/Legacy/CrySystem/CmdLineArg.h b/Code/Legacy/CrySystem/CmdLineArg.h index 5e3a629e7c..66d56be132 100644 --- a/Code/Legacy/CrySystem/CmdLineArg.h +++ b/Code/Legacy/CrySystem/CmdLineArg.h @@ -30,6 +30,7 @@ public: const ECmdLineArgType GetType() const; const float GetFValue() const; const int GetIValue() const; + const bool GetBoolValue(bool& cmdLineValue) const; private: From 7c30adb66caee3be16b8d80a48e0576212e9949e Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:10:02 -0800 Subject: [PATCH 37/72] Removes _vs2019 from jenkins jobs and documentation (#5855) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../EditorPythonTestTools/README.txt | 4 +- .../ap_fixtures/ap_setup_fixture.py | 2 +- .../ap_fixtures/asset_processor_fixture.py | 2 +- .../Windows/ProjectManagerDefs_windows.cpp | 2 +- .../azpy/synthetic_env.py | 2 +- .../DccScriptingInterface/config.py | 2 +- .../Code/Tests/run_EMotionFX_tests.py | 94 ---------------- README.md | 4 +- Tools/LyTestTools/README.txt | 4 +- .../managers/abstract_resource_locator.py | 6 +- .../_internal/managers/workspace.py | 2 +- .../ly_remote_console/README.txt | 3 +- .../build/Platform/Android/build_config.json | 2 +- .../build/Platform/Windows/build_config.json | 102 +++++++++--------- .../Windows/package_build_config.json | 4 +- .../package/Platform/Windows/package_env.json | 2 +- scripts/o3de/README.txt | 2 +- 17 files changed, 72 insertions(+), 167 deletions(-) delete mode 100755 Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt index 642d7279a4..bd9740f60f 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt @@ -26,8 +26,8 @@ INSTALL It is recommended to set up these these tools with O3DE's CMake build commands. Assuming CMake is already setup on your operating system, below are some sample build commands: cd /path/to/od3e/ - mkdir windows_vs2019 - cd windows_vs2019 + mkdir windows + cd windows cmake .. -G "Visual Studio 16 2019" -DLY_PROJECTS=AutomatedTesting To manually install the project in development mode using your own installed Python interpreter: diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py index 244ecfb516..c5b02e4f28 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py @@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT -A fixture for Setting Up Asset Processor Batch workspace for tests in lmbr_test +A fixture for Setting Up Asset Processor Batch workspace for tests """ # Import builtin libraries diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py index eea6cb9224..674862443e 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py @@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT -A fixture for using the Asset Processor in lmbr_test, this will stop the asset processor after every test via +A fixture for using the Asset Processor, this will stop the asset processor after every test via the teardown. Using the fixture at class level will stop the asset processor after the suite completes. Using the fixture at test level will stop asset processor after the test completes. Calling this fixture as a test argument will still run the teardown to stop the Asset Processor. """ diff --git a/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp b/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp index 6b58458ccd..9fa9321cce 100644 --- a/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp +++ b/Code/Tools/ProjectManager/Platform/Windows/ProjectManagerDefs_windows.cpp @@ -9,7 +9,7 @@ namespace O3DE::ProjectManager { - const QString ProjectBuildPathPostfix = ProjectBuildDirectoryName + "/windows_vs2019"; + const QString ProjectBuildPathPostfix = ProjectBuildDirectoryName + "/windows"; const QString GetPythonScriptPath = "python/get_python.bat"; } // namespace O3DE::ProjectManager diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py index 33ac6c6814..2d0685b67d 100644 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/azpy/synthetic_env.py @@ -508,7 +508,7 @@ def init_ly_pyside(env_dict=_SYNTH_ENV_DICT): site.addsitedir(str(QTFORPYTHON_PATH)) O3DE_BIN_PATH = Path.joinpath(O3DE_DEV, - 'windows_vs2019', + 'windows', 'bin', 'profile').resolve() os.environ["DYNACONF_O3DE_BIN_PATH"] = str(O3DE_BIN_PATH) diff --git a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py index 5578bcd577..a9cf5e8ee5 100755 --- a/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py +++ b/Gems/AtomLyIntegration/TechnicalArt/DccScriptingInterface/config.py @@ -532,7 +532,7 @@ if __name__ == '__main__': parser.add_argument('-bf', '--build-folder', type=str, required=False, - help='The name (tag) of the o3de build folder, example build or windows_vs2019.') + help='The name (tag) of the o3de build folder, example build or windows.') parser.add_argument('-pp', '--project-path', type=pathlib.Path, required=False, diff --git a/Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py b/Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py deleted file mode 100755 index e3b930e43b..0000000000 --- a/Gems/EMotionFX/Code/Tests/run_EMotionFX_tests.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -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 - -python run_EMotionFX_tests.py --config --vsVersion - -Example: -python run_EMotionFX_tests.py --config profile --vsVersion vs2017 -python run_EMotionFX_tests.py --config debug --vsVersion vs2019 - - -Requirements: - -- Provide a single script that executes all your team's automated BAT/Regression tests - -- The script should run the tests successfully if killed in the middle and restarted - -- Provide any documentation needed along with the script so that other feature teams wanting to execute your tests can execute them locally - -- The documentation should also cover where the test results are reported and how to find failing tests and their logs - - -""" - -import argparse -import os -import subprocess - - -#Setup Parser -def parser_setup(): - parser = argparse.ArgumentParser(description='Sets up for and runs the specified EMotionFX tests') - - # Configuration - parser.add_argument('--config', choices=['profile','debug'] , help='The Conrfiguration you have pre-build and want to run the tests on. Options[profile,debug]') - - #Visual Studio Version - parser.add_argument('--vsVersion', choices=['vs2017','vs2019'], help='The version of Visual Studio you used to build your branch. Options[vs2017, vs2019]') - - - - return parser - - - -#Main Program -def main(): - # Set up CLI arguments for CLI argument parser - parser = parser_setup() - - # Capture arguments and their values - args = parser.parse_args() - - - # Change directory to branch root - dev_path = os.path.join(os.path.dirname(__file__), '..', '..','..','..') - os.chdir(dev_path) - dirpath = os.getcwd() - - - vsVersion = args.vsVersion - config = args.config - - if vsVersion == 'vs2017': - if config == 'profile': - #lmbr_test.cmd scan --dir Bin64vc141.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc141.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - elif config == 'debug': - #lmbr_test.cmd scan --dir Bin64vc141.Debug.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc141.Debug.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - else: - print('INVALID ARGUMENT(s)... Ending') - elif vsVersion == 'vs2019': - if config == 'profile': - #lmbr_test.cmd scan --dir Bin64vc142.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc142.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - elif config == 'debug': - #lmbr_test.cmd scan --dir Bin64vc142.Debug.Test --only Gem\.EMotionFX\..*\.dll - subprocess.run('lmbr_test.cmd scan --dir Bin64vc141.Debug.Test --only Gem\.EMotionFX\..*\.dll', check=True) - - else: - print('INVALID ARGUMENT(s)... Ending') - else: - print('INVALID ARGUMENT(s)... Ending') - - - -if __name__ == '__main__': - main() diff --git a/README.md b/README.md index 11fec028bc..063a59de74 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ To set up a project-centric source engine, complete the following steps. For oth Example: ``` - cmake -B C:\o3de\build\windows_vs2019 -S C:\o3de -G "Visual Studio 16" -DLY_3RDPARTY_PATH=C:\o3de-packages + cmake -B C:\o3de\build\windows -S C:\o3de -G "Visual Studio 16" -DLY_3RDPARTY_PATH=C:\o3de-packages ``` > Note: Do not use trailing slashes for the <3rdParty package path>. @@ -107,7 +107,7 @@ For more details on the steps above, refer to [Setting up O3DE from GitHub](http Example: ``` - cmake -B C:\my-project\build\windows_vs2019 -S C:\my-project -G "Visual Studio 16" + cmake -B C:\my-project\build\windows -S C:\my-project -G "Visual Studio 16" ``` > Note: Do not use trailing slashes for the <3rdParty cache path>. diff --git a/Tools/LyTestTools/README.txt b/Tools/LyTestTools/README.txt index 61ad507dc4..4372bc5201 100644 --- a/Tools/LyTestTools/README.txt +++ b/Tools/LyTestTools/README.txt @@ -35,8 +35,8 @@ INSTALL It is recommended to set up these these tools with Lumberyard's CMake build commands. Assuming CMake is already setup on your operating system, below are some sample build commands: cd /path/to/lumberyard/dev/ - mkdir windows_vs2019 - cd windows_vs2019 + mkdir windows + cd windows cmake -E time cmake --build . --target ALL_BUILD --config profile To manually install the project in development mode using your own installed Python interpreter: diff --git a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py index 4ff71a5b31..d11980658d 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py @@ -277,7 +277,7 @@ class AbstractResourceLocator(object): def get_shader_compiler_path(self): """ Return path to shader compiler executable - ex. engine_root/dev/windows_vs2019/bin/profile/CrySCompileServer + ex. engine_root/dev/windows/bin/profile/CrySCompileServer :return: path to CrySCompileServer executable """ return os.path.join(self.build_directory(), 'CrySCompileServer') @@ -313,7 +313,7 @@ class AbstractResourceLocator(object): def shader_compiler_config_file(self): """ Return path to the Shader Compiler config file - ex. engine_root/dev/windows_vs2019/bin/profile/config.ini + ex. engine_root/dev/windows/bin/profile/config.ini :return: path to the Shader Compiler config file """ return os.path.join(self.build_directory(), 'config.ini') @@ -321,7 +321,7 @@ class AbstractResourceLocator(object): def shader_cache(self): """ Return path to the shader cache for the current build - ex. engine_root/dev/windows_vs2019/bin/profile/Cache + ex. engine_root/dev/windows/bin/profile/Cache :return: path to the shader cache for the current build """ return os.path.join(self.build_directory(), 'Cache') diff --git a/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py b/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py index ac412acf84..801729f008 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/managers/workspace.py @@ -119,7 +119,7 @@ class AbstractWorkspaceManager: def clear_bin(self): """ - Clears the relative Bin folder (i.e. engine_root/dev/windows_vs2019/bin/profile/) + Clears the relative Bin folder (i.e. engine_root/dev/windows/bin/profile/) :return: None """ if os.path.exists(self.paths.build_directory()): diff --git a/Tools/RemoteConsole/ly_remote_console/README.txt b/Tools/RemoteConsole/ly_remote_console/README.txt index 497179ac15..0c5d8c67af 100644 --- a/Tools/RemoteConsole/ly_remote_console/README.txt +++ b/Tools/RemoteConsole/ly_remote_console/README.txt @@ -22,8 +22,7 @@ installed on your system. INSTALL ----------- -It is recommended to set up these these tools with the lmbr_test tool Lumberyard's root directory: - lmbr_test pysetup install +Installation of these tools happen automatically when get_python and cmake is run. To manually install the project in development mode: python -m pip install -e . diff --git a/scripts/build/Platform/Android/build_config.json b/scripts/build/Platform/Android/build_config.json index dbdafcf97d..06fa1ffb5f 100644 --- a/scripts/build/Platform/Android/build_config.json +++ b/scripts/build/Platform/Android/build_config.json @@ -92,7 +92,7 @@ "COMMAND":"../Windows/build_asset_windows.cmd", "PARAMETERS": { "CONFIGURATION":"profile", - "OUTPUT_DIRECTORY":"build\\windows_vs2019", + "OUTPUT_DIRECTORY":"build\\windows", "CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS":"AutomatedTesting", "CMAKE_TARGET":"AssetProcessorBatch", diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index 6f1aaa1570..c591ca0eac 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -15,24 +15,24 @@ "validation" ] }, - "debug_vs2019_pipe": { + "debug_pipe": { "TAGS": [ "nightly-incremental", "nightly-clean" ], "steps": [ - "debug_vs2019", - "test_debug_vs2019" + "debug", + "test_debug" ] }, - "profile_vs2019_pipe": { + "profile_pipe": { "TAGS": [ "default" ], "steps": [ - "profile_vs2019", - "asset_profile_vs2019", - "test_cpu_profile_vs2019" + "profile", + "asset_profile", + "test_cpu_profile" ] }, "scrubbing": { @@ -79,40 +79,40 @@ "SCRIPT_PARAMETERS": "--platform 3rdParty --type 3rdParty_all" } }, - "test_impact_analysis_profile_vs2019": { + "test_impact_analysis_profile": { "TAGS": [ ], "COMMAND": "python_windows.cmd", "PARAMETERS": { - "OUTPUT_DIRECTORY": "build/windows_vs2019", + "OUTPUT_DIRECTORY": "build/windows", "CONFIGURATION": "profile", "SCRIPT_PATH": "scripts/build/TestImpactAnalysis/tiaf_driver.py", "SCRIPT_PARAMETERS": "--config=\"%OUTPUT_DIRECTORY%/bin/TestImpactFramework/profile/Persistent/tiaf.json\" --src-branch=%BRANCH_NAME% --dst-branch=%CHANGE_TARGET% --commit=%CHANGE_ID% --s3-bucket=%TEST_IMPACT_S3_BUCKET% --mars-index-prefix=jonawals --s3-top-level-dir=%REPOSITORY_NAME% --build-number=%BUILD_NUMBER% --suite=main --test-failure-policy=continue" } }, - "debug_vs2019": { + "debug": { "TAGS": [ "weekly-build-metrics" ], "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "debug", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "test_debug_vs2019": { + "test_debug": { "TAGS": [ "weekly-build-metrics" ], "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "debug", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", @@ -122,7 +122,7 @@ "TEST_RESULTS": "True" } }, - "profile_vs2019": { + "profile": { "TAGS": [ "daily-pipeline-metrics", "weekly-build-metrics" @@ -130,14 +130,14 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_TEST_IMPACT_INSTRUMENTATION_BIN=%TEST_IMPACT_WIN_BINARY%", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "profile_vs2019_nounity": { + "profile_nounity": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -146,14 +146,14 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=FALSE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "test_cpu_profile_vs2019": { + "test_cpu_profile": { "TAGS": [ "daily-pipeline-metrics", "weekly-build-metrics" @@ -161,7 +161,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", @@ -171,7 +171,7 @@ "TEST_RESULTS": "True" } }, - "test_gpu_profile_vs2019": { + "test_gpu_profile": { "TAGS":[ "nightly-incremental", "nightly-clean" @@ -182,7 +182,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main", @@ -193,7 +193,7 @@ "TEST_SCREENSHOTS": "True" } }, - "asset_profile_vs2019": { + "asset_profile": { "TAGS": [ "weekly-build-metrics", "nightly-incremental", @@ -202,7 +202,7 @@ "COMMAND": "build_asset_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "AssetProcessorBatch", @@ -212,18 +212,18 @@ "ASSET_PROCESSOR_PLATFORMS": "pc,server" } }, - "awsi_test_profile_vs2019_pipe": { + "awsi_test_profile_pipe": { "TAGS": [ "nightly-incremental", "nightly-clean" ], "steps": [ "awsi_deployment", - "awsi_test_profile_vs2019", + "awsi_test_profile", "awsi_destruction" ] }, - "awsi_test_profile_vs2019": { + "awsi_test_profile": { "TAGS": [ "weekly-build-metrics" ], @@ -233,7 +233,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_awsi", @@ -243,7 +243,7 @@ "TEST_RESULTS": "True" } }, - "periodic_test_profile_vs2019": { + "periodic_test_profile": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -252,7 +252,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "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", @@ -262,7 +262,7 @@ "TEST_RESULTS": "True" } }, - "sandbox_test_profile_vs2019": { + "sandbox_test_profile": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -274,7 +274,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_sandbox", @@ -284,7 +284,7 @@ "TEST_RESULTS": "True" } }, - "benchmark_test_profile_vs2019": { + "benchmark_test_profile": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -293,7 +293,7 @@ "COMMAND": "build_test_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "TEST_SUITE_benchmark", @@ -303,7 +303,7 @@ "TEST_RESULTS": "True" } }, - "release_vs2019": { + "release": { "TAGS": [ "default", "nightly-incremental", @@ -313,14 +313,14 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "release", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "monolithic_release_vs2019": { + "monolithic_release": { "TAGS": [ "nightly-incremental", "nightly-clean", @@ -329,25 +329,25 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "release", - "OUTPUT_DIRECTORY": "build\\mono_windows_vs2019", + "OUTPUT_DIRECTORY": "build\\mono_windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_MONOLITHIC_GAME=TRUE", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "install_profile_vs2019": { + "install_profile": { "TAGS": [], "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_DISABLE_TEST_MODULES=TRUE", "CMAKE_TARGET": "INSTALL", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "installer_vs2019": { + "installer": { "TAGS": [ "nightly-clean", "nightly-installer" @@ -358,7 +358,7 @@ "COMMAND": "build_installer_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_DISABLE_TEST_MODULES=TRUE -DLY_VERSION_ENGINE_NAME=o3de-sdk -DLY_INSTALLER_WIX_ROOT=\"!WIX! \"", "EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=TRUE -DLY_INSTALLER_DOWNLOAD_URL=!INSTALLER_DOWNLOAD_URL! -DLY_INSTALLER_LICENSE_URL=!INSTALLER_DOWNLOAD_URL!/license", "CMAKE_TARGET": "ALL_BUILD", @@ -366,7 +366,7 @@ "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "install_profile_vs2019_pipe": { + "install_profile_pipe": { "TAGS": [ "nightly-incremental", "nightly-clean" @@ -375,9 +375,9 @@ "PROJECT_REPOSITORY_NAME": "TestProject" }, "steps": [ - "install_profile_vs2019", + "install_profile", "project_generate", - "project_engineinstall_profile_vs2019" + "project_engineinstall_profile" ] }, "project_generate": { @@ -388,7 +388,7 @@ "SCRIPT_PARAMETERS": "create-project -pp %WORKSPACE%\\%PROJECT_REPOSITORY_NAME% --force" } }, - "project_enginesource_profile_vs2019": { + "project_enginesource_profile": { "TAGS": [ "project" ], @@ -398,13 +398,13 @@ "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=%WORKSPACE%/o3de/cmake", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "project_engineinstall_profile_vs2019": { + "project_engineinstall_profile": { "TAGS": [], "PIPELINE_ENV": { "EXECUTE_FROM_PROJECT": "1" @@ -413,19 +413,19 @@ "PARAMETERS": { "COMMAND_CWD": "%WORKSPACE%\\%PROJECT_REPOSITORY_NAME%", "CONFIGURATION": "profile", - "OUTPUT_DIRECTORY": "build\\windows_vs2019", + "OUTPUT_DIRECTORY": "build\\windows", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=%WORKSPACE%/o3de/install/cmake", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, - "project_engineinstall_profile_vs2019_pipe": { + "project_engineinstall_profile_pipe": { "TAGS": [ "project" ], "steps": [ - "install_profile_vs2019", - "project_engineinstall_profile_vs2019" + "install_profile", + "project_engineinstall_profile" ] }, "awsi_deployment": { diff --git a/scripts/build/Platform/Windows/package_build_config.json b/scripts/build/Platform/Windows/package_build_config.json index 5eb96f1e38..1a94fb802a 100644 --- a/scripts/build/Platform/Windows/package_build_config.json +++ b/scripts/build/Platform/Windows/package_build_config.json @@ -1,9 +1,9 @@ { - "profile_vs2019_atom": { + "profile_atom": { "COMMAND":"build_windows.cmd", "PARAMETERS": { "CONFIGURATION":"profile", - "OUTPUT_DIRECTORY":"windows_vs2019", + "OUTPUT_DIRECTORY":"windows", "CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", "CMAKE_LY_PROJECTS":"AtomTest;AtomSampleViewer", "CMAKE_TARGET":"ALL_BUILD", diff --git a/scripts/build/package/Platform/Windows/package_env.json b/scripts/build/package/Platform/Windows/package_env.json index 970361bacc..bfe526bc16 100644 --- a/scripts/build/package/Platform/Windows/package_env.json +++ b/scripts/build/package/Platform/Windows/package_env.json @@ -27,7 +27,7 @@ { "BUILD_CONFIG_FILENAME": "build_config.json", "PLATFORM": "Windows", - "TYPE": "profile_vs2019" + "TYPE": "profile" } ] } diff --git a/scripts/o3de/README.txt b/scripts/o3de/README.txt index ded52bb264..39817c2df7 100644 --- a/scripts/o3de/README.txt +++ b/scripts/o3de/README.txt @@ -23,7 +23,7 @@ INSTALL It is recommended to set up these these tools with O3DE's CMake build commands. Assuming CMake is already setup on your operating system, below are some sample build commands: cd /path/to/od3e/ - cmake -B windows_vs2019 -S . -G"Visual Studio 16" + cmake -B windows -S . -G"Visual Studio 16" To manually install the project in development mode using your own installed Python interpreter: cd /path/to/od3e/o3de From 6d0ba68b55378c8170c72b4f2630cc1fcc902ebc Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 11:12:07 -0800 Subject: [PATCH 38/72] Using new GetBool value when checking if we're an editor-server. Clean up MPEditorSystemComponent for unused #includes, and null-checking when piping server logs Signed-off-by: Gene Walters --- Code/Legacy/CrySystem/SystemInit.cpp | 5 ++--- .../Editor/MultiplayerEditorSystemComponent.cpp | 16 +++++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp index 6f550fcac6..70595e53c1 100644 --- a/Code/Legacy/CrySystem/SystemInit.cpp +++ b/Code/Legacy/CrySystem/SystemInit.cpp @@ -741,9 +741,8 @@ bool CSystem::Init(const SSystemInitParams& startupParams) bool suppressSystemOutput = true; if (const ICmdLineArg* isEditorServerArg = m_pCmdLine->FindArg(eCLAT_Pre, "editorsv_isDedicated")) { - AZ::CVarFixedString lowercaseValue(isEditorServerArg->GetValue()); - AZStd::to_lower(lowercaseValue.begin(), lowercaseValue.end()); - if (lowercaseValue == "true") + bool editorsv_isDedicated = false; + if (isEditorServerArg->GetBoolValue(editorsv_isDedicated) && editorsv_isDedicated) { suppressSystemOutput = false; } diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index fa855cf28c..259d544279 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -6,7 +6,6 @@ * */ -#include "AzFramework/Process/ProcessCommunicator.h" #include #include @@ -16,11 +15,8 @@ #include #include #include -#include -#include #include -#include #include #include #include @@ -425,7 +421,17 @@ namespace Multiplayer void MultiplayerEditorSystemComponent::OnTick(float, AZ::ScriptTimePoint) { - m_serverProcessTracePrinter->Pump(); + if (m_serverProcessTracePrinter) + { + m_serverProcessTracePrinter->Pump(); + } + else + { + AZ::TickBus::Handler::BusDisconnect(); + AZ_Warning( + "MultiplayerEditorSystemComponent", false, + "The server process trace printer is NULL so we won't be able to pipe server logs to the editor. Please update the code to call AZ::TickBus::Handler::BusDisconnect whenever the editor-server is terminated.") + } } } From f05b63bcbaab605e07adad8ce66077ec79db141d Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:18:41 -0600 Subject: [PATCH 39/72] Enabling only optimized test runners for Editor/DynVeg/GradSignal (#5873) Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../Gem/PythonTests/editor/CMakeLists.txt | 54 ------------------- .../editor/TestSuite_Main_Optimized.py | 1 - .../PythonTests/largeworlds/CMakeLists.txt | 33 +----------- .../dyn_veg/TestSuite_Main_Optimized.py | 1 - 4 files changed, 2 insertions(+), 87 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt index bf42579970..1fc71da972 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt @@ -7,60 +7,6 @@ # if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED) - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Main - TEST_SUITE main - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py - PYTEST_MARKS "not REQUIRES_gpu" - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Main_GPU - TEST_SUITE main - TEST_SERIAL - TEST_REQUIRES gpu - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py - PYTEST_MARKS "REQUIRES_gpu" - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Periodic - TEST_SUITE periodic - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) - - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Sandbox - TEST_SUITE sandbox - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) ly_add_pytest( NAME AutomatedTesting::EditorTests_Main_Optimized diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py index ccc4ee9737..d87fd8625b 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py @@ -49,7 +49,6 @@ class TestAutomationNoAutoTestMode(EditorTestSuite): from .EditorScripts import AssetPicker_UI_UX as test_module -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt index 98801b49d6..ba607ede32 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt @@ -11,24 +11,10 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ ## DynVeg ## ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationTests_Main + NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized TEST_SERIAL TEST_SUITE main - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main.py - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.GameLauncher - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic.py + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -37,7 +23,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ COMPONENT LargeWorlds ) - ly_add_pytest( NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized TEST_SERIAL @@ -52,20 +37,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ LargeWorlds ) - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized - TEST_SERIAL - TEST_SUITE main - PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - AutomatedTesting.GameLauncher - COMPONENT - LargeWorlds - ) - ## LandscapeCanvas ## ly_add_pytest( diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index ed23af51ad..d83f88cad2 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -12,7 +12,6 @@ import ly_test_tools.environment.file_system as file_system from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) From b63064f604a5a2f66a6de8e7b7cc910012b694cb Mon Sep 17 00:00:00 2001 From: AMZN-stankowi <4838196+AMZN-stankowi@users.noreply.github.com> Date: Tue, 30 Nov 2021 11:34:54 -0800 Subject: [PATCH 40/72] Automated test for bundle mode that creates and mounts a bundle with a level.pak file in it, and verifies that occurs. (#5805) This is a regression test for bundle mode causing the editor to crash if you mount a bundle containing a level.pak file. Signed-off-by: AMZN-stankowi <4838196+AMZN-stankowi@users.noreply.github.com> --- .../asset_processor_tests/CMakeLists.txt | 13 +++ .../bundle_mode_in_editor_tests.py | 20 ++++ .../bundle_mode_tests.py | 93 +++++++++++++++++++ .../ly_test_tools/launchers/platforms/base.py | 2 +- 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py create mode 100644 AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt index 5a5809595e..e37a5ed99b 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt @@ -103,6 +103,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AssetBundlerBatch ) + ly_add_pytest( + NAME AssetPipelineTests.BundleMode + PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py + EXCLUDE_TEST_RUN_TARGET_FROM_IDE + TEST_SERIAL + TEST_SUITE periodic + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + AZ::AssetBundlerBatch + Legacy::Editor + AutomatedTesting.Assets + ) + ly_add_pytest( NAME AssetPipelineTests.AssetBuilder PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py new file mode 100644 index 0000000000..33a55d6601 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py @@ -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 +""" +import azlmbr.bus +import azlmbr.editor +import azlmbr.legacy.general +import sys + +# Print out the passed in bundle_path, so the outer test can verify this was sent in correctly +bundle_path = sys.argv[1] +print('Bundle mode test running with path {}'.format(sys.argv[1])) + +# Turn on bundle mode. This will trigger some printouts that the outer test logic will validate. +azlmbr.legacy.general.set_cvar_integer("sys_report_files_not_found_in_paks", 1) +azlmbr.legacy.general.run_console(f"loadbundles {bundle_path}") + +azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt') diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py new file mode 100644 index 0000000000..af92bb1773 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py @@ -0,0 +1,93 @@ +""" +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 os +import pytest +import logging +import sys +import time +pytest.importorskip('ly_test_tools') + +import ly_test_tools.environment.file_system as fs +import ly_test_tools.environment.waiter as waiter +import ly_test_tools.log.log_monitor + +from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor +from ..ap_fixtures.bundler_batch_setup_fixture import bundler_batch_setup_fixture as bundler_batch_helper +from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout + +@pytest.mark.SUITE_periodic +@pytest.mark.parametrize('launcher_platform', ['windows_editor']) +@pytest.mark.parametrize('project', ['AutomatedTesting']) +@pytest.mark.parametrize('level', ['auto_test']) +class TestBundleMode(object): + def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform, + asset_processor, workspace, bundler_batch_helper): + level_pak = os.path.join("levels", level, "level.pak") + + bundles_folder = os.path.join(workspace.paths.project(), "Bundles") + bundle_request_path = os.path.join(bundles_folder, "bundle.pak") + bundle_result_path = os.path.join(bundles_folder, + bundler_batch_helper.platform_file_name( + "bundle.pak", workspace.asset_processor_platform)) + + # Create target 'Bundles' folder if it doesn't exist + if not os.path.exists(bundles_folder): + os.mkdir(bundles_folder) + # Delete target bundle file if it already exists + if os.path.exists(bundle_result_path): + fs.delete([bundle_result_path], True, False) + + # Make asset list file to use in the bundle + bundler_batch_helper.call_assetLists( + addSeed=level_pak, + assetListFile=bundler_batch_helper["asset_info_file_request"], + ) + + # Make bundle in /Bundles + bundler_batch_helper.call_bundles( + assetListFile=bundler_batch_helper["asset_info_file_result"], + outputBundlePath=bundle_request_path, + maxSize="2048", + ) + + # Ensure the bundle was created + assert os.path.exists(bundle_result_path), f"Bundle was not created at location: {bundle_result_path}" + + # The editor flips the slash direction in some of the printouts + bundle_result_path_editor_separator = bundle_result_path.replace('\\', '/') + + expected_lines = [ + # A beginning of test printout can help debug where failures occur, if this line is missing + # then the Editor didn't launch, didn't run the Python test, or didn't pass in the right parameter + f'Bundle mode test running with path {bundles_folder}', + # These printouts happen in response to the loadbundles call, and verify this bundle is actually loaded + f"[CONSOLE] Executing console command 'loadbundles {bundles_folder}'", + f'(BundlingSystem) - Loading bundles from {bundles_folder} of type .pak', + f'(Archive) - Opening archive file {bundle_result_path_editor_separator}', + ] + unexpected_lines = [] + + timeout = 180 + halt_on_unexpected = False + test_directory = os.path.join(os.path.dirname(__file__)) + test_file = os.path.join(test_directory, 'bundle_mode_in_editor_tests.py') + editor.args.extend(['-NullRenderer', '-rhi=Null', "--skipWelcomeScreenDialog", + "--autotest_mode", "--runpythontest", test_file, "--runpythonargs", bundles_folder]) + + with editor.start(launch_ap=True): + editor_log_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log') + log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editor_log_file) + waiter.wait_for( + lambda: editor.is_alive(), + timeout, + exc=("Log file '{}' was never opened by another process.".format(editor_log_file)), + interval=1) + log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout) + + # Delete the bundle created and used in this test + fs.delete([bundle_result_path], True, False) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py index d32be10562..c9458899b4 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py @@ -91,7 +91,7 @@ class Launcher(object): open(os.path.join(self.workspace.paths.project_log(), artifact), 'w').close() # clear it log.info(f"Clearing pre-existing artifact {artifact} from calling Launcher.setup()") except PermissionError: - log.warn(f'Unable to remove artifact: {artifact}, skipping.') + log.warning(f'Unable to remove artifact: {artifact}, skipping.') pass # In case this is the first run, we will create default logs to prevent the logmonitor from not finding the file From 8afd47950c788dfe5f6e317f3265fcef3a0e1c15 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 12:01:04 -0800 Subject: [PATCH 41/72] Removing an extra new-line I added by accident Signed-off-by: Gene Walters --- .../Code/Source/Editor/MultiplayerEditorSystemComponent.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 259d544279..ec783808a2 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -6,7 +6,6 @@ * */ - #include #include #include From b3bf02a4d5e03f11b4bec5417d2c8c606fff7475 Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:13:42 -0800 Subject: [PATCH 42/72] Adds Warning Dialog When Following an External Link in Project Manager (#6003) Signed-off-by: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> --- .../Resources/ProjectManager.qss | 10 +- .../Source/ExternalLinkDialog.cpp | 98 +++++++++++++++++++ .../Source/ExternalLinkDialog.h | 28 ++++++ .../Source/GemCatalog/GemUninstallDialog.cpp | 2 +- .../Source/GemCatalog/GemUpdateDialog.cpp | 2 +- .../ProjectManager/Source/LinkWidget.cpp | 29 +++++- .../Source/ProjectManagerSettings.cpp | 7 +- .../Source/ProjectManagerSettings.h | 1 + .../project_manager_files.cmake | 2 + 9 files changed, 170 insertions(+), 9 deletions(-) create mode 100644 Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp create mode 100644 Code/Tools/ProjectManager/Source/ExternalLinkDialog.h diff --git a/Code/Tools/ProjectManager/Resources/ProjectManager.qss b/Code/Tools/ProjectManager/Resources/ProjectManager.qss index 426f409581..1fc808b72c 100644 --- a/Code/Tools/ProjectManager/Resources/ProjectManager.qss +++ b/Code/Tools/ProjectManager/Resources/ProjectManager.qss @@ -232,6 +232,11 @@ QTabBar::tab:focus { stop: 0 #555555, stop: 1.0 #777777); } +#dialogSubTitle { + font-size:14px; + font-weight:600; +} + #horizontalSeparatingLine { color: #666666; } @@ -604,11 +609,6 @@ QProgressBar::chunk { stop: 0 #951D1F, stop: 1.0 #C92724); } -#gemCatalogDialogSubTitle { - font-size:14px; - font-weight:600; -} - /************** Filter Tag widget **************/ #FilterTagWidgetTextLabel { diff --git a/Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp new file mode 100644 index 0000000000..122a5cbf5a --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.cpp @@ -0,0 +1,98 @@ +/* + * 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 + +namespace O3DE::ProjectManager +{ + ExternalLinkDialog::ExternalLinkDialog(const QUrl& url, QWidget* parent) + : QDialog(parent) + { + setWindowTitle(tr("Leaving O3DE")); + setObjectName("ExternalLinkDialog"); + setAttribute(Qt::WA_DeleteOnClose); + setModal(true); + + QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setMargin(30); + hLayout->setAlignment(Qt::AlignTop); + setLayout(hLayout); + + QVBoxLayout* warningLayout = new QVBoxLayout(); + warningLayout->setMargin(0); + warningLayout->setAlignment(Qt::AlignTop); + hLayout->addLayout(warningLayout); + + QLabel* warningIcon = new QLabel(this); + warningIcon->setPixmap(QIcon(":/Warning.svg").pixmap(32, 32)); + warningLayout->addWidget(warningIcon); + + warningLayout->addStretch(); + + QVBoxLayout* layout = new QVBoxLayout(); + layout->setMargin(0); + layout->setAlignment(Qt::AlignTop); + hLayout->addLayout(layout); + + // Body + QLabel* subTitleLabel = new QLabel(tr("You are about to leave O3DE Project Manager to visit an external link.")); + subTitleLabel->setObjectName("dialogSubTitle"); + layout->addWidget(subTitleLabel); + + layout->addSpacing(10); + + QLabel* bodyLabel = new QLabel(tr("If you trust this source, you can proceed to this link, or click \"Cancel\" to return.")); + layout->addWidget(bodyLabel); + + // Don't actually set linkUrl we are just using LinkLabel superficially here + LinkLabel* linkLabel = new LinkLabel(url.toString(), {}, 12); + layout->addWidget(linkLabel); + + layout->addSpacing(40); + + QCheckBox* skipDialogCheckbox = new QCheckBox(tr("Do not show this again")); + layout->addWidget(skipDialogCheckbox); + connect(skipDialogCheckbox, &QCheckBox::stateChanged, this, &ExternalLinkDialog::SetSkipDialogSetting); + + // Buttons + QDialogButtonBox* dialogButtons = new QDialogButtonBox(); + dialogButtons->setObjectName("footer"); + layout->addWidget(dialogButtons); + + QPushButton* cancelButton = dialogButtons->addButton(tr("Cancel"), QDialogButtonBox::RejectRole); + cancelButton->setProperty("secondary", true); + QPushButton* acceptButton = dialogButtons->addButton(tr("Proceed"), QDialogButtonBox::ApplyRole); + + connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject); + connect(acceptButton, &QPushButton::clicked, this, &QDialog::accept); + } + + void ExternalLinkDialog::SetSkipDialogSetting(bool state) + { + auto settingsRegistry = AZ::SettingsRegistry::Get(); + if (settingsRegistry) + { + QString settingsKey = GetExternalLinkWarningKey(); + settingsRegistry->Set(settingsKey.toStdString().c_str(), state); + SaveProjectManagerSettings(); + } + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ExternalLinkDialog.h b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.h new file mode 100644 index 0000000000..45d391e64e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/ExternalLinkDialog.h @@ -0,0 +1,28 @@ +/* + * 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 + +#if !defined(Q_MOC_RUN) +#include +#endif + +namespace O3DE::ProjectManager +{ + class ExternalLinkDialog + : public QDialog + { + Q_OBJECT // AUTOMOC + public: + explicit ExternalLinkDialog(const QUrl& url, QWidget* parent = nullptr); + ~ExternalLinkDialog() = default; + + private slots: + void SetSkipDialogSetting(bool state); + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp index 1408e29b6d..679d9c576f 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemUninstallDialog.cpp @@ -31,7 +31,7 @@ namespace O3DE::ProjectManager // Body QLabel* subTitleLabel = new QLabel(tr("Are you sure you want to uninstall %1?").arg(gemName)); - subTitleLabel->setObjectName("gemCatalogDialogSubTitle"); + subTitleLabel->setObjectName("dialogSubTitle"); layout->addWidget(subTitleLabel); layout->addSpacing(10); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp index 82d205aab5..d973dd3749 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemUpdateDialog.cpp @@ -32,7 +32,7 @@ namespace O3DE::ProjectManager // Body QLabel* subTitleLabel = new QLabel(tr("%1 to the latest version of %2?").arg( updateAvaliable ? tr("Update") : tr("Force update"), gemName)); - subTitleLabel->setObjectName("gemCatalogDialogSubTitle"); + subTitleLabel->setObjectName("dialogSubTitle"); layout->addWidget(subTitleLabel); layout->addSpacing(10); diff --git a/Code/Tools/ProjectManager/Source/LinkWidget.cpp b/Code/Tools/ProjectManager/Source/LinkWidget.cpp index 9c8c78ed37..f25e38db67 100644 --- a/Code/Tools/ProjectManager/Source/LinkWidget.cpp +++ b/Code/Tools/ProjectManager/Source/LinkWidget.cpp @@ -7,6 +7,11 @@ */ #include +#include +#include + +#include + #include #include #include @@ -26,7 +31,29 @@ namespace O3DE::ProjectManager { if (m_url.isValid()) { - QDesktopServices::openUrl(m_url); + // Check if user request not to be shown external link warning dialog + bool skipDialog = false; + auto settingsRegistry = AZ::SettingsRegistry::Get(); + + if (settingsRegistry) + { + QString settingsKey = GetExternalLinkWarningKey(); + settingsRegistry->Get(skipDialog, settingsKey.toStdString().c_str()); + } + + if (!skipDialog) + { + // Style does not apply if LinkLabel is parent so use parentWidget as parent instead + ExternalLinkDialog* linkDialog = new ExternalLinkDialog(m_url.toString(), parentWidget()); + if (linkDialog->exec() == QDialog::Accepted) + { + QDesktopServices::openUrl(m_url); + } + } + else + { + QDesktopServices::openUrl(m_url); + } } emit clicked(); diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp index 3049a6d70c..66480aab3e 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.cpp @@ -6,7 +6,7 @@ * */ -#include "ProjectManagerSettings.h" +#include #include #include @@ -51,4 +51,9 @@ namespace O3DE::ProjectManager { return QString("%1/Projects/%2/BuiltSuccessfully").arg(ProjectManagerKeyPrefix).arg(projectName); } + + QString GetExternalLinkWarningKey() + { + return QString("%1/SkipExternalLinkWarning").arg(ProjectManagerKeyPrefix); + } } diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h index 3454909062..93cfbc5ceb 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h +++ b/Code/Tools/ProjectManager/Source/ProjectManagerSettings.h @@ -18,4 +18,5 @@ namespace O3DE::ProjectManager void SaveProjectManagerSettings(); QString GetProjectBuiltSuccessfullyKey(const QString& projectName); + QString GetExternalLinkWarningKey(); } diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index 43c11edacc..468e8dcbc5 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -78,6 +78,8 @@ set(FILES Source/TagWidget.cpp Source/TemplateButtonWidget.h Source/TemplateButtonWidget.cpp + Source/ExternalLinkDialog.h + Source/ExternalLinkDialog.cpp Source/GemCatalog/GemCatalogHeaderWidget.h Source/GemCatalog/GemCatalogHeaderWidget.cpp Source/GemCatalog/GemCatalogScreen.h From b7f051fb9aea28ed973eab3fdd9a60f18d2d4581 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:44:20 -0600 Subject: [PATCH 43/72] Procedural Prefabs - Add mesh modifier support (#5894) * Clean up error output Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add mesh modifiers to scene_data.py Add example usage of modifiers to scene_mesh_to_prefab.py Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add type hints, cleanup dict creation, fix variable naming Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add documentation Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Rename DefaultOrValue to __default_or_value Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../Editor/Scripts/scene_mesh_to_prefab.py | 14 +- .../Editor/Scripts/scene_api/scene_data.py | 174 ++++++++++++++++-- 2 files changed, 164 insertions(+), 24 deletions(-) diff --git a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py index e832b1f82b..7b9349e270 100644 --- a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py +++ b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: Apache-2.0 OR MIT # # -import os, traceback, binascii, sys, json, pathlib +import os, traceback, binascii, sys, json, pathlib, logging import azlmbr.math import azlmbr.bus @@ -15,9 +15,9 @@ import azlmbr.bus def log_exception_traceback(): - exc_type, exc_value, exc_tb = sys.exc_info() - data = traceback.format_exception(exc_type, exc_value, exc_tb) - print(str(data)) + data = traceback.format_exc() + logger = logging.getLogger('python') + logger.error(data) def get_mesh_node_names(sceneGraph): import azlmbr.scene as sceneApi @@ -114,12 +114,18 @@ def update_manifest(scene): mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, source_filename_only + mesh_path)) + '}' # Set our current node as the only node that is included in this MeshGroup scene_manifest.mesh_group_select_node(mesh_group, mesh_path) + scene_manifest.mesh_group_add_comment(mesh_group, "Hello World") # Explicitly remove all other nodes to prevent implicit inclusions for node in all_node_paths: if node != mesh_path: scene_manifest.mesh_group_unselect_node(mesh_group, node) + scene_manifest.mesh_group_add_cloth_rule(mesh_group, mesh_path, "Col0", 1, "Col0", 2, "Col0", 2, 3) + scene_manifest.mesh_group_add_advanced_mesh_rule(mesh_group, True, False, True, "Col0") + scene_manifest.mesh_group_add_skin_rule(mesh_group, 3, 0.002) + scene_manifest.mesh_group_add_tangent_rule(mesh_group, 1, 0) + # Create an editor entity entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name) # Add an EditorMeshComponent to the entity diff --git a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py index 2578efeae2..d105ecdb43 100755 --- a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py +++ b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py @@ -95,7 +95,7 @@ class SceneManifest(): def __init__(self): self.manifest = {'values': []} - def add_mesh_group(self, name) -> dict: + def add_mesh_group(self, name: str) -> dict: meshGroup = {} meshGroup['$type'] = '{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup' meshGroup['name'] = name @@ -104,7 +104,7 @@ class SceneManifest(): self.manifest['values'].append(meshGroup) return meshGroup - def add_prefab_group(self, name, id, json) -> dict: + def add_prefab_group(self, name: str, id: str, json: dict) -> dict: prefabGroup = {} prefabGroup['$type'] = '{99FE3C6F-5B55-4D8B-8013-2708010EC715} PrefabGroup' prefabGroup['name'] = name @@ -113,30 +113,164 @@ class SceneManifest(): self.manifest['values'].append(prefabGroup) return prefabGroup - def mesh_group_select_node(self, meshGroup, nodeName): - meshGroup['nodeSelectionList']['selectedNodes'].append(nodeName) + def mesh_group_select_node(self, mesh_group: dict, node_name: str) -> None: + mesh_group['nodeSelectionList']['selectedNodes'].append(node_name) - def mesh_group_unselect_node(self, meshGroup, nodeName): - meshGroup['nodeSelectionList']['unselectedNodes'].append(nodeName) + def mesh_group_unselect_node(self, mesh_group: dict, node_name: str) -> None: + mesh_group['nodeSelectionList']['unselectedNodes'].append(node_name) - def mesh_group_add_advanced_coordinate_system(self, meshGroup, originNodeName, translation, rotation, scale): - originRule = {} - originRule['$type'] = 'CoordinateSystemRule' - originRule['useAdvancedData'] = True - originRule['originNodeName'] = '' if originNodeName is None else originNodeName + def mesh_group_add_advanced_coordinate_system(self, mesh_group: dict, origin_node_name: str, translation: object, + rotation: object, scale: float) -> None: + origin_rule = { + '$type': 'CoordinateSystemRule', + 'useAdvancedData': True, + 'originNodeName': '' if origin_node_name is None else origin_node_name + } if translation is not None: - originRule['translation'] = translation + origin_rule['translation'] = translation if rotation is not None: - originRule['rotation'] = rotation + origin_rule['rotation'] = rotation if scale != 1.0: - originRule['scale'] = scale - meshGroup['rules']['rules'].append(originRule) + origin_rule['scale'] = scale + mesh_group['rules']['rules'].append(origin_rule) - def mesh_group_add_comment(self, meshGroup, comment): - commentRule = {} - commentRule['$type'] = 'CommentRule' - commentRule['comment'] = comment - meshGroup['rules']['rules'].append(commentRule) + def mesh_group_add_comment(self, mesh_group: dict, comment: str) -> None: + commentRule = { + '$type': 'CommentRule', + 'comment': comment + } + mesh_group['rules']['rules'].append(commentRule) + + def __default_or_value(self, val, default): + return default if val is None else val + + def mesh_group_add_cloth_rule(self, mesh_group: dict, cloth_node_name: str, + inverse_masses_stream_name: str, inverse_masses_channel: int, + motion_constraints_stream_name: str, motion_constraints_channel: int, + backstop_stream_name: str, backstop_offset_channel: int, + backstop_radius_channel: int) -> None: + """ + Adds a Cloth rule. 0 = Red, 1 = Green, 2 = Blue, 3 = Alpha + :param mesh_group: Mesh Group to add the cloth rule to + :param cloth_node_name: Name of the node that the rule applies to + :param inverse_masses_stream_name: Name of the color stream to use for inverse masses + :param inverse_masses_channel: Color channel (index) for inverse masses + :param motion_constraints_stream_name: Name of the color stream to use for motion constraints + :param motion_constraints_channel: Color channel (index) for motion constraints + :param backstop_stream_name: Name of the color stream to use for backstop + :param backstop_offset_channel: Color channel (index) for backstop offset value + :param backstop_radius_channel: Color chnanel (index) for backstop radius value + """ + cloth_rule = { + '$type': 'ClothRule', + 'meshNodeName': cloth_node_name, + 'inverseMassesStreamName': self.__default_or_value(inverse_masses_stream_name, 'Default: 1.0') + } + + if inverse_masses_channel is not None: + cloth_rule['inverseMassesChannel'] = inverse_masses_channel + cloth_rule['motionConstraintsStreamName'] = self.__default_or_value(motion_constraints_stream_name, 'Default: 1.0') + if motion_constraints_channel is not None: + cloth_rule['motionConstraintsChannel'] = motion_constraints_channel + cloth_rule['backstopStreamName'] = self.__default_or_value(backstop_stream_name, 'None') + if backstop_offset_channel is not None: + cloth_rule['backstopOffsetChannel'] = backstop_offset_channel + if backstop_radius_channel is not None: + cloth_rule['backstopRadiusChannel'] = backstop_radius_channel + mesh_group['rules']['rules'].append(cloth_rule) + + def mesh_group_add_lod_rule(self, mesh_group: dict) -> dict: + """ + Adds an LOD rule + :param mesh_group: Mesh Group to add the rule to + :return: LOD rule + """ + lod_rule = { + '$type': '{6E796AC8-1484-4909-860A-6D3F22A7346F} LodRule', + 'nodeSelectionList': [] + } + + mesh_group['rules']['rules'].append(lod_rule) + return lod_rule + + def lod_rule_add_lod(self, lod_rule: dict) -> dict: + """ + Adds an LOD level to the LOD rule. Nodes are added in order. The first node added represents LOD1, 2nd LOD2, etc + :param lod_rule: LOD rule to add the LOD level to + :return: LOD level + """ + lod = {'selectedNodes': [], 'unselectedNodes': []} + lod_rule['nodeSelectionList'].append(lod) + return lod + + def lod_select_node(self, lod: dict, selected_node: str) -> None: + """ + Adds a node as a selected node + :param lod: LOD level to add the node to + :param selected_node: Path of the node + """ + lod['selectedNodes'].append(selected_node) + + def lod_unselect_node(self, lod: dict, unselected_node: str) -> None: + """ + Adds a node as an unselected node + :param lod: LOD rule to add the node to + :param unselected_node: Path of the node + """ + lod['unselectedNodes'].append(unselected_node) + + def mesh_group_add_advanced_mesh_rule(self, mesh_group: dict, use_32bit_vertices: bool, merge_meshes: bool, + use_custom_normals: bool, + vertex_color_stream: str) -> None: + """ + Adds an Advanced Mesh rule + :param mesh_group: Mesh Group to add the rule to + :param use_32bit_vertices: False = 16bit vertex position precision. True = 32bit vertex position precision + :param merge_meshes: Merge all meshes into a single mesh + :param use_custom_normals: True = use normals from DCC tool. False = average normals + :param vertex_color_stream: Color stream name to use for Vertex Coloring + """ + rule = { + '$type': 'StaticMeshAdvancedRule', + 'use32bitVertices': self.__default_or_value(use_32bit_vertices, False), + 'mergeMeshes': self.__default_or_value(merge_meshes, True), + 'useCustomNormals': self.__default_or_value(use_custom_normals, True) + } + + if vertex_color_stream is not None: + rule['vertexColorStreamName'] = vertex_color_stream + + mesh_group['rules']['rules'].append(rule) + + def mesh_group_add_skin_rule(self, mesh_group: dict, max_weights_per_vertex: int, weight_threshold: float) -> None: + """ + Adds a Skin rule + :param mesh_group: Mesh Group to add the rule to + :param max_weights_per_vertex: Max number of joints that can influence a vertex + :param weight_threshold: Weight values below this value will be treated as 0 + """ + rule = { + '$type': 'SkinRule', + 'maxWeightsPerVertex': self.__default_or_value(max_weights_per_vertex, 4), + 'weightThreshold': self.__default_or_value(weight_threshold, 0.001) + } + + mesh_group['rules']['rules'].append(rule) + + def mesh_group_add_tangent_rule(self, mesh_group: dict, tangent_space: int, tspace_method: int) -> None: + """ + Adds a Tangent rule to control tangent space generation + :param mesh_group: Mesh Group to add the rule to + :param tangent_space: Tangent space source. 0 = Scene, 1 = MikkT Tangent Generation + :param tspace_method: MikkT Generation method. 0 = TSpace, 1 = TSpaceBasic + """ + rule = { + '$type': 'TangentsRule', + 'tangentSpace': self.__default_or_value(tangent_space, 1), + 'tSpaceMethod': self.__default_or_value(tspace_method, 0) + } + + mesh_group['rules']['rules'].append(rule) def export(self): return json.dumps(self.manifest) From 858885dca932e6bda964616dab852cfe358e87ee Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 13:46:53 -0800 Subject: [PATCH 44/72] Removes all files from linux install (#6019) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- cmake/Platform/Linux/Packaging/postrm.in | 5 ----- cmake/Platform/Linux/Packaging/prerm.in | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/cmake/Platform/Linux/Packaging/postrm.in b/cmake/Platform/Linux/Packaging/postrm.in index acda38bf1e..cd6f37abe4 100644 --- a/cmake/Platform/Linux/Packaging/postrm.in +++ b/cmake/Platform/Linux/Packaging/postrm.in @@ -8,8 +8,3 @@ # set -o errexit # exit on the first failure encountered - -{ - pushd @CPACK_PACKAGING_INSTALL_PREFIX@ - popd -} &> /dev/null # hide output diff --git a/cmake/Platform/Linux/Packaging/prerm.in b/cmake/Platform/Linux/Packaging/prerm.in index 5595d7010f..843f21da24 100644 --- a/cmake/Platform/Linux/Packaging/prerm.in +++ b/cmake/Platform/Linux/Packaging/prerm.in @@ -19,5 +19,6 @@ set -o errexit # exit on the first failure encountered pushd @CPACK_PACKAGING_INSTALL_PREFIX@ # delete python downloads rm -rf python/downloaded_packages python/runtime - popd + find . -type d -name *.egg-info -prune -exec rm -rf {} \; + popd } &> /dev/null # hide output From 530bcb9428dc0e898f3392c3e1eac1947ed77da2 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 30 Nov 2021 14:17:02 -0800 Subject: [PATCH 45/72] //! for code comments autogen Signed-off-by: Gene Walters --- .../AzFramework/Process/ProcessCommunicatorTracePrinter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h index 8b84c4c28d..5e14fa290d 100644 --- a/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h +++ b/Code/Framework/AzFramework/AzFramework/Process/ProcessCommunicatorTracePrinter.h @@ -18,13 +18,13 @@ public: ProcessCommunicatorTracePrinter(AzFramework::ProcessCommunicator* communicator, const char* window); ~ProcessCommunicatorTracePrinter(); - // Call this periodically to drain the buffers and write them. + //! Call this periodically to drain the buffers and write them. void Pump(); - // Drains the buffer into the string that's being built, then traces the string when it hits a newline. + //! Drains the buffer into the string that's being built, then traces the string when it hits a newline. void ParseDataBuffer(AZ::u32 readSize, bool isFromStdErr); - // Prints the current buffer to AZ_Error or AZ_TracePrintf so that it can be picked up by AZ::Debug::Trace + //! Prints the current buffer to AZ_Error or AZ_TracePrintf so that it can be picked up by AZ::Debug::Trace void WriteCurrentString(bool isFromStdError); private: From fb6e6e339fe8777bc0304b33d60098ac87f11534 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:07:57 -0800 Subject: [PATCH 46/72] Add CRC validator (#5857) * Adds crc validation checks Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Fixes invalid CRCs Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Changes test to smoke suite Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * excludes some test data from the validator Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * uses pathlib instead of os.path Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * fixes wrong path to test scripts Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Escape not needed Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/Math/Crc.h | 4 +- .../AzToolsFramework/Viewport/ActionBus.h | 10 ++-- .../Code/Source/AtomBridgeSystemComponent.cpp | 4 +- .../AssetCollectionAsyncLoaderTestComponent.h | 4 +- ...tomViewportDisplayIconsSystemComponent.cpp | 2 +- ...clusionCullingPlaneComponentController.cpp | 4 +- .../Source/Editor/EditorSystemComponent.h | 4 +- .../NodePalette/InputOutputNodePaletteItem.h | 2 +- .../NodePalette/ModuleNodePaletteItem.h | 2 +- .../NodePalette/StandardNodePaletteItem.h | 2 +- .../Shape/EditorTubeShapeComponentMode.cpp | 2 +- .../PropertyHandlerUiParticleColorKeyframe.h | 2 +- .../PropertyHandlerUiParticleFloatKeyframe.h | 2 +- .../LyShine/Code/Source/LyShineLoadScreen.cpp | 4 +- .../Code/Editor/ColliderComponentMode.cpp | 8 ++-- .../Code/Source/EditorSystemComponent.h | 2 +- .../EditorWhiteBoxDefaultMode.cpp | 4 +- scripts/commit_validation/CMakeLists.txt | 6 +-- .../commit_validation/commit_validation.py | 2 + .../tests/validators/test_crc_validator.py | 47 ++++++++++++++++++ .../validators/crc_validator.py | 48 +++++++++++++++++++ 21 files changed, 130 insertions(+), 35 deletions(-) create mode 100644 scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py create mode 100644 scripts/commit_validation/commit_validation/validators/crc_validator.py diff --git a/Code/Framework/AzCore/AzCore/Math/Crc.h b/Code/Framework/AzCore/AzCore/Math/Crc.h index 9ba2a83139..c71339e92e 100644 --- a/Code/Framework/AzCore/AzCore/Math/Crc.h +++ b/Code/Framework/AzCore/AzCore/Math/Crc.h @@ -16,7 +16,7 @@ // // When AZ_CRC("My string") is used by default it will map to AZ::Crc32("My string"). // We do have a pro-processor program which will precompute the crc for you and -// transform that macro to AZ_CRC("My string",0xabcdef00) this will expand to just 0xabcdef00. +// transform that macro to AZ_CRC("My string", 0x18fbd270) this will expand to just 0x18fbd270. // This will remove completely the "My string" from your executable, it will add it to a database and so on. // WHen you want to update the string, just change the string. // If you don't run the precompile step the code should still run fine, except it will be slower, @@ -24,7 +24,7 @@ // a constant expression. // For example // switch(id) { -// case AZ_CRC("My string",0xabcdef00): {} break; // this will compile fine +// case AZ_CRC("My string",0x18fbd270): {} break; // this will compile fine // case AZ_CRC("My string"): {} break; // this will cause "error C2051: case expression not constant" // } // So it's you choice what you do, depending on your needs. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h index 4dde676511..c0562025b6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h @@ -23,11 +23,11 @@ namespace AzToolsFramework /// @name Reverse URLs. /// Used to identify common actions and override them when necessary. //@{ - static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0xd772a2af); - static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x5731f6cb); - static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0x08ccf461); - static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xcc26094f); - static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0d18ff39); + static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0x80c3030f); + static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x58e78eed); + static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0xbc5a4a23); + static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xf9aca3a8); + static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0580eaec); //@} /// Specific Action properties to be sent to a type implementing diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp index d822b16486..7a980f9824 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp @@ -67,12 +67,12 @@ namespace AZ void AtomBridgeSystemComponent::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99)); + provided.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5)); } void AtomBridgeSystemComponent::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99)); + incompatible.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5)); } void AtomBridgeSystemComponent::GetRequiredServices(ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h index 9ab25741af..3af1ad8907 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.h @@ -109,12 +109,12 @@ namespace AZ static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) { - services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0xdd5ab934)); + services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0x66d04369)); } static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) { - services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0xdd5ab934)); + services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0x66d04369)); } static void Reflect(AZ::ReflectContext* context); diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp index 38679432ea..fa7a0cf2bf 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp @@ -73,7 +73,7 @@ namespace AZ::Render void AtomViewportDisplayIconsSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { required.push_back(AZ_CRC("RPISystem", 0xf2add773)); - required.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99)); + required.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5)); } void AtomViewportDisplayIconsSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp index 4c78a0afd7..4addbde3ef 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp @@ -59,12 +59,12 @@ namespace AZ void OcclusionCullingPlaneComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x9123f33d)); + provided.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x7d036c2e)); } void OcclusionCullingPlaneComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x9123f33d)); + incompatible.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x7d036c2e)); } void OcclusionCullingPlaneComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h index 31daae1a18..fe17bfaac0 100644 --- a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h +++ b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h @@ -31,12 +31,12 @@ namespace Blast private: static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("BlastEditorService", 0x0a61cda5)); + provided.push_back(AZ_CRC("BlastEditorService", 0xeddfed0d)); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { - required.push_back(AZ_CRC("BlastService", 0x75beae2d)); + required.push_back(AZ_CRC("BlastService", 0x46927a9f)); } AZStd::unique_ptr m_editorBlastChunksAssetHandler; diff --git a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h index 15f308c4d2..99a32d965b 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/InputOutputNodePaletteItem.h @@ -33,7 +33,7 @@ namespace GraphModelIntegration //! Constructor //! \param nodeName Name of the node that will show up in the Palette - //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a)) + //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0x0a1dff96)) //! \param dataType The type of data that the InputGraphNode or OutputGraphNode will represent InputOutputNodePaletteItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId, GraphModel::DataTypePtr dataType) : DraggableNodePaletteTreeItem(nodeName, editorId) diff --git a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h index a0121ac035..51e1fca55b 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/ModuleNodePaletteItem.h @@ -95,7 +95,7 @@ namespace GraphModelIntegration AZ_CLASS_ALLOCATOR(ModuleNodePaletteItem, AZ::SystemAllocator, 0); //! Constructor - //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a)) + //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0x0a1dff96)) //! \param sourceFileId The unique id for the module node graph source file. //! \param sourceFilePath The path to the module node graph source file. This will be used for node naming and debug output. ModuleNodePaletteItem(GraphCanvas::EditorId editorId, AZ::Uuid sourceFileId, AZStd::string_view sourceFilePath) diff --git a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h index 5d2914d7ad..e38e3b7478 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Integration/NodePalette/StandardNodePaletteItem.h @@ -34,7 +34,7 @@ namespace GraphModelIntegration //! Constructor //! \param nodeName Name of the node that will show up in the Palette - //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0xa6d1a85a)) + //! \param editorId Unique name of the client system editor (ex: AZ_CRC("ShaderCanvas", 0x0a1dff96)) StandardNodePaletteItem(AZStd::string_view nodeName, GraphCanvas::EditorId editorId) : DraggableNodePaletteTreeItem(nodeName, editorId) { diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp index 340752251d..fd91c84c12 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp @@ -22,7 +22,7 @@ namespace LmbrCentral { AZ_CLASS_ALLOCATOR_IMPL(EditorTubeShapeComponentMode, AZ::SystemAllocator, 0) - static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.o3de.action.tubeshape.reset_radii", 0x0f2ef8e2); + static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.o3de.action.tubeshape.reset_radii", 0xa987659c); static const char* const s_resetRadiiTitle = "Reset Radii"; static const char* const s_resetRadiiDesc = "Reset all variable radius values to the default"; diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h index 9fdc8e61c4..639d042b34 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h +++ b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleColorKeyframe.h @@ -50,7 +50,7 @@ class PropertyHandlerUiParticleColorKeyframe public: AZ_CLASS_ALLOCATOR(PropertyHandlerUiParticleColorKeyframe, AZ::SystemAllocator, 0); - AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleColorKeyframeCtrl", 0x8cb3a9f1); } + AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleColorKeyframeCtrl", 0xe3ef28b6); } bool IsDefaultHandler() const override { return true; } QWidget* CreateGUI(QWidget* pParent) override; void ConsumeAttribute(PropertyUiParticleColorKeyframeCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override; diff --git a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h index 39e5dd27c2..df3983dc3e 100644 --- a/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h +++ b/Gems/LyShine/Code/Editor/PropertyHandlerUiParticleFloatKeyframe.h @@ -50,7 +50,7 @@ class PropertyHandlerUiParticleFloatKeyframe public: AZ_CLASS_ALLOCATOR(PropertyHandlerUiParticleFloatKeyframe, AZ::SystemAllocator, 0); - AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleFloatKeyframeCtrl", 0xba9359a2); } + AZ::u32 GetHandlerName(void) const override { return AZ_CRC("UiParticleFloatKeyframeCtrl", 0x448a90ec); } bool IsDefaultHandler() const override { return true; } QWidget* CreateGUI(QWidget* pParent) override; void ConsumeAttribute(PropertyUiParticleFloatKeyframeCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override; diff --git a/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp b/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp index 279c0527bd..831bdb048a 100644 --- a/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp +++ b/Gems/LyShine/Code/Source/LyShineLoadScreen.cpp @@ -31,12 +31,12 @@ namespace LyShine void LyShineLoadScreenComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xBB5EAB17)); + provided.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xbb5eab17)); } void LyShineLoadScreenComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xBB5EAB17)); + incompatible.emplace_back(AZ_CRC("LyShineLoadScreenService", 0xbb5eab17)); } void LyShineLoadScreenComponent::Init() diff --git a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp index e5e75d88a3..b91b3e5bb9 100644 --- a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp @@ -27,10 +27,10 @@ namespace PhysX namespace { //! Uri's for shortcut actions. - const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.o3de.action.physx.setdimensionssubmode", 0x77b70dd6); - const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.o3de.action.physx.setoffsetsubmode", 0xc06132e5); - const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.o3de.action.physx.setrotationsubmode", 0xc4225918); - const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.o3de.action.physx.resetsubmode", 0xb70b120e); + const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.o3de.action.physx.setdimensionssubmode", 0x508b1781); + const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.o3de.action.physx.setoffsetsubmode", 0x777ac743); + const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.o3de.action.physx.setrotationsubmode", 0xf1a8f3ff); + const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.o3de.action.physx.resetsubmode", 0x599d1594); } // namespace AZ_CLASS_ALLOCATOR_IMPL(ColliderComponentMode, AZ::SystemAllocator, 0); diff --git a/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h b/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h index 14f37ef01e..fc0d60640c 100644 --- a/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h +++ b/Gems/PhysXDebug/Code/Source/EditorSystemComponent.h @@ -32,7 +32,7 @@ namespace PhysXDebug static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("PhysXDebugEditorService", 0xe3dde7d8)); + provided.push_back(AZ_CRC("PhysXDebugEditorService", 0xf8611967)); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) diff --git a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp index 3d6d9a4c0a..608605be62 100644 --- a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp +++ b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp @@ -33,8 +33,8 @@ namespace WhiteBox AZ::Color, cl_whiteBoxVertexIndicatorColor, AZ::Color::CreateFromRgba(0, 0, 0, 102), nullptr, AZ::ConsoleFunctorFlags::Null, "The color of the vertex indicator"); - static const AZ::Crc32 HideEdge = AZ_CRC("com.o3de.action.whitebox.hide_edge", 0x6a60ae23); - static const AZ::Crc32 HideVertex = AZ_CRC("com.o3de.action.whitebox.hide_vertex", 0x4a4bd092); + static const AZ::Crc32 HideEdge = AZ_CRC("com.o3de.action.whitebox.hide_edge", 0x84f6a9b9); + static const AZ::Crc32 HideVertex = AZ_CRC("com.o3de.action.whitebox.hide_vertex", 0x5f81c937); static const char* const HideEdgeTitle = "Hide Edge"; static const char* const HideEdgeDesc = "Hide the selected edge to merge the two connected polygons"; diff --git a/scripts/commit_validation/CMakeLists.txt b/scripts/commit_validation/CMakeLists.txt index 6079515eb8..00e8506ef1 100644 --- a/scripts/commit_validation/CMakeLists.txt +++ b/scripts/commit_validation/CMakeLists.txt @@ -6,10 +6,8 @@ # # -# this ctest makes sure that the commit validation function -# also runs its tests during commit validation! ly_add_pytest( NAME test_commit_validation - PATH ${CMAKE_CURRENT_LIST_DIR} + PATH ${CMAKE_CURRENT_LIST_DIR}/commit_validation/tests + TEST_SUITE smoke ) - diff --git a/scripts/commit_validation/commit_validation/commit_validation.py b/scripts/commit_validation/commit_validation/commit_validation.py index 513244a735..be8fc4ce1e 100755 --- a/scripts/commit_validation/commit_validation/commit_validation.py +++ b/scripts/commit_validation/commit_validation/commit_validation.py @@ -181,4 +181,6 @@ EXCLUDED_VALIDATION_PATTERNS = [ 'restricted/*/Tools/*RemoteControl', '*/user/Cache/*', '*/user/log/*', + '*/user/log_test_1/*', + '*/user/log_test_2/*', ] diff --git a/scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py b/scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py new file mode 100644 index 0000000000..6fbe86ab29 --- /dev/null +++ b/scripts/commit_validation/commit_validation/tests/validators/test_crc_validator.py @@ -0,0 +1,47 @@ +# +# 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 unittest +from unittest.mock import patch, mock_open + +from commit_validation.tests.mocks.mock_commit import MockCommit +from commit_validation.validators.crc_validator import CrcValidator + + +class CrcValidatorTests(unittest.TestCase): + + @patch('builtins.open', mock_open(read_data='This file does not contain an AZ_CRC macro')) + def test_fileWithNoCrc_passes(self): + commit = MockCommit(files=['/someCppFile.cpp']) + error_list = [] + self.assertTrue(CrcValidator().run(commit, error_list)) + self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}") + + @patch('builtins.open', mock_open(read_data='This file contains an invalid CRC macro AZ_CRC("My string", 0xabcdef00)')) + def test_fileWithInvalidCrc_fails(self): + commit = MockCommit(files=['/someCppFile.cpp']) + error_list = [] + self.assertFalse(CrcValidator().run(commit, error_list)) + self.assertNotEqual(len(error_list), 0, f"Errors were expected but none were returned.") + + @patch('builtins.open', mock_open(read_data='This file contains a valid CRC macro AZ_CRC("My string", 0x18fbd270)')) + def test_fileWithValidCrc_fails(self): + commit = MockCommit(files=['/someCppFile.cpp']) + error_list = [] + self.assertTrue(CrcValidator().run(commit, error_list)) + self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}") + + @patch('builtins.open', mock_open(read_data='This file contains an invalid CRC macro AZ_CRC("My string", 0xabcdef00)')) + def test_fileExtensionIgnored_passes(self): + commit = MockCommit(files=['/someCppFile.somerandomextension']) + error_list = [] + self.assertTrue(CrcValidator().run(commit, error_list)) + self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}") + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/commit_validation/commit_validation/validators/crc_validator.py b/scripts/commit_validation/commit_validation/validators/crc_validator.py new file mode 100644 index 0000000000..db99d7b50b --- /dev/null +++ b/scripts/commit_validation/commit_validation/validators/crc_validator.py @@ -0,0 +1,48 @@ +# +# 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 binascii +import fnmatch +import pathlib +import re +from typing import Type, List + +from commit_validation.commit_validation import Commit, CommitValidator, SOURCE_FILE_EXTENSIONS, EXCLUDED_VALIDATION_PATTERNS, VERBOSE + +class CrcValidator(CommitValidator): + """A file-level validator that makes sure a file does not contain an invalid CRC""" + + def run(self, commit: Commit, errors: List[str]) -> bool: + for file_name in commit.get_files(): + for pattern in EXCLUDED_VALIDATION_PATTERNS: + if fnmatch.fnmatch(file_name, pattern): + if VERBOSE: print(f'{file_name}::{self.__class__.__name__} SKIPPED - Validation pattern excluded on path.') + break + else: + if pathlib.Path(file_name).suffix.lower() not in SOURCE_FILE_EXTENSIONS: + if VERBOSE: print(f'{file_name}::{self.__class__.__name__} SKIPPED - File excluded based on extension.') + continue + + with open(file_name, mode='r', encoding='utf8') as fh: + fileContents = fh.read() + matchesFound = re.findall(r'AZ_CRC\("([^"]+)",([^)]*)\)', fileContents) + for element in matchesFound: + stringInCode = element[0] + valueInCode = element[1].strip() + expectedValue = "{0:#0{1}x}".format(binascii.crc32(stringInCode.lower().encode('utf8')), 10) + if expectedValue != valueInCode: + error_message = str(f'{file_name}::{self.__class__.__name__} FAILED - Source file contains a CRC mismatch!\n' + f' AZ_CRC("{stringInCode}", {valueInCode}), expected value {expectedValue}') + if VERBOSE: print(error_message) + errors.append(error_message) + return (not errors) + + +def get_validator() -> Type[CrcValidator]: + """Returns the validator class for this module""" + return CrcValidator From 93ec5de5525ad573b203ae33ea671fe23b82c047 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:09:20 -0800 Subject: [PATCH 47/72] Enables monolithic for ServerLauncher (#5883) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- cmake/Monolithic.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/Monolithic.cmake b/cmake/Monolithic.cmake index 1e121c2b20..2310d8d0d7 100644 --- a/cmake/Monolithic.cmake +++ b/cmake/Monolithic.cmake @@ -16,7 +16,6 @@ if(LY_MONOLITHIC_GAME) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_TESTS_SUPPORTED FALSE) - ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) else() ly_set(PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE SHARED) ly_set(PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE GEM_MODULE) From 79ac840246b16244ad65d62e6c7612a5cded30b7 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:19:59 -0800 Subject: [PATCH 48/72] add docstring info for the LDR color grading LUT property option for Display Mapper components Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/atom_utils/atom_constants.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index ebc8a932d6..b40cf8b26c 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -149,6 +149,8 @@ class AtomComponentProperties: def display_mapper(property: str = 'name') -> str: """ Display Mapper component properties. + - 'LDR color Grading LUT' is the Low Definition Range (LDR) color grading for Look-up Textures (LUT) which is + typically a lighting asset file (i.e. test.lightingpreset.azasset set as a LDR color grading LUT). :param property: From the last element of the property tree path. Default 'name' for component name string. :return: Full property path OR component name if no property specified. """ From c8a5f1b3ebf3d4e1553c61592fb5340287aa8131 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Tue, 30 Nov 2021 15:26:18 -0800 Subject: [PATCH 49/72] add Asset.id value to the Display Mapper docstring for LDR color grading LUT property Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/atom_utils/atom_constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index b40cf8b26c..1cd4bf3ac0 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -150,7 +150,7 @@ class AtomComponentProperties: """ Display Mapper component properties. - 'LDR color Grading LUT' is the Low Definition Range (LDR) color grading for Look-up Textures (LUT) which is - typically a lighting asset file (i.e. test.lightingpreset.azasset set as a LDR color grading LUT). + an Asset.id value corresponding to a lighting asset file. :param property: From the last element of the property tree path. Default 'name' for component name string. :return: Full property path OR component name if no property specified. """ From 28096617941313ecce272038378a7ae3735cc885 Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Tue, 30 Nov 2021 17:43:53 -0600 Subject: [PATCH 50/72] Xfailing 2 DynVeg tests that fail to create levels in AR (#6051) * Xfailing 2 DynVeg tests that fail to create levels in AR Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> * Adding xfail to one more test, and updating reason Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../largeworlds/dyn_veg/TestSuite_Main_Optimized.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index d83f88cad2..2211c28060 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -148,6 +148,7 @@ class TestAutomation(EditorTestSuite): class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorParallelTest): from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module + @pytest.mark.xfail(reason="Intermittently fails to create level") class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest): from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module @@ -156,6 +157,7 @@ class TestAutomation(EditorTestSuite): file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], True, True) + @pytest.mark.xfail(reason="Intermittently fails to create level") class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest): from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module @@ -163,7 +165,8 @@ class TestAutomation(EditorTestSuite): def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], True, True) - + + @pytest.mark.xfail(reason="Intermittently fails to create level") class test_LayerBlender_E2E_Editor(EditorSingleTest): from .EditorScripts import LayerBlender_E2E_Editor as test_module From 58be7c27edec0319cc76b22f5389e1f77cda398b Mon Sep 17 00:00:00 2001 From: Shirang Jia Date: Tue, 30 Nov 2021 16:46:03 -0800 Subject: [PATCH 51/72] Make scrubber/validator not depend on legacy packaging scripts (#6053) * Make validator not depend on legacy packaging scripts Signed-off-by: Shirang Jia * Remove unused glob_to_regex.py Signed-off-by: Shirang Jia * Remove unsued import path Signed-off-by: Shirang Jia --- scripts/build/package/glob_to_regex.py | 130 ------------------------- scripts/scrubbing/scrubbing_job.py | 29 ------ scripts/scrubbing/validator.py | 37 +++---- 3 files changed, 12 insertions(+), 184 deletions(-) delete mode 100755 scripts/build/package/glob_to_regex.py delete mode 100755 scripts/scrubbing/scrubbing_job.py diff --git a/scripts/build/package/glob_to_regex.py b/scripts/build/package/glob_to_regex.py deleted file mode 100755 index 53ad3d850d..0000000000 --- a/scripts/build/package/glob_to_regex.py +++ /dev/null @@ -1,130 +0,0 @@ -# -# 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 __future__ import absolute_import -import os -import re -import json -import sys -try: - import six -except ImportError: - import pip - pip.main(['install', 'six', '--ignore-installed', '-q']) - import six -from pathlib import Path - -this_file_path = os.path.dirname(os.path.realpath(__file__)) - -# resolve symlinks and eliminate ".." components -engine_root_path = Path(__file__).resolve().parents[3] - -def convert_glob_pattern_to_regex_pattern(glob_pattern): - # switch to forward slashes because way easier to pattern match against - pattern = re.sub(r'\\', r'/', glob_pattern) - - # Replace the dots and question marks - pattern = re.sub(r'\.', r'\\.', pattern) - pattern = re.sub(r'\?', r'.', pattern) - - # Handle the * vs ** expansions - pattern = re.sub(r'([^*])\*($|[^*])', r'\1[^/\\\\]*\2', pattern) - pattern = re.sub(r'\*\*/', r'(.*/)?', pattern) - pattern = re.sub(r'\*\*', r'.*', pattern) - - # replace the forward slashes with [/\\] so it works on PC/unix - pattern = re.sub(r'([^^])/', r'\1[/\\\\]', pattern) - return pattern - -# Convert the package json into a pair of regexes we can use to look for includes and excludes -def convert_glob_list_to_regex_list(filelist, prefix): - includes = [] - excludes = [] - for key, value in six.iteritems(filelist): - glob_pattern = os.path.join(prefix, key) - if isinstance(value, dict): - (sub_includes, sub_excludes) = convert_glob_list_to_regex_list(value, glob_pattern) - includes.extend(sub_includes) - excludes.extend(sub_excludes) - else: - # Simulate what glob would do with file walking to scope the * within a directory - # and ** across directories - regex_pattern = convert_glob_pattern_to_regex_pattern(os.path.normpath(glob_pattern)) - - # Deal with the commands. include/exclude are straight forward. Moves/renames are to be considered - # includes, and we will stick with validating the original contents for now - if value == "#include": - includes.append(regex_pattern) - elif value == "#exclude": - excludes.append(regex_pattern) - elif value.startswith('#move:'): - includes.append(regex_pattern) - elif value.startswith('#rename:'): - includes.append(regex_pattern) - else: - pass - return (includes, excludes) - -def generate_excludes_for_platform(root, platform): - if platform == 'all': - platform_exclusions_filename = os.path.join(this_file_path, 'platform_exclusions.json') - with open(platform_exclusions_filename, 'r') as platform_exclusions_file: - platform_exclusions = json.load(platform_exclusions_file) - else: - # Use real path in case root is a symlink path - if os.name == 'posix' and os.path.islink(root): - root = os.readlink(root) - # "root" is the root of the folder structure we're validating - # "engine_root_path" is the engine root where the restricted platform folder is linked - relative_folder = os.path.relpath(this_file_path, engine_root_path) - platform_exclusions_filename = os.path.join(engine_root_path, 'restricted', platform, relative_folder, platform.lower() + '_exclusions.json') - with open(platform_exclusions_filename, 'r') as platform_exclusions_file: - platform_exclusions = json.load(platform_exclusions_file) - - if platform not in platform_exclusions: - raise KeyError('No {} found in {}'.format(platform, platform_exclusions_filename)) - if '@lyengine' not in platform_exclusions[platform]: - raise KeyError('No {}/@lyengine found in {}'.format(platform, package_file_list)) - (_, excludes) = convert_glob_list_to_regex_list(platform_exclusions[platform]['@lyengine'], root) - del _ - return excludes - -def generate_include_exclude_regexes(package_platform, package_type, root, prohibited_platforms): - # The general contents will be indicated by the package file - if package_type == 'all': - package_file_list = os.path.join(this_file_path, 'package_filelists', 'all.json') - else: - # Search non-restricted platform first - package_file_list = os.path.join(this_file_path, 'Platform', package_platform, 'package_filelists', f'{package_type}.json') - if not os.path.exists(filelist): - # Use real path in case root is a symlink path - if os.name == 'posix' and os.path.islink(root): - root = os.readlink(root) - # "root" is the root of the folder structure we're validating - # "engine_root_path" is the engine root where the restricted platform folder is linked - rel_path = os.path.relpath(this_file_path, engine_root_path) - package_file_list = os.path.join(engine_root_path, 'restricted', package_platform, rel_path, 'package_filelists', - f'{package_type}.json') - with open(package_file_list, 'r') as package_file: - package = json.load(package_file) - - if '@lyengine' not in package: - raise KeyError('No @lyengine found in {}'.format(package_file_list)) - - (includes_list, excludes_list) = convert_glob_list_to_regex_list(package['@lyengine'], root) - prohibited_platforms.append('all') - - # Add the exclusions of each prohibited platform - for p in prohibited_platforms: - excludes_list.extend(generate_excludes_for_platform(root, p)) - - includes = re.compile('|'.join(includes_list), re.IGNORECASE) - excludes = re.compile('|'.join(excludes_list), re.IGNORECASE) - return (includes, excludes) - -def generate_exclude_regexes_for_platform(root, platform): - return re.compile('|'.join(generate_excludes_for_platform(root, platform)), re.IGNORECASE) diff --git a/scripts/scrubbing/scrubbing_job.py b/scripts/scrubbing/scrubbing_job.py deleted file mode 100755 index 11dbf5ea5a..0000000000 --- a/scripts/scrubbing/scrubbing_job.py +++ /dev/null @@ -1,29 +0,0 @@ -# -# 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 os -import sys -cur_dir = cur_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, os.path.abspath(f'{cur_dir}/../build/package')) -import util - -# Run validator -success = True -validator_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'validator.py') -engine_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) -if sys.platform == 'win32': - python = os.path.join(engine_root, 'python', 'python.cmd') -else: - python = os.path.join(engine_root, 'python', 'python.sh') -args = [python, validator_path, '--package_platform', 'Windows', '--package_type', 'all', engine_root] -return_code = util.safe_execute_system_call(args) -if return_code != 0: - success = False -if not success: - util.error('Restricted file validator failed.') -print('Restricted file validator completed successfully.') diff --git a/scripts/scrubbing/validator.py b/scripts/scrubbing/validator.py index 39f1a40a18..3b53417755 100755 --- a/scripts/scrubbing/validator.py +++ b/scripts/scrubbing/validator.py @@ -29,8 +29,6 @@ else: from io import StringIO import validator_data_LEGAL_REVIEW_REQUIRED # pull in the data we need to configure this tool -sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'build', 'package')) -from glob_to_regex import generate_include_exclude_regexes class Validator(object): """Class to contain the validator program""" @@ -212,9 +210,6 @@ class Validator(object): # TODO: Perhaps the directories to skip should become a parameter so we can use the validator # on non-Lumberyard trees. def validate_directory_tree(self, root, platform): - prohibited_platforms = validator_data_LEGAL_REVIEW_REQUIRED.get_prohibited_platforms_for_package(self.options.package_platform) - (includes, excludes) = generate_include_exclude_regexes(self.options.package_platform, self.options.package_type, root, prohibited_platforms) - """Walk from root to find all files to validate and call the validator on each file. Return 0 if no problems where found, and 1 if any validation failures occured.""" counter = 0 @@ -227,28 +222,22 @@ class Validator(object): # First deal with the files in the current directory for filename in filenames: filepath = os.path.join(dirname, filename) - include_match = includes.match(filepath) - exclude_match = excludes.match(filepath) - allowed = include_match and not exclude_match - - if self.options.all or allowed: - scanned += 1 - file_failed = self.validate_file(os.path.normpath(filepath)) - if file_failed: - platform_failed = file_failed - else: - validations += 1 - counter += 1 + scanned += 1 + file_failed = self.validate_file(os.path.normpath(filepath)) + if file_failed: + platform_failed = file_failed + else: + validations += 1 # Trim out allowlisted subdirectories in the current directory if allowed for name in bypassed_directories: if name in dirnames: dirnames.remove(name) - if counter == 0 or scanned == 0: + if scanned == 0: logging.error('No files scanned at target search directory: %s', root) platform_failed = 1 else: - print('validated {} of {} package files ({} non-package files skipped)'.format(validations, scanned, counter - scanned)) + print('validated {} of {} files'.format(validations, scanned)) return platform_failed @@ -387,8 +376,6 @@ def parse_options(): choices=platform_choices, dest='package_platform', help='Package platform to validate. Must be one of {}.'.format(platform_choices)) - parser.add_option('--package_type', action='store', type='string', default='all', dest='package_type', - help='Package type to validate.') parser.add_option('-s', '--store-exceptions', action='store', type='string', default='', dest='exception_file', help='Store list of lines that the validator gave exceptions to by matching accepted use patterns. These can be diffed with prior runs to see what is changing.') @@ -430,7 +417,6 @@ def main(): package_failed = 0 package_platform = validator.options.package_platform - package_type = validator.options.package_type prohibited_platforms = validator_data_LEGAL_REVIEW_REQUIRED.get_prohibited_platforms_for_package(package_platform) if validator.options.exception_file != '': @@ -441,19 +427,20 @@ def main(): sys.exit(1) for platform in prohibited_platforms: - print('validating {} against {} for package platform {} package type {}'.format(args[0], platform, package_platform, package_type)) + print('validating {} against {} for package platform {}'.format(args[0], platform, package_platform)) platform_failed = validator.validate(platform) if platform_failed: - print('{} FAILED validation against {} for package platform {} package type {}'.format(args[0], platform, package_platform, package_type)) + print('{} FAILED validation against {} for package platform {}'.format(args[0], platform, package_platform)) package_failed = platform_failed else: - print('{} is VALIDATED against {} for package platform {} package type {}'.format(args[0], platform, package_platform, package_type)) + print('{} is VALIDATED against {} for package platform {}'.format(args[0], platform, package_platform)) if validator.options.exception_file != '': validator.exceptions_output.close() return package_failed + if __name__ == '__main__': # pylint: disable-msg=C0103 main_results = main() From b2c13b24ffea6f5c57ddded4ac8cef05ae2422f3 Mon Sep 17 00:00:00 2001 From: bosnichd Date: Wed, 1 Dec 2021 07:49:22 -0700 Subject: [PATCH 52/72] Fix ImGui Gamepad Input (#6055) This fixes gamepad input for both of our ImGui integrations (which should probably be combined at some point). Signed-off-by: bosnichd --- .../Common/Code/Source/ImGui/ImGuiPass.cpp | 23 +++++++++++-- .../Common/Code/Source/ImGui/ImGuiPass.h | 1 + Gems/ImGui/Code/Source/ImGuiManager.cpp | 34 +++++-------------- Gems/ImGui/Code/Source/ImGuiManager.h | 5 --- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp index 0ff8d2c165..7197b95917 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.cpp @@ -140,9 +140,18 @@ namespace AZ m_drawData.push_back(drawData); } + int ImGuiPass::GetTickOrder() + { + // We have to call ImGui::NewFrame (which happens in ImGuiPass::OnTick) after setting + // ImGui::GetIO().NavInputs (which happens in ImGuiPass::OnInputChannelEventFiltered), + // but before ImGui::Render (which happens in ImGuiPass::SetupFrameGraphDependencies). + return AZ::ComponentTickBus::TICK_PRE_RENDER; + } + void ImGuiPass::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint) { auto imguiContextScope = ImguiContextScope(m_imguiContext); + ImGui::NewFrame(); auto& io = ImGui::GetIO(); io.DeltaTime = deltaTime; @@ -413,6 +422,7 @@ namespace AZ void ImGuiPass::Init() { + auto imguiContextScope = ImguiContextScope(m_imguiContext); auto& io = ImGui::GetIO(); // ImGui IO Setup @@ -421,7 +431,6 @@ namespace AZ { io.KeyMap[static_cast(i)] = static_cast(i); } - io.NavActive = true; // Touch input const AzFramework::InputDevice* inputDevice = nullptr; @@ -434,6 +443,17 @@ namespace AZ io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen; } + // Gamepad input + inputDevice = nullptr; + AzFramework::InputDeviceRequestBus::EventResult(inputDevice, + AzFramework::InputDeviceGamepad::IdForIndex0, + &AzFramework::InputDeviceRequests::GetInputDevice); + if (inputDevice && inputDevice->IsSupported()) + { + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + } + // Set initial display size to something reasonable (this will be updated in FramePrepare) io.DisplaySize.x = 1920; io.DisplaySize.y = 1080; @@ -571,7 +591,6 @@ namespace AZ auto imguiContextScope = ImguiContextScope(m_imguiContext); ImGui::GetIO().MouseWheel = m_lastFrameMouseWheel; m_lastFrameMouseWheel = 0.0; - ImGui::NewFrame(); } void ImGuiPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) diff --git a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h index 018d2d46b7..6c9dd11914 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h +++ b/Gems/Atom/Feature/Common/Code/Source/ImGui/ImGuiPass.h @@ -77,6 +77,7 @@ namespace AZ void RenderImguiDrawData(const ImDrawData& drawData); // TickBus::Handler overrides... + int GetTickOrder() override; void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override; // AzFramework::InputTextEventListener overrides... diff --git a/Gems/ImGui/Code/Source/ImGuiManager.cpp b/Gems/ImGui/Code/Source/ImGuiManager.cpp index b30eda8825..f90aa60a88 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.cpp +++ b/Gems/ImGui/Code/Source/ImGuiManager.cpp @@ -172,7 +172,6 @@ void ImGuiManager::Initialize() // Broadcast ImGui Ready to Listeners ImGuiUpdateListenerBus::Broadcast(&IImGuiUpdateListener::OnImGuiInitialize); - m_currentControllerIndex = -1; m_button1Pressed = m_button2Pressed = false; m_menuBarStatusChanged = false; @@ -227,6 +226,7 @@ void ImGui::ImGuiManager::RestoreRenderWindowSizeToDefault() void ImGui::ImGuiManager::SetDpiScalingFactor(float dpiScalingFactor) { + ImGui::ImGuiContextScope contextScope(m_imguiContext); ImGuiIO& io = ImGui::GetIO(); // Set the global font scale to size our UI to the scaling factor // Note: Currently we use the default, 13px fixed-size IMGUI font, so this can get somewhat blurry @@ -235,6 +235,7 @@ void ImGui::ImGuiManager::SetDpiScalingFactor(float dpiScalingFactor) float ImGui::ImGuiManager::GetDpiScalingFactor() const { + ImGui::ImGuiContextScope contextScope(m_imguiContext); ImGuiIO& io = ImGui::GetIO(); return io.FontGlobalScale; } @@ -406,7 +407,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) // Cycle through ImGui Menu Bar States on Home button press if (inputChannelId == InputDeviceKeyboard::Key::NavigationHome) { - ToggleThroughImGuiVisibleState(-1); + ToggleThroughImGuiVisibleState(); } // Cycle through Standalone Editor Window States @@ -453,19 +454,10 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) } // Handle Controller Inputs - int inputControllerIndex = -1; - bool controllerInput = false; if (InputDeviceGamepad::IsGamepadDevice(inputDeviceId)) { - inputControllerIndex = inputDeviceId.GetIndex(); - controllerInput = true; - } - - - if (controllerInput) - { - // Only pipe in Controller Nav Inputs if we are the current Controller Index and at least 1 of the two controller modes are enabled. - if (m_currentControllerIndex == inputControllerIndex && m_controllerModeFlags) + // Only pipe in Controller Nav Inputs when at least 1 of the two controller modes are enabled. + if (m_controllerModeFlags) { const auto lyButtonToImGuiNav = s_lyInputToImGuiNavIndexMap.find(inputChannelId); if (lyButtonToImGuiNav != s_lyInputToImGuiNavIndexMap.end()) @@ -476,7 +468,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) } //Switch menu bar display only if two buttons are pressed at the same time - if (inputChannelId == InputDeviceGamepad::Button::L3) + if (inputChannelId == InputDeviceGamepad::Button::L1) { if (inputChannel.IsStateBegan()) { @@ -488,7 +480,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) m_menuBarStatusChanged = false; } } - if (inputChannelId == InputDeviceGamepad::Button::R3) + if (inputChannelId == InputDeviceGamepad::Button::R1) { if (inputChannel.IsStateBegan()) { @@ -502,7 +494,7 @@ bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel) } if (!m_menuBarStatusChanged && m_button1Pressed && m_button2Pressed) { - ToggleThroughImGuiVisibleState(inputControllerIndex); + ToggleThroughImGuiVisibleState(); } // If we have the Discrete Input Mode Enabled.. and we are in the Visible State, then consume input here @@ -627,14 +619,13 @@ bool ImGuiManager::OnInputTextEventFiltered(const AZStd::string& textUTF8) return io.WantTextInput && m_clientMenuBarState == DisplayState::Visible;; } -void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) +void ImGuiManager::ToggleThroughImGuiVisibleState() { ImGui::ImGuiContextScope contextScope(m_imguiContext); switch (m_clientMenuBarState) { case DisplayState::Hidden: - m_currentControllerIndex = controllerIndex; m_clientMenuBarState = DisplayState::Visible; // Draw the ImGui Mouse cursor if either the hardware mouse is connected, or the controller mouse is enabled. @@ -669,7 +660,6 @@ void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) default: m_clientMenuBarState = DisplayState::Hidden; - m_currentControllerIndex = -1; // Enable system cursor if it's in editor and it's not editor game mode if (gEnv->IsEditor() && !gEnv->IsEditorGameMode()) @@ -686,12 +676,6 @@ void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex) m_setEnabledEvent.Signal(m_clientMenuBarState == DisplayState::Hidden); } -void ImGuiManager::ToggleThroughImGuiVisibleState() -{ - ToggleThroughImGuiVisibleState(-1); -} - - void ImGuiManager::RenderImGuiBuffers(const ImVec2& scaleRects) { ImGui::ImGuiContextScope contextScope(m_imguiContext); diff --git a/Gems/ImGui/Code/Source/ImGuiManager.h b/Gems/ImGui/Code/Source/ImGuiManager.h index c4fa5169f7..c0071c94c5 100644 --- a/Gems/ImGui/Code/Source/ImGuiManager.h +++ b/Gems/ImGui/Code/Source/ImGuiManager.h @@ -76,9 +76,6 @@ namespace ImGui // Sets up initial window size and listens for changes void InitWindowSize(); - // A function to toggle through the available ImGui Visibility States - void ToggleThroughImGuiVisibleState(int controllerIndex); - private: ImGuiContext* m_imguiContext = nullptr; DisplayState m_clientMenuBarState = DisplayState::Hidden; @@ -96,8 +93,6 @@ namespace ImGui std::vector m_idxBuffer; //Controller navigation - static const int MaxControllerNumber = 4; - int m_currentControllerIndex; bool m_button1Pressed, m_button2Pressed, m_menuBarStatusChanged; bool m_hardwardeMouseConnected = false; From 2065225099e73a535c8e3c1bb756a7acabf4405e Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 1 Dec 2021 09:04:49 -0600 Subject: [PATCH 53/72] Fixed LodRuleBehavior using wrong loop index (#5915) * Fixed LodRuleBehavior using wrong loop index Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add unit test for LOD auto-add crash Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix macro usage Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix include Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../SceneData/Behaviors/LodRuleBehavior.cpp | 2 +- .../SceneData/Behaviors/LodRuleBehavior.h | 18 +++-- .../SceneAPI/SceneData/Rules/LodRule.cpp | 1 - Code/Tools/SceneAPI/SceneData/Rules/LodRule.h | 20 ++--- .../SceneData/SceneData_testing_files.cmake | 1 + .../SceneData/Tests/GraphData/RulesTests.cpp | 78 +++++++++++++++++++ 6 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp index f51c670fc8..c47330620d 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.cpp @@ -185,7 +185,7 @@ namespace AZ if (lodCount > 0) { rule->AddLod(); - selection.CopyTo(rule->GetNodeSelectionList(index)); + selection.CopyTo(rule->GetNodeSelectionList(lodLevel)); } else { diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h index d152386940..c9416c0aa8 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace AZ { @@ -27,7 +28,7 @@ namespace AZ { class LodRule; - class LodRuleBehavior + class SCENE_DATA_CLASS LodRuleBehavior : public SceneCore::BehaviorComponent , public Events::ManifestMetaInfoBus::Handler , public Events::AssetImportRequestBus::Handler @@ -36,18 +37,19 @@ namespace AZ public: AZ_COMPONENT(LodRuleBehavior, "{D2E19864-9A4B-41FD-8ACC-DA6756728CB3}", SceneCore::BehaviorComponent); - ~LodRuleBehavior() override = default; + SCENE_DATA_API ~LodRuleBehavior() override = default; - void Activate() override; - void Deactivate() override; + SCENE_DATA_API void Activate() override; + SCENE_DATA_API void Deactivate() override; static void Reflect(ReflectContext* context); - void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override; - Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action, + SCENE_DATA_API void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override; + SCENE_DATA_API Events::ProcessingResult UpdateManifest( + Containers::Scene& scene, ManifestAction action, RequestingApplication requester) override; - void GetVirtualTypeName(AZStd::string& name, Crc32 type) override; - void GetAllVirtualTypes(AZStd::set& types) override; + SCENE_DATA_API void GetVirtualTypeName(AZStd::string& name, Crc32 type) override; + SCENE_DATA_API void GetAllVirtualTypes(AZStd::set& types) override; private: size_t SelectLodMeshes(const Containers::Scene& scene, DataTypes::ISceneNodeSelectionList& selection, size_t lodLevel) const; diff --git a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp index f893751caf..a6c624397a 100644 --- a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp +++ b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.cpp @@ -21,7 +21,6 @@ namespace AZ { const size_t LodRule::m_maxLods; - AZ_CLASS_ALLOCATOR_IMPL(LodRule, SystemAllocator, 0) SceneNodeSelectionList& LodRule::GetNodeSelectionList(size_t index) { diff --git a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h index 0d9bf0a9a6..fd7d6bacd8 100644 --- a/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h +++ b/Code/Tools/SceneAPI/SceneData/Rules/LodRule.h @@ -25,26 +25,26 @@ namespace AZ } namespace SceneData { - class LodRule + class SCENE_DATA_CLASS LodRule : public DataTypes::ILodRule { public: AZ_RTTI(LodRule, "{6E796AC8-1484-4909-860A-6D3F22A7346F}", DataTypes::ILodRule); - AZ_CLASS_ALLOCATOR_DECL + AZ_CLASS_ALLOCATOR(LodRule, AZ::SystemAllocator, 0) - ~LodRule() override = default; + SCENE_DATA_API ~LodRule() override = default; - SceneNodeSelectionList& GetNodeSelectionList(size_t index); + SCENE_DATA_API SceneNodeSelectionList& GetNodeSelectionList(size_t index); - DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) override; - const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) const override; - size_t GetLodCount() const override; + SCENE_DATA_API DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) override; + SCENE_DATA_API const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList(size_t index) const override; + SCENE_DATA_API size_t GetLodCount() const override; - void AddLod(); + SCENE_DATA_API void AddLod(); static void Reflect(ReflectContext* context); - //The engine supports 6 total lods. 1 for the base model then 5 more lods. - //The rule only captures lods past level 0 so this is set to 5. + //The engine supports 6 total lods. 1 for the base model then 5 more lods. + //The rule only captures lods past level 0 so this is set to 5. static const size_t m_maxLods = 5; protected: diff --git a/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake b/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake index 51f3dfc9e7..3a51180ca1 100644 --- a/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake +++ b/Code/Tools/SceneAPI/SceneData/SceneData_testing_files.cmake @@ -11,5 +11,6 @@ set(FILES Tests/GraphData/MeshDataTests.cpp Tests/GraphData/MeshDataPrimitiveUtilsTests.cpp Tests/GraphData/GraphDataBehaviorTests.cpp + Tests/GraphData/RulesTests.cpp Tests/SceneManifest/SceneManifestRuleTests.cpp ) diff --git a/Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp b/Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp new file mode 100644 index 0000000000..a6ccdfa59d --- /dev/null +++ b/Code/Tools/SceneAPI/SceneData/Tests/GraphData/RulesTests.cpp @@ -0,0 +1,78 @@ +/* + * 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 + +namespace AZ +{ + namespace SceneData + { + struct SoftNameMock + : SceneAPI::Events::GraphMetaInfoBus::Handler + { + SoftNameMock() + { + BusConnect(); + } + + ~SoftNameMock() override + { + BusDisconnect(); + } + + void GetVirtualTypes(AZStd::set& types, const SceneAPI::Containers::Scene&, SceneAPI::Containers::SceneGraph::NodeIndex) override + { + // Indicate this node is a LOD1 type + types.emplace(AZ_CRC_CE("LODMesh1")); + } + }; + + TEST(LOD, LODRuleTest) + { + // Test that UpdateManifest doesn't crash when trying to auto-add new LOD levels + SoftNameMock softNameMock; + + SceneAPI::SceneData::LodRuleBehavior lod; + SceneAPI::Containers::Scene scene("test"); + + auto lodRule = AZStd::shared_ptr(aznew SceneAPI::SceneData::LodRule()); + scene.GetManifest().AddEntry(lodRule); + + auto group = AZStd::shared_ptr(aznew SceneAPI::SceneData::MeshGroup()); + + // Add a bunch of other rules first + // This is necessary to replicate the bug condition where the index of the rule is used instead of the index of the LOD + for (int i = 0; i < 5; ++i) + { + auto tangentsRule = AZStd::shared_ptr(aznew SceneAPI::SceneData::TangentsRule()); + group->GetRuleContainer().AddRule(tangentsRule); + } + + group->GetRuleContainer().AddRule(lodRule); + scene.GetManifest().AddEntry(group); + + auto meshData = AZStd::shared_ptr(new GraphData::MeshData()); + scene.GetGraph().AddChild(scene.GetGraph().GetRoot(), "test", meshData); + + EXPECT_EQ(lodRule->GetLodCount(), 0); + + // This should auto-add 1 LOD because of the "test" node we added above along with the SoftNameMock which will report it as an LOD1 + lod.UpdateManifest(scene, SceneAPI::Events::AssetImportRequest::Update, SceneAPI::Events::AssetImportRequest::Generic); + + EXPECT_EQ(lodRule->GetLodCount(), 1); + } + } +} From 828431f185a39846bdad5630dcdf7c7d117ed931 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 1 Dec 2021 09:05:35 -0600 Subject: [PATCH 54/72] Update AssetManager unit tests to not interact with the disk (#5815) * Changed AssetManager tests to use memory streams for asset reading/writing Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fix compilation on non-unity builds Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Fixed handling of path lookups when test folder path is non-empty Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add more detailed error message for "asset is not loaded" Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Make numThreads a constexpr Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add FindFile function Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Remove unused lambda capture Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Remove trailing whitespace Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add size to assert Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- .../AzCore/AzCore/Asset/AssetCommon.h | 4 +- .../Tests/Asset/AssetManagerLoadingTests.cpp | 176 +++++------- .../Tests/Asset/BaseAssetManagerTest.cpp | 250 ++++++++++++++++++ .../AzCore/Tests/Asset/BaseAssetManagerTest.h | 66 ++++- Code/Framework/AzCore/Tests/TestCatalog.cpp | 8 +- 5 files changed, 393 insertions(+), 111 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h index c45bb21c6d..0b181f6782 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h @@ -325,13 +325,13 @@ namespace AZ T& operator*() const { - AZ_Assert(m_assetData, "Asset is not loaded"); + AZ_Assert(m_assetData, "Asset %s (%s) is not loaded", m_assetId.ToString().c_str(), m_assetHint.c_str()); return *Get(); } T* operator->() const { - AZ_Assert(m_assetData, "Asset is not loaded"); + AZ_Assert(m_assetData, "Asset %s (%s) is not loaded", m_assetId.ToString().c_str(), m_assetHint.c_str()); return Get(); } diff --git a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp index fe38451101..043eb1aee6 100644 --- a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp +++ b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -131,8 +132,8 @@ namespace UnitTest * This will test the aspect of the system where ObjectStreams and asset jobs loading dependent * assets will do the work in their own thread. */ - class AssetJobsFloodTest - : public BaseAssetManagerTest + + class AssetJobsFloodTest : public DisklessAssetManagerBase { public: TestAssetManager* m_testAssetManager{ nullptr }; @@ -183,15 +184,14 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); SetupTest(); } void TearDown() override { - TearDownTest(); AssetManager::Destroy(); - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } void SetupAssets() @@ -257,9 +257,9 @@ namespace UnitTest AssetWithSerializedData ap2; AssetWithSerializedData ap3; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, m_serializeContext)); AssetWithAssetReference assetWithPreload1; AssetWithAssetReference assetWithPreload2; @@ -273,11 +273,11 @@ namespace UnitTest noLoadAsset.m_asset = m_testAssetManager->CreateAsset(MyAsset2Id, AssetLoadBehavior::NoLoad); EXPECT_EQ(m_assetHandlerAndCatalog->m_numCreations, 4); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DelayLoadAsset.txt", AZ::DataStream::ST_XML, &delayedAsset, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "NoLoadAsset.txt", AZ::DataStream::ST_XML, &noLoadAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DelayLoadAsset.txt", &delayedAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("NoLoadAsset.txt", &noLoadAsset, m_serializeContext)); AssetWithQueueAndPreLoadReferences preLoadRoot; AssetWithQueueAndPreLoadReferences preLoadA; @@ -297,16 +297,16 @@ namespace UnitTest preLoadBrokenA.m_preLoad = m_testAssetManager->CreateAsset(PreloadBrokenDepBId, AssetLoadBehavior::PreLoad); preLoadBrokenB.m_preLoad = m_testAssetManager->CreateAsset(PreloadAssetNoDataId, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadRoot.txt", AZ::DataStream::ST_XML, &preLoadRoot, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadA.txt", AZ::DataStream::ST_XML, &preLoadA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadB.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadC.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadA.txt", AZ::DataStream::ST_XML, &queueLoadA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadB.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "QueueLoadC.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadBrokenA.txt", AZ::DataStream::ST_XML, &preLoadBrokenA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadBrokenB.txt", AZ::DataStream::ST_XML, &preLoadBrokenB, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "PreLoadNoData.txt", AZ::DataStream::ST_XML, &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadRoot.txt", &preLoadRoot, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadA.txt", &preLoadA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadB.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadC.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadA.txt", &queueLoadA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadB.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("QueueLoadC.txt", &noRefs, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadBrokenA.txt", &preLoadBrokenA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadBrokenB.txt", &preLoadBrokenB, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("PreLoadNoData.txt", &noRefs, m_serializeContext)); AssetWithQueueAndPreLoadReferences circularA; AssetWithQueueAndPreLoadReferences circularB; @@ -318,43 +318,15 @@ namespace UnitTest circularC.m_preLoad = m_testAssetManager->CreateAsset(CircularBId, AssetLoadBehavior::PreLoad); circularD.m_preLoad = circularC.m_preLoad; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularA.txt", AZ::DataStream::ST_XML, &circularA, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularB.txt", AZ::DataStream::ST_XML, &circularB, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularC.txt", AZ::DataStream::ST_XML, &circularC, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "CircularD.txt", AZ::DataStream::ST_XML, &circularD, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularA.txt", &circularA, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularB.txt", &circularB, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularC.txt", &circularC, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("CircularD.txt", &circularD, m_serializeContext)); + m_assetHandlerAndCatalog->m_numCreations = 0; } } - void TearDownTest() - { - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset4.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset5.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset6.txt"); - - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset1.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset2.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "TestAsset3.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "DelayLoadAsset.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "NoLoadAsset.txt"); - - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadRoot.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadC.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "QueueLoadC.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadBrokenA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadBrokenB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "PreLoadNoData.txt"); - - DeleteAssetFromDisk(GetTestFolderPath() + "CircularA.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "CircularB.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "CircularC.txt"); - DeleteAssetFromDisk(GetTestFolderPath() + "CircularD.txt"); - } - void CheckFinishedCreationsAndDestructions() { // Make sure asset jobs have finished before validating the number of destroyed assets, because it's possible that the asset job @@ -367,7 +339,7 @@ namespace UnitTest }; static constexpr AZStd::chrono::seconds MaxDispatchTimeoutSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds * 12; - + template bool DispatchEventsUntilCondition(AZ::Data::AssetManager& assetManager, Pred&& conditionPredicate, AZStd::chrono::seconds logIntervalSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds, @@ -608,7 +580,7 @@ namespace UnitTest AZ::Data::AssetData::AssetStatus expected_base_status = AZ::Data::AssetData::AssetStatus::Ready; EXPECT_EQ(baseStatus, expected_base_status); } - + TEST_F(AssetJobsFloodTest, RapidAcquireAndRelease) { auto assetUuids = { @@ -641,7 +613,7 @@ namespace UnitTest { Asset asset1 = m_testAssetManager->GetAsset(assetUuid, azrtti_typeid(), AZ::Data::AssetLoadBehavior::PreLoad); - + if (checkLoaded) { asset1.BlockUntilLoadComplete(); @@ -714,8 +686,8 @@ namespace UnitTest AssetWithSerializedData ap; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "a.txt", AZ::DataStream::ST_XML, &ap, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "b.txt", AZ::DataStream::ST_XML, &ap, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("a.txt", &ap, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("b.txt", &ap, m_serializeContext)); } auto& assetManager = AssetManager::Instance(); @@ -778,7 +750,7 @@ namespace UnitTest * Verify that loads without using the Asset Container still work correctly */ class AssetContainerDisableTest - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { public: static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" }; @@ -797,7 +769,7 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); SetupTest(); } @@ -807,7 +779,7 @@ namespace UnitTest AssetManager::Instance().UnregisterHandler(m_assetHandlerAndCatalog); delete m_assetHandlerAndCatalog; AssetManager::Destroy(); - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } void SetupAssets() @@ -849,9 +821,9 @@ namespace UnitTest AssetWithSerializedData ap2; AssetWithSerializedData ap3; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, m_serializeContext)); AssetWithAssetReference assetWithPreload1; AssetWithAssetReference assetWithPreload2; @@ -862,9 +834,9 @@ namespace UnitTest assetWithPreload3.m_asset = m_testAssetManager->CreateAsset(MyAsset6Id, AssetLoadBehavior::PreLoad); EXPECT_EQ(m_assetHandlerAndCatalog->m_numCreations, 3); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, m_serializeContext)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, m_serializeContext)); m_assetHandlerAndCatalog->m_numCreations = 0; } @@ -2014,11 +1986,12 @@ namespace UnitTest CheckFinishedCreationsAndDestructions(); m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusDisconnect(); } + /** * Run multiple threads that get and release assets simultaneously to test AssetManager's thread safety */ class AssetJobsMultithreadedTest - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { public: static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" }; @@ -2028,6 +2001,7 @@ namespace UnitTest static inline const AZ::Uuid MyAsset5Id{ "{D9CDAB04-D206-431E-BDC0-1DD615D56197}" }; static inline const AZ::Uuid MyAsset6Id{ "{B2F139C3-5032-4B52-ADCA-D52A8F88E043}" }; + // Initialize the Job Manager with 2 threads for the Asset Manager to use. size_t GetNumJobManagerThreads() const override { return 2; } @@ -2078,9 +2052,9 @@ namespace UnitTest AssetWithSerializedData ap2; AssetWithSerializedData ap3; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &ap1, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &ap2, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &ap3, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &ap1, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &ap2, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &ap3, &context)); AssetWithAssetReference assetWithPreload1; AssetWithAssetReference assetWithPreload2; @@ -2089,9 +2063,9 @@ namespace UnitTest assetWithPreload2.m_asset = AssetManager::Instance().CreateAsset(MyAsset5Id, AssetLoadBehavior::PreLoad); assetWithPreload3.m_asset = AssetManager::Instance().CreateAsset(MyAsset6Id, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &assetWithPreload1, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &assetWithPreload2, &context)); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &assetWithPreload3, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &assetWithPreload1, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &assetWithPreload2, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &assetWithPreload3, &context)); EXPECT_TRUE(assetHandlerAndCatalog->m_numCreations == 3); assetHandlerAndCatalog->m_numCreations = 0; @@ -2191,22 +2165,22 @@ namespace UnitTest // A will be saved to disk with MyAsset1Id AssetWithAssetReference a; a.m_asset = AssetManager::Instance().CreateAsset(MyAsset2Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &a, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &a, &context)); AssetWithAssetReference b; b.m_asset = AssetManager::Instance().CreateAsset(MyAsset3Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &b, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &b, &context)); AssetWithAssetReference c; c.m_asset = AssetManager::Instance().CreateAsset(MyAsset4Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &c, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &c, &context)); AssetWithAssetReference d; d.m_asset = AssetManager::Instance().CreateAsset(MyAsset5Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &d, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &d, &context)); AssetWithAssetReference e; e.m_asset = AssetManager::Instance().CreateAsset(MyAsset6Id); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset5.txt", AZ::DataStream::ST_XML, &e, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset5.txt", &e, &context)); AssetWithAssetReference f; f.m_asset = AssetManager::Instance().CreateAsset(MyAsset1Id); // refer back to asset1 - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset6.txt", AZ::DataStream::ST_XML, &f, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset6.txt", &f, &context)); EXPECT_TRUE(assetHandlerAndCatalog->m_numCreations == 6); assetHandlerAndCatalog->m_numCreations = 0; @@ -2347,26 +2321,26 @@ namespace UnitTest // AssetD is MYASSETD AssetWithSerializedData d; d.m_data = 42; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset4.txt", AZ::DataStream::ST_XML, &d, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset4.txt", &d, &context)); // AssetC is MYASSETC AssetWithAssetReference c; c.m_asset = db.CreateAsset(AssetId(MyAssetDId)); // point at D - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset3.txt", AZ::DataStream::ST_XML, &c, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset3.txt", &c, &context)); // AssetB is MYASSETB AssetWithAssetReference b; b.m_asset = db.CreateAsset(AssetId(MyAssetCId)); // point at C - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset2.txt", AZ::DataStream::ST_XML, &b, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset2.txt", &b, &context)); // AssetA will be written to disk as MYASSETA AssetWithAssetReference a; a.m_asset = db.CreateAsset(AssetId(MyAssetBId)); // point at B - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "TestAsset1.txt", AZ::DataStream::ST_XML, &a, &context)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("TestAsset1.txt", &a, &context)); } - const size_t numThreads = 4; - AZStd::atomic_int threadCount(numThreads); + constexpr size_t NumThreads = 4; + AZStd::atomic_int threadCount(NumThreads); AZStd::condition_variable cv; AZStd::vector threads; AZStd::atomic_bool keepDispatching(true); @@ -2381,7 +2355,7 @@ namespace UnitTest AZStd::thread dispatchThread(dispatch); - for (size_t threadIdx = 0; threadIdx < numThreads; ++threadIdx) + for (size_t threadIdx = 0; threadIdx < NumThreads; ++threadIdx) { threads.emplace_back([&threadCount, &db, &cv]() { @@ -2569,7 +2543,6 @@ namespace UnitTest #if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS TEST_F(AssetJobsMultithreadedTest, DISABLED_ParallelDeepAssetReferences) #else - // temporarily disabled until sporadic failures can be root caused TEST_F(AssetJobsMultithreadedTest, ParallelDeepAssetReferences) #endif // AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS { @@ -2577,7 +2550,7 @@ namespace UnitTest } class AssetManagerTests - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { protected: static inline const AZ::Uuid MyAsset1Id{ "{5B29FE2B-6B41-48C9-826A-C723951B0560}" }; @@ -2592,7 +2565,7 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); m_console = AZStd::make_unique(); AZ::Interface::Register(m_console.get()); @@ -2631,7 +2604,7 @@ namespace UnitTest AssetManager::Destroy(); AZ::Interface::Unregister(m_console.get()); m_console = nullptr; - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } }; @@ -2982,7 +2955,7 @@ namespace UnitTest * the middle of loading. The tests help ensure that assets can't get stuck in perpetual loading states. **/ class AssetManagerClearAssetReferenceTests - : public BaseAssetManagerTest + : public DisklessAssetManagerBase { protected: static inline const AZ::Uuid RootAssetId{ "{AB13F568-C676-41FE-A7E9-341F71A78104}" }; @@ -3001,7 +2974,7 @@ namespace UnitTest void SetUp() override { - BaseAssetManagerTest::SetUp(); + DisklessAssetManagerBase::SetUp(); // create the database AssetManager::Descriptor desc; @@ -3039,21 +3012,18 @@ namespace UnitTest // Create and save the dependent asset first, so that we can get a reference to it. AssetWithSerializedData dependentBlockingAsset; - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DependentPreloadBlockingAsset.txt", - AZ::DataStream::ST_XML, &dependentBlockingAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DependentPreloadBlockingAsset.txt", &dependentBlockingAsset, m_serializeContext)); AssetWithAssetReference dependentAsset; dependentAsset.m_asset = AssetManager::Instance().CreateAsset( NestedDependentPreloadBlockingAssetId, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "DependentPreloadAsset.txt", - AZ::DataStream::ST_XML, &dependentAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("DependentPreloadAsset.txt", &dependentAsset, m_serializeContext)); // Create and save the top-level asset. AssetWithAssetReference rootAsset; rootAsset.m_asset = AssetManager::Instance().CreateAsset( DependentPreloadAssetId, AssetLoadBehavior::PreLoad); - EXPECT_TRUE(AZ::Utils::SaveObjectToFile(GetTestFolderPath() + "RootAsset.txt", - AZ::DataStream::ST_XML, &rootAsset, m_serializeContext)); + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile("RootAsset.txt", &rootAsset, m_serializeContext)); } void TearDown() override @@ -3065,7 +3035,7 @@ namespace UnitTest delete m_assetHandlerAndCatalog; AssetManager::Destroy(); - BaseAssetManagerTest::TearDown(); + DisklessAssetManagerBase::TearDown(); } }; diff --git a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp index c6fa296cbc..532cb0a1d8 100644 --- a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp +++ b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.cpp @@ -165,4 +165,254 @@ namespace UnitTest EXPECT_FALSE(AssetManager::Instance().HasActiveJobsOrStreamerRequests()); } + + MemoryStreamerWrapper::MemoryStreamerWrapper() + { + using ::testing::_; + using ::testing::NiceMock; + using ::testing::Return; + + ON_CALL(m_mockStreamer, SuspendProcessing()).WillByDefault([this]() + { + m_suspended = true; + }); + + ON_CALL(m_mockStreamer, ResumeProcessing()).WillByDefault([this]() + { + AZStd::unique_lock lock(m_mutex); + + m_suspended = false; + + while (!m_processingQueue.empty()) + { + FileRequestHandle requestHandle = m_processingQueue.front(); + m_processingQueue.pop(); + + const auto& onCompleteCallback = GetReadRequest(requestHandle)->m_callback; + + if (onCompleteCallback) + { + onCompleteCallback(requestHandle); + } + } + }); + + ON_CALL(m_mockStreamer, Read(_, ::testing::An(), _, _, _, _)) + .WillByDefault( + [this]( + [[maybe_unused]] AZStd::string_view relativePath, IStreamerTypes::RequestMemoryAllocator& allocator, size_t size, + AZStd::chrono::microseconds deadline, IStreamerTypes::Priority priority, [[maybe_unused]] size_t offset) + { + AZStd::unique_lock lock(m_mutex); + + ReadRequest request; + + // Save off the requested deadline and priority + request.m_deadline = deadline; + request.m_priority = priority; + request.m_data = allocator.Allocate(size, size, 8); + + const auto* virtualFile = FindFile(relativePath); + + AZ_Assert( + virtualFile->size() == size, "Streamer read request size did not match size of saved file: %d vs %d (%.*s)", + virtualFile->size(), size, + relativePath.size(), relativePath.data()); + AZ_Assert(size > 0, "Size is zero %.*s", relativePath.size(), relativePath.data()); + + memcpy(request.m_data.m_address, virtualFile->data(), size); + + // Create a real file request result and return it + request.m_request = m_context.GetNewExternalRequest(); + + m_readRequests.push_back(request); + + return request.m_request; + }); + + ON_CALL(m_mockStreamer, SetRequestCompleteCallback(_, _)) + .WillByDefault([this](FileRequestPtr& request, AZ::IO::IStreamer::OnCompleteCallback callback) -> FileRequestPtr& + { + // Save off the callback just so that we can call it when the request is "done" + AZStd::unique_lock lock(m_mutex); + ReadRequest* readRequest = GetReadRequest(request); + readRequest->m_callback = callback; + + return request; + }); + + ON_CALL(m_mockStreamer, QueueRequest(_)) + .WillByDefault([this](const auto& fileRequest) + { + if (!m_suspended) + { + decltype(ReadRequest::m_callback) onCompleteCallback; + + AZStd::unique_lock lock(m_mutex); + ReadRequest* readRequest = GetReadRequest(fileRequest); + onCompleteCallback = readRequest->m_callback; + + if (onCompleteCallback) + { + onCompleteCallback(fileRequest); + + m_readRequests.erase(readRequest); + } + } + else + { + AZStd::unique_lock lock(m_mutex); + + m_processingQueue.push(fileRequest); + } + }); + + ON_CALL(m_mockStreamer, GetRequestStatus(_)) + .WillByDefault([]([[maybe_unused]] FileRequestHandle request) + { + // Return whatever request status has been set in this class + return IO::IStreamerTypes::RequestStatus::Completed; + }); + + ON_CALL(m_mockStreamer, GetReadRequestResult(_, _, _, _)) + .WillByDefault([this]( + [[maybe_unused]] FileRequestHandle request, void*& buffer, AZ::u64& numBytesRead, + IStreamerTypes::ClaimMemory claimMemory) + { + // Make sure the requestor plans to free the data buffer we allocated. + EXPECT_EQ(claimMemory, IStreamerTypes::ClaimMemory::Yes); + + AZStd::unique_lock lock(m_mutex); + + ReadRequest* readRequest = GetReadRequest(request); + + // Provide valid data buffer results. + numBytesRead = readRequest->m_data.m_size; + buffer = readRequest->m_data.m_address; + + return true; + }); + + ON_CALL(m_mockStreamer, RescheduleRequest(_, _, _)) + .WillByDefault([this](IO::FileRequestPtr target, AZStd::chrono::microseconds newDeadline, IO::IStreamerTypes::Priority newPriority) + { + AZStd::unique_lock lock(m_mutex); + ReadRequest* readRequest = GetReadRequest(target); + + readRequest->m_deadline = newDeadline; + readRequest->m_priority = newPriority; + + return target; + }); + } + + ReadRequest* MemoryStreamerWrapper::GetReadRequest(FileRequestHandle request) + { + auto itr = AZStd::find_if( + m_readRequests.begin(), m_readRequests.end(), + [request](const ReadRequest& searchItem) -> bool + { + return (searchItem.m_request == request); + }); + + return itr; + } + + AZStd::vector* MemoryStreamerWrapper::FindFile(AZStd::string_view path) + { + auto itr = m_virtualFiles.find(path); + + if (itr == m_virtualFiles.end()) + { + // Path didn't work as-is, does it have the test folder prefixed? If so try removing it + if (AZ::StringFunc::StartsWith(path, GetTestFolderPath())) + { + AZStd::string_view pathWithoutFolder = path; + + pathWithoutFolder = AZ::StringFunc::LStrip(pathWithoutFolder, GetTestFolderPath().c_str()); + itr = m_virtualFiles.find(pathWithoutFolder); + } + else // Path isn't prefixed, so try adding it + { + itr = m_virtualFiles.find(GetTestFolderPath().append(path)); + } + } + + if (itr != m_virtualFiles.end()) + { + return &itr->second; + } + + // Currently no test expects a file not to exist so we assert to make it easy to quickly find where something went wrong + // If we ever need to test for a non-existent file this assert should just be conditionally disabled for that specific test + AZ_Assert(false, "Failed to find virtual file %*.s", path.size(), path.data()) + + return nullptr; + } + + void DisklessAssetManagerBase::SetUp() + { + using ::testing::_; + using ::testing::NiceMock; + using ::testing::Return; + + BaseAssetManagerTest::SetUp(); + + ON_CALL(m_fileIO, Size(::testing::Matcher(::testing::_), _)) + .WillByDefault( + [this](const char* path, u64& size) + { + AZStd::scoped_lock lock(m_streamerWrapper->m_mutex); + + const auto* file = m_streamerWrapper->FindFile(path); + + if (file) + { + size = file->size(); + return ResultCode::Success; + } + + AZ_Error("DisklessAssetManagerBase", false, "Failed to find virtual file %.*s", path); + + return ResultCode::Error; + }); + + m_prevFileIO = IO::FileIOBase::GetInstance(); + IO::FileIOBase::SetInstance(nullptr); + IO::FileIOBase::SetInstance(&m_fileIO); + } + + void DisklessAssetManagerBase::TearDown() + { + IO::FileIOBase::SetInstance(nullptr); + IO::FileIOBase::SetInstance(m_prevFileIO); + + BaseAssetManagerTest::TearDown(); + } + + IO::IStreamer* DisklessAssetManagerBase::CreateStreamer() + { + m_streamerWrapper = AZStd::make_unique(); + + return &(m_streamerWrapper->m_mockStreamer); + } + + void DisklessAssetManagerBase::DestroyStreamer(IO::IStreamer*) + { + m_streamerWrapper = nullptr; + } + + void DisklessAssetManagerBase::WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string&) + { + AZStd::string assetFileName = GetTestFolderPath() + assetName; + + AssetWithCustomData asset; + + EXPECT_TRUE(m_streamerWrapper->WriteMemoryFile(assetFileName, &asset, m_serializeContext)); + } + + void DisklessAssetManagerBase::DeleteAssetFromDisk(const AZStd::string&) + { + + } } diff --git a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h index 29c2c124cd..af48c74a60 100644 --- a/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h +++ b/Code/Framework/AzCore/Tests/Asset/BaseAssetManagerTest.h @@ -20,7 +20,8 @@ #include #include #include - +#include +#include namespace UnitTest { @@ -58,7 +59,11 @@ namespace UnitTest // Subclasses can optionally override the streamer creation and destruction virtual IO::IStreamer* CreateStreamer() { return aznew IO::Streamer(AZStd::thread_desc{}, StreamerComponent::CreateStreamerStack()); } - virtual void DestroyStreamer(IO::IStreamer* streamer) { delete streamer; } + virtual void DestroyStreamer(IO::IStreamer* streamer) + { + delete streamer; + streamer = nullptr; + } void SetUp() override; void TearDown() override; @@ -66,8 +71,8 @@ namespace UnitTest static void SuppressTraceOutput(bool suppress); // Helper methods to create and destroy actual assets on the disk for true end-to-end asset loading. - void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid); - void DeleteAssetFromDisk(const AZStd::string& assetName); + virtual void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid); + virtual void DeleteAssetFromDisk(const AZStd::string& assetName); void BlockUntilAssetJobsAreComplete(); @@ -82,4 +87,57 @@ namespace UnitTest AZStd::vector m_assetsWritten; }; + + struct ReadRequest + { + AZStd::chrono::milliseconds m_deadline{}; + AZ::IO::IStreamerTypes::Priority m_priority{}; + IO::IStreamerTypes::RequestMemoryAllocatorResult m_data{ nullptr, 0, IO::IStreamerTypes::MemoryType::ReadWrite }; + AZ::IO::IStreamer::OnCompleteCallback m_callback; + IO::FileRequestPtr m_request; + }; + + struct MemoryStreamerWrapper + { + MemoryStreamerWrapper(); + ~MemoryStreamerWrapper() = default; + + ReadRequest* GetReadRequest(IO::FileRequestHandle request); + + template + bool WriteMemoryFile(const AZStd::string& filePath, TObject* object, AZ::SerializeContext* context) + { + auto& buffer = m_virtualFiles[filePath]; + ByteContainerStream stream(&buffer); + + return AZ::Utils::SaveObjectToStream(stream, DataStream::StreamType::ST_XML, object, context); + } + + AZStd::vector* FindFile(AZStd::string_view path); + + ::testing::NiceMock m_mockStreamer; + IO::StreamerContext m_context; + AZStd::atomic_bool m_suspended{ false }; + + AZStd::recursive_mutex m_mutex; + AZStd::queue m_processingQueue; // Keeps tracks of requests that have been queued while processing is suspended + AZStd::vector m_readRequests; + AZStd::unordered_map> m_virtualFiles; + }; + + struct DisklessAssetManagerBase : BaseAssetManagerTest + { + void SetUp() override; + void TearDown() override; + IO::IStreamer* CreateStreamer() override; + void DestroyStreamer(IO::IStreamer*) override; + + void WriteAssetToDisk(const AZStd::string& assetName, const AZStd::string& assetIdGuid) override; + void DeleteAssetFromDisk(const AZStd::string& assetName) override; + + AZStd::unique_ptr m_streamerWrapper; + ::testing::NiceMock m_fileIO; + IO::FileIOBase* m_prevFileIO{}; + }; + } diff --git a/Code/Framework/AzCore/Tests/TestCatalog.cpp b/Code/Framework/AzCore/Tests/TestCatalog.cpp index c633c6391b..cb8fa11c72 100644 --- a/Code/Framework/AzCore/Tests/TestCatalog.cpp +++ b/Code/Framework/AzCore/Tests/TestCatalog.cpp @@ -167,7 +167,8 @@ namespace UnitTest if (!info.m_streamName.empty()) { AZStd::string fullName = GetTestFolderPath() + info.m_streamName; - info.m_dataLen = static_cast(IO::SystemFile::Length(fullName.c_str())); + IO::FileIOBase* io = IO::FileIOBase::GetInstance(); + io->Size(fullName.c_str(), info.m_dataLen); } else { @@ -187,8 +188,11 @@ namespace UnitTest if (!info.m_streamName.empty()) { + IO::FileIOBase* io = AZ::IO::FileIOBase::GetInstance(); + AZStd::string fullName = GetTestFolderPath() + info.m_streamName; - info.m_dataLen = static_cast(IO::SystemFile::Length(fullName.c_str())); + + io->Size(fullName.c_str(), info.m_dataLen); } else { From 57d688fbc1dcd51d9dce146c70457bb5c5c8acb3 Mon Sep 17 00:00:00 2001 From: AMZN-nggieber <52797929+AMZN-nggieber@users.noreply.github.com> Date: Wed, 1 Dec 2021 08:03:36 -0800 Subject: [PATCH 55/72] Added Tests for Gem Catalog Filtering (#5999) * Added Tests for Gem Catalog Filtering Signed-off-by: nggieber <52797929+AMZN-nggieber@users.noreply.github.com> * Addressed PR feedback, Renamed all tests to Osherove naming pattern Signed-off-by: nggieber <52797929+AMZN-nggieber@users.noreply.github.com> --- Code/Tools/ProjectManager/CMakeLists.txt | 1 + .../Source/GemCatalog/GemInfo.h | 4 +- .../ProjectManager/tests/GemCatalogTests.cpp | 543 +++++++++++++++++- 3 files changed, 529 insertions(+), 19 deletions(-) diff --git a/Code/Tools/ProjectManager/CMakeLists.txt b/Code/Tools/ProjectManager/CMakeLists.txt index a47ccb62c9..9974125ffb 100644 --- a/Code/Tools/ProjectManager/CMakeLists.txt +++ b/Code/Tools/ProjectManager/CMakeLists.txt @@ -92,6 +92,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) AZ::AzTest AZ::AzFramework AZ::AzFrameworkTestShared + AZ::AzQtComponents AZ::ProjectManager.Static ) diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h index 5c1bc90c6e..23e95cf487 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h @@ -73,10 +73,10 @@ namespace O3DE::ProjectManager QString m_path; QString m_name = "Unknown Gem Name"; - QString m_displayName = "Unknown Gem Name"; + QString m_displayName; QString m_creator = "Unknown Creator"; GemOrigin m_gemOrigin = Local; - bool m_isAdded = false; //! Is the gem currently added and enabled in the project? + bool m_isAdded = false; //! Is the gem explicitly added (not a dependency) and enabled in the project? QString m_summary = "No summary provided."; Platforms m_platforms; Types m_types; //! Asset and/or Code and/or Tool diff --git a/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp b/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp index f5c6d5196a..701a1ddcef 100644 --- a/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp +++ b/Code/Tools/ProjectManager/tests/GemCatalogTests.cpp @@ -8,8 +8,8 @@ #include #include -#include +#include namespace O3DE::ProjectManager { @@ -17,14 +17,22 @@ namespace O3DE::ProjectManager : public ::UnitTest::ScopedAllocatorSetupFixture { public: + void SetUp() override + { + m_gemModel.reset(new GemModel()); + } - GemCatalogTests() = default; + void TearDown() override + { + m_gemModel.release(); + } + + protected: + AZStd::unique_ptr m_gemModel; }; - TEST_F(GemCatalogTests, GemCatalog_Displays_But_Does_Not_Add_Dependencies) + TEST_F(GemCatalogTests, GemCatalog_GemWithDependencies_DisplaysButDoesNotAddDependencies) { - GemModel* gemModel = new GemModel(); - // given 3 gems a,b,c where a depends on b which depends on c GemInfo gemA, gemB, gemC; QModelIndex indexA, indexB, indexC; @@ -35,30 +43,531 @@ namespace O3DE::ProjectManager gemA.m_dependencies = QStringList({ "b" }); gemB.m_dependencies = QStringList({ "c" }); - gemModel->AddGem(gemA); - indexA = gemModel->FindIndexByNameString(gemA.m_name); + indexA = m_gemModel->AddGem(gemA); + indexB = m_gemModel->AddGem(gemB); + indexC = m_gemModel->AddGem(gemC); - gemModel->AddGem(gemB); - indexB = gemModel->FindIndexByNameString(gemB.m_name); - - gemModel->AddGem(gemC); - indexC = gemModel->FindIndexByNameString(gemC.m_name); - - gemModel->UpdateGemDependencies(); + m_gemModel->UpdateGemDependencies(); EXPECT_FALSE(GemModel::IsAdded(indexA)); EXPECT_FALSE(GemModel::IsAddedDependency(indexB) || GemModel::IsAddedDependency(indexC)); // when a is added - GemModel::SetIsAdded(*gemModel, indexA, true); + GemModel::SetIsAdded(*m_gemModel, indexA, true); // expect b and c are now dependencies of an added gem but not themselves added // cmake will handle dependencies EXPECT_TRUE(GemModel::IsAddedDependency(indexB) && GemModel::IsAddedDependency(indexC)); - EXPECT_TRUE(!GemModel::IsAdded(indexB) && !GemModel::IsAdded(indexC)); + EXPECT_FALSE(GemModel::IsAdded(indexB) || GemModel::IsAdded(indexC)); - QVector gemsToAdd = gemModel->GatherGemsToBeAdded(); + const QVector& gemsToAdd = m_gemModel->GatherGemsToBeAdded(); EXPECT_TRUE(gemsToAdd.size() == 1); EXPECT_EQ(GemModel::GetName(gemsToAdd.at(0)), gemA.m_name); } + + class GemCatalogFilterTests + : public GemCatalogTests + { + public: + void SetUp() override + { + GemCatalogTests::SetUp(); + m_proxyModel.reset(new GemSortFilterProxyModel(m_gemModel.get())); + } + + void TearDown() override + { + m_proxyModel.release(); + GemCatalogTests::TearDown(); + } + + protected: + AZStd::unique_ptr m_proxyModel; + }; + + class GemCatalogSearchFilterTests + : public GemCatalogFilterTests + { + public: + void SetUp() override + { + GemCatalogFilterTests::SetUp(); + + GemInfo gemfilterName, gemfilterDisplayName, gemfilterCreator, gemfilterSummary, gemfilterFeature; + + gemfilterName.m_name = "Name"; + gemfilterDisplayName.m_name = "D"; + gemfilterCreator.m_name = "C"; + gemfilterSummary.m_name = "S"; + gemfilterFeature.m_name = "F"; + + gemfilterDisplayName.m_displayName = "Display Name"; + gemfilterCreator.m_creator = "Johnathon Doe"; + gemfilterSummary.m_summary = "Unique Summary"; + gemfilterFeature.m_features.append("Creative Feature"); + + m_gemRows.append(m_gemModel->AddGem(gemfilterName).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterDisplayName).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterCreator).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterSummary).row()); + m_gemRows.append(m_gemModel->AddGem(gemfilterFeature).row()); + } + + protected: + enum RowOrder + { + Name, + DisplayName, + Creator, + Summary, + Features + }; + + QVector m_gemRows; + }; + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringName_ShowsNameGems) + { + m_proxyModel->SetSearchString("Name"); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringDisplayName_ShowsDisplayNameGem) + { + m_proxyModel->SetSearchString("Display Name"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringCreator_ShowsCreatorGem) + { + m_proxyModel->SetSearchString("Johnathon Doe"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringSummary_ShowsSummaryGem) + { + m_proxyModel->SetSearchString("Unique Summary"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringFeatures_ShowsFeatureGem) + { + m_proxyModel->SetSearchString("Creative"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringEmpty_ShowsAll) + { + m_proxyModel->SetSearchString(""); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringCommonCharacter_ShowsAll) + { + // All gems contain "a" in a searchable field so all should be shown + m_proxyModel->SetSearchString("a"); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringDifferentCaseCommonCharacter_ShowsAll) + { + // No gems contain the character "A" but search should be case insensitive + m_proxyModel->SetSearchString("A"); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringNoneContainCharacter_ShowsNone) + { + // No gems contain the character "z" or "Z" so none should be shown + m_proxyModel->SetSearchString("z"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + TEST_F(GemCatalogSearchFilterTests, GemCatalogFilters_SearchStringPartialMatchString_ShowsNone) + { + // Token matching is currently not supported + // The whole string must match a substring + m_proxyModel->SetSearchString("Name Token"); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Name], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DisplayName], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Creator], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Summary], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[Features], QModelIndex())); + } + + class GemCatalogSelectedActiveFilterTests + : public GemCatalogFilterTests + { + public: + void SetUp() override + { + GemCatalogFilterTests::SetUp(); + + GemInfo gemSelected, gemSelectedDep, gemUnselected, gemUnselectedDep, gemActive, gemInactive; + + gemSelected.m_name = "selected"; + gemSelectedDep.m_name = "selectedDep"; + gemUnselected.m_name = "unselected"; + gemUnselectedDep.m_name = "unselectedDep"; + gemActive.m_name = "active"; + gemInactive.m_name = "inactive"; + + gemSelected.m_dependencies = QStringList({ "selectedDep" }); + gemUnselected.m_dependencies = QStringList({ "unselectedDep" }); + + m_gemIndices.append(m_gemModel->AddGem(gemSelected)); + m_gemIndices.append(m_gemModel->AddGem(gemSelectedDep)); + m_gemIndices.append(m_gemModel->AddGem(gemUnselected)); + m_gemIndices.append(m_gemModel->AddGem(gemUnselectedDep)); + m_gemIndices.append(m_gemModel->AddGem(gemActive)); + m_gemIndices.append(m_gemModel->AddGem(gemInactive)); + + m_gemModel->UpdateGemDependencies(); + + // Set intial state of catalog with the to be unselected gem currently added along with active gem + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Unselected], true); + GemModel::SetWasPreviouslyAdded(*m_gemModel, m_gemIndices[Unselected], true); + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Active], true); + GemModel::SetWasPreviouslyAdded(*m_gemModel, m_gemIndices[Active], true); + + // Add selected gem and remove unselected gem + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Selected], true); + GemModel::SetIsAdded(*m_gemModel, m_gemIndices[Unselected], false); + } + + protected: + enum IndexOrder + { + Selected, + SelectedDep, + Unselected, + UnselectedDep, + Active, + Inactive + }; + + QVector m_gemIndices; + }; + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_SelectedActiveIntialState_AddedGemsAndDependenciesAreAdded) + { + // Check if gems are all in expected state + // if this test fails all other Selected/Active tests are invalid + EXPECT_TRUE(GemModel::IsAdded(m_gemIndices[Selected])); + EXPECT_TRUE(GemModel::IsAddedDependency(m_gemIndices[SelectedDep])); + EXPECT_FALSE(GemModel::IsAdded(m_gemIndices[Unselected])); + EXPECT_FALSE(GemModel::IsAddedDependency(m_gemIndices[UnselectedDep])); + EXPECT_TRUE(GemModel::IsAdded(m_gemIndices[Active])); + EXPECT_FALSE(GemModel::IsAdded(m_gemIndices[Inactive])); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_SelectedActiveNoFilter_ShowsAll) + { + // Filter is clear + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterSelected_ShowsSelectedAndDependencies) + { + // Check selected filter + // Selected dependencies should also be shown + m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Selected); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterUnselected_ShowsUnselectedAndDependencies) + { + // Check unselected filter + // Unselected dependencies should also be shown + m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Unselected); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterSelectedAndUnselected_ShowsAllChangesAndDependencies) + { + // Check both un/selected filter + m_proxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Both); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterActive_ShowsActive) + { + // Check active filter + // Active dependencies should also be shown + m_proxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Active); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + TEST_F(GemCatalogSelectedActiveFilterTests, GemCatalogFilters_FilterActive_ShowsInactive) + { + // Check inactive filter + m_proxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Inactive); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Selected].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[SelectedDep].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Unselected].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[UnselectedDep].row(), QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemIndices[Active].row(), QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemIndices[Inactive].row(), QModelIndex())); + } + + class GemCatalogMiscFilterTests + : public GemCatalogFilterTests + { + public: + void SetUp() override + { + GemCatalogFilterTests::SetUp(); + + GemInfo gemA, gemB, gemC; + + gemA.m_name = "Default Audio"; + gemB.m_name = "Mobile UX"; + gemC.m_name = "City Props"; + + gemA.m_gemOrigin = GemInfo::GemOrigin::Open3DEngine; + gemB.m_gemOrigin = GemInfo::GemOrigin::Local; + gemC.m_gemOrigin = GemInfo::GemOrigin::Remote; + + gemA.m_types = GemInfo::Type::Code; + gemB.m_types = GemInfo::Type::Code | GemInfo::Type::Tool; + gemC.m_types = GemInfo::Type::Asset; + + using Plat = GemInfo::Platform; + gemA.m_platforms = Plat::Windows; + gemB.m_platforms = Plat::Android | Plat::iOS; + gemC.m_platforms = Plat::Android | Plat::iOS | Plat::Linux | Plat::macOS | Plat::Windows; + + gemA.m_features = QStringList({ "Audio", "Framework", "SDK" }); + gemB.m_features = QStringList({ "Framework", "Tools", "UI" }); + gemC.m_features = QStringList({ "Assets", "Content", "Environment" }); + + m_gemRows.append(m_gemModel->AddGem(gemA).row()); + m_gemRows.append(m_gemModel->AddGem(gemB).row()); + m_gemRows.append(m_gemModel->AddGem(gemC).row()); + } + + protected: + enum RowOrder + { + DefaultAudio, + MobileUX, + CityProps + }; + + QVector m_gemRows; + }; + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_MiscNoFilter_ShowsAll) + { + // No filter + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleOrigin_ShowsOriginMatch) + { + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Open3DEngine); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Local); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Remote); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleOrigins_ShowsMultipleOriginMatches) + { + m_proxyModel->SetGemOrigins(GemInfo::GemOrigin::Open3DEngine | GemInfo::GemOrigin::Local); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleType_ShowsTypeMatch) + { + m_proxyModel->SetTypes(GemInfo::Type::Code); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetTypes(GemInfo::Type::Tool); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetTypes(GemInfo::Type::Asset); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleTypes_ShowsMultipleTypeMatches) + { + m_proxyModel->SetTypes(GemInfo::Type::Tool | GemInfo::Type::Asset); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSinglePlatform_ShowsPlatformMatch) + { + m_proxyModel->SetPlatforms(GemInfo::Platform::Windows); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetPlatforms(GemInfo::Platform::Android); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetPlatforms(GemInfo::Platform::macOS); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultiplePlatforms_ShowsMultiplePlatformMatches) + { + m_proxyModel->SetPlatforms(GemInfo::Platform::Android | GemInfo::Platform::iOS); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterSingleFeature_ShowsFeatureMatch) + { + m_proxyModel->SetFeatures({ "Audio" }); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetFeatures({ "Tools", }); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + + m_proxyModel->SetFeatures({ "Environment" }); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterMultipleFeatures_ShowsMultipleFeatureMatches) + { + m_proxyModel->SetFeatures({ "Assets", "Framework" }); + + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_TRUE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } + + TEST_F(GemCatalogMiscFilterTests, GemCatalogFilters_FilterPartialMatchFeature_ShowsNone) + { + // Features must be an exact match to filter by them directly + m_proxyModel->SetFeatures({ "Frame" }); + + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[DefaultAudio], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[MobileUX], QModelIndex())); + EXPECT_FALSE(m_proxyModel->filterAcceptsRow(m_gemRows[CityProps], QModelIndex())); + } } From c492d644da2bc1fc0881a1408b32dade88b4b7f3 Mon Sep 17 00:00:00 2001 From: Nicholas Lawson <70027408+lawsonamzn@users.noreply.github.com> Date: Wed, 1 Dec 2021 08:18:39 -0800 Subject: [PATCH 56/72] Fixes #5909 hash file stats missing from AP stats log (#5913) The "begin and end" markers were removed due to a merge conflict. This restores them. It also stops printing out sections that are empty - for example, if the AP runs without processing anything, there will no longer be a "top 10 processed files" section. Signed-off-by: lawsonamzn <70027408+lawsonamzn@users.noreply.github.com> --- Code/Tools/AssetProcessor/native/utilities/StatsCapture.cpp | 6 ++++++ Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/Code/Tools/AssetProcessor/native/utilities/StatsCapture.cpp b/Code/Tools/AssetProcessor/native/utilities/StatsCapture.cpp index 1174e2500c..f6b7c07a91 100644 --- a/Code/Tools/AssetProcessor/native/utilities/StatsCapture.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/StatsCapture.cpp @@ -132,6 +132,12 @@ namespace AssetProcessor // calls PrintStat on each element in the vector. void PrintStatsArray(AZStd::vector& keys, int maxToPrint, const char* header) { + // don't print anything out at all, not even a header, if the keys are empty. + if (keys.empty()) + { + return; + } + if ((m_dumpHumanReadableStats)&&(header)) { AZ_TracePrintf(AssetProcessor::ConsoleChannel,"Top %i %s\n", maxToPrint, header); diff --git a/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp b/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp index ae70ee7fe5..6bcd0dec01 100644 --- a/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp @@ -1182,7 +1182,11 @@ namespace AssetUtilities } } + // keep track of how much time we spend actually hashing files. + AZStd::string statName = AZStd::string::format("HashFile,%s", filePath); + AssetProcessor::StatsCapture::BeginCaptureStat(statName.c_str()); hash = AssetBuilderSDK::GetFileHash(filePath, bytesReadOut, hashMsDelay); + AssetProcessor::StatsCapture::EndCaptureStat(statName.c_str()); return hash; } From 1a46f548a79ea101ff9408041dd5c96d41933f38 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 1 Dec 2021 09:14:07 -0800 Subject: [PATCH 57/72] Remove unused scripts/build/package (#5885) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../Jenkins/tools/jenkins_pipeline_metrics.py | 15 +- .../Windows/package_build_config.json | 13 -- scripts/build/package/PackageEnv.py | 191 ------------------ scripts/build/package/Params.py | 80 -------- .../Platform/3rdParty/package_env.json | 19 -- .../3rdParty/package_filelists/3rdParty.json | 18 -- .../package/Platform/Android/package_env.json | 25 --- .../package/Platform/Mac/package_env.json | 40 ---- .../Mac/package_filelists/3rdParty.json | 82 -------- .../package/Platform/Windows/package_env.json | 35 ---- .../Windows/package_filelists/3rdParty.json | 113 ----------- scripts/build/package/glob3.py | 163 --------------- scripts/build/package/package.py | 187 ----------------- scripts/build/package/package_env.json | 11 - .../build/package/package_filelists/all.json | 15 -- .../package/package_filelists/symbols.json | 5 - .../build/package/platform_exclusions.json | 12 -- scripts/{build/package => util}/util.py | 15 -- 18 files changed, 7 insertions(+), 1032 deletions(-) delete mode 100644 scripts/build/Platform/Windows/package_build_config.json delete mode 100755 scripts/build/package/PackageEnv.py delete mode 100755 scripts/build/package/Params.py delete mode 100644 scripts/build/package/Platform/3rdParty/package_env.json delete mode 100644 scripts/build/package/Platform/3rdParty/package_filelists/3rdParty.json delete mode 100644 scripts/build/package/Platform/Android/package_env.json delete mode 100644 scripts/build/package/Platform/Mac/package_env.json delete mode 100644 scripts/build/package/Platform/Mac/package_filelists/3rdParty.json delete mode 100644 scripts/build/package/Platform/Windows/package_env.json delete mode 100644 scripts/build/package/Platform/Windows/package_filelists/3rdParty.json delete mode 100755 scripts/build/package/glob3.py delete mode 100755 scripts/build/package/package.py delete mode 100644 scripts/build/package/package_env.json delete mode 100644 scripts/build/package/package_filelists/all.json delete mode 100644 scripts/build/package/package_filelists/symbols.json delete mode 100644 scripts/build/package/platform_exclusions.json rename scripts/{build/package => util}/util.py (78%) mode change 100755 => 100644 diff --git a/scripts/build/Jenkins/tools/jenkins_pipeline_metrics.py b/scripts/build/Jenkins/tools/jenkins_pipeline_metrics.py index 8b0164e3e8..6ea2e135a7 100644 --- a/scripts/build/Jenkins/tools/jenkins_pipeline_metrics.py +++ b/scripts/build/Jenkins/tools/jenkins_pipeline_metrics.py @@ -16,9 +16,8 @@ from datetime import datetime, timezone from requests.auth import HTTPBasicAuth cur_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(os.path.join(os.path.dirname(os.path.dirname(cur_dir)), 'package')) -from util import * - +sys.path.insert(0, os.path.abspath(f'{cur_dir}/../../../util')) +import util class JenkinsAPIClient: def __init__(self, jenkins_base_url, jenkins_username, jenkins_api_token): @@ -36,7 +35,7 @@ class JenkinsAPIClient: except Exception: traceback.print_exc() print(f'WARN: Get request {url} failed, retying....') - error(f'Get request {url} failed, see exception for more details.') + util.error(f'Get request {url} failed, see exception for more details.') def get_builds(self, pipeline_name, branch_name=''): url = self.jenkins_base_url + self.blueocean_api_path + f'/{pipeline_name}/{branch_name}/runs' @@ -123,9 +122,9 @@ def upload_files_to_s3(env, formatted_date): else: python = os.path.join(engine_root, 'python', 'python.sh') upload_csv_cmd = [python, upload_to_s3_script_path, '--base_dir', cur_dir, '--file_regex', env['CSV_REGEX'], '--bucket', env['BUCKET'], '--key_prefix', csv_s3_prefix] - execute_system_call(upload_csv_cmd) + util.execute_system_call(upload_csv_cmd) upload_manifest_cmd = [python, upload_to_s3_script_path, '--base_dir', cur_dir, '--file_regex', env['MANIFEST_REGEX'], '--bucket', env['BUCKET'], '--key_prefix', manifest_s3_prefix] - execute_system_call(upload_manifest_cmd) + util.execute_system_call(upload_manifest_cmd) def get_required_env(env, keys): @@ -134,7 +133,7 @@ def get_required_env(env, keys): try: env[key] = os.environ[key].strip() except KeyError: - error(f'{key} is not set in environment variable') + util.error(f'{key} is not set in environment variable') success = False return success @@ -143,7 +142,7 @@ def main(): env = {} required_env_list = ['JENKINS_URL', 'PIPELINE_NAME', 'BRANCH_NAME', 'JENKINS_USERNAME', 'JENKINS_API_TOKEN', 'BUCKET', 'CSV_REGEX', 'CSV_PREFIX', 'MANIFEST_REGEX', 'MANIFEST_PREFIX', 'DAYS_TO_COLLECT'] if not get_required_env(env, required_env_list): - error('Required environment variable is not set, see log for more details.') + util.error('Required environment variable is not set, see log for more details.') target_date = datetime.today().date() formatted_date = f'{target_date.year}/{target_date:%m}/{target_date:%d}' diff --git a/scripts/build/Platform/Windows/package_build_config.json b/scripts/build/Platform/Windows/package_build_config.json deleted file mode 100644 index 1a94fb802a..0000000000 --- a/scripts/build/Platform/Windows/package_build_config.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "profile_atom": { - "COMMAND":"build_windows.cmd", - "PARAMETERS": { - "CONFIGURATION":"profile", - "OUTPUT_DIRECTORY":"windows", - "CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0", - "CMAKE_LY_PROJECTS":"AtomTest;AtomSampleViewer", - "CMAKE_TARGET":"ALL_BUILD", - "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" - } - } -} diff --git a/scripts/build/package/PackageEnv.py b/scripts/build/package/PackageEnv.py deleted file mode 100755 index 1f2d102214..0000000000 --- a/scripts/build/package/PackageEnv.py +++ /dev/null @@ -1,191 +0,0 @@ -# -# 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 Params import Params -from util import * - - -class PackageEnv(Params): - def __init__(self, platform, type, json_file): - super(PackageEnv, self).__init__() - self.__cur_dir = os.path.dirname(os.path.abspath(__file__)) - global_env_file = os.path.join(self.__cur_dir, json_file) - with open(global_env_file, 'r') as source: - data = json.load(source) - self.__global_env = data.get('global_env') - platform_env_file = os.path.join(self.__cur_dir, 'Platform', platform, json_file) - if not os.path.exists(platform_env_file): - print(f'{platform_env_file} is not found.') - # Search restricted platform folders - engine_root = self.get('ENGINE_ROOT') - # Use real path in case engine root is a symlink path - if os.name == 'posix' and os.path.islink(engine_root): - engine_root = os.readlink(engine_root) - rel_path = os.path.relpath(self.__cur_dir, engine_root) - platform_env_file = os.path.join(engine_root, 'restricted', platform, rel_path, json_file) - if not os.path.exists(platform_env_file): - ly_build_error(f'{platform_env_file} is not found.') - with open(platform_env_file, 'r') as source: - data = json.load(source) - types = data.get('types') - if type not in types: - ly_build_error(f'Package type {type} is not supported') - self.__platform = platform - self.__platform_env = data.get('local_env') - self.__platform_env.update(self.__global_env) - self.__type = type - self.__type_env = types.get(type) - - def get_platform(self): - return self.__platform - - def get_type(self): - return self.__type - - def get_platform_env(self): - return self.__platform_env - - def get_type_env(self): - return self.__type_env - - def __get_platform_value(self, key): - key = key.upper() - value = self.__platform_env.get(key) - if value is None: - ly_build_error(f'{key} is not defined in global env nor in local env') - return value - - def __get_type_value(self, key): - key = key.upper() - value = self.__type_env.get(key) - if value is None: - ly_build_error(f'{key} is not defined in package type {self.__type} for platform {self.__platform}') - return value - - def __evaluate_boolean(self, v): - return str(v).lower() in ['1', 'true'] - - def __get_engine_root(self): - def validate_engine_root(engine_root): - if not os.path.isdir(engine_root): - return False - return os.path.exists(os.path.join(engine_root, 'engine.json')) - - workspace = os.getenv('WORKSPACE') - if workspace is not None: - print(f'Environment variable WORKSPACE={workspace} detected') - if validate_engine_root(workspace): - print(f'Setting ENGINE_ROOT to {workspace}') - return workspace - print('Cannot locate ENGINE_ROOT with Environment variable WORKSPACE') - - engine_root = os.getenv('ENGINE_ROOT', '') - if validate_engine_root(engine_root): - return engine_root - - print('Environment variable ENGINE_ROOT is not set or invalid, checking ENGINE_ROOT in env json file') - engine_root = self.__global_env.get('ENGINE_ROOT') - if validate_engine_root(engine_root): - return engine_root - - # Set engine_root based on script location - engine_root = os.path.dirname(os.path.dirname(os.path.dirname(self.__cur_dir))) - print(f'ENGINE_ROOT from env json file is invalid, defaulting to {engine_root}') - if validate_engine_root(engine_root): - return engine_root - else: - error('Cannot Locate ENGINE_ROOT') - - def __get_thirdparty_home(self): - third_party_home = os.getenv('LY_3RDPARTY_PATH', '') - if os.path.exists(third_party_home): - print(f'LY_3RDPARTY_PATH found, using {third_party_home} as 3rdParty path.') - return third_party_home - third_party_home = self.__get_platform_value('THIRDPARTY_HOME') - if os.path.isdir(third_party_home): - return third_party_home - - # Set engine_root based on script location - print('THIRDPARTY_HOME is not valid, looking for THIRD_PARTY_HOME') - - # Finding THIRD_PARTY_HOME - cur_dir = self.__get_engine_root() - last_dir = None - while last_dir != cur_dir: - third_party_home = os.path.join(cur_dir, '3rdParty') - print(f'Cheking THIRDPARTY_HOME {third_party_home}') - if os.path.exists(os.path.join(third_party_home, '3rdParty.txt')): - print(f'Setting THIRDPARTY_HOME to {third_party_home}') - return third_party_home - last_dir = cur_dir - cur_dir = os.path.dirname(cur_dir) - error('Cannot locate THIRDPARTY_HOME') - - def __get_package_name_pattern(self): - package_name_pattern = self.__get_platform_value('PACKAGE_NAME_PATTERN') - if os.getenv('PACKAGE_NAME_PATTERN') is not None: - package_name_pattern = os.getenv('PACKAGE_NAME_PATTERN') - return package_name_pattern - - def __get_branch_name(self): - branch_name = self.__get_platform_value('BRANCH_NAME') - if os.getenv('BRANCH_NAME') is not None: - branch_name = os.getenv('BRANCH_NAME') - branch_name = branch_name.replace('/', '_').replace('\\', '_') - return branch_name - - def __get_build_number(self): - build_number = self.__get_platform_value('BUILD_NUMBER') - if os.getenv('BUILD_NUMBER') is not None: - build_number = os.getenv('BUILD_NUMBER') - return build_number - - def __get_scrub_params(self): - return self.__get_type_value('SCRUB_PARAMS') - - def __get_validator_platforms(self): - return self.__get_type_value('VALIDATOR_PLATFORMS') - - def __get_package_targets(self): - return self.__get_type_value('PACKAGE_TARGETS') - - def __get_build_targets(self): - return self.__get_type_value('BUILD_TARGETS') - - def __get_asset_processor_path(self): - return self.__get_type_value('ASSET_PROCESSOR_PATH') - - def __get_asset_game_folders(self): - return self.__get_type_value('ASSET_GAME_FOLDERS') - - def __get_asset_platform(self): - return self.__get_type_value('ASSET_PLATFORM') - - def __get_bootstrap_cfg_game_folder(self): - return self.__get_type_value('BOOTSTRAP_CFG_GAME_FOLDER') - - def __get_skip_build(self): - skip_build = os.getenv('SKIP_BUILD') - if skip_build is None: - skip_build = self.__get_type_value('SKIP_BUILD') - return self.__evaluate_boolean(skip_build) - - def __get_skip_scrubbing(self): - skip_scrubbing = os.getenv('SKIP_SCRUBBING') - if skip_scrubbing is None: - skip_scrubbing = self.__type_env.get('SKIP_SCRUBBING', 'False') - return self.__evaluate_boolean(skip_scrubbing) - - def __get_internal_s3_bucket(self): - return self.__get_platform_value('INTERNAL_S3_BUCKET') - - def __get_qa_s3_bucket(self): - return self.__get_platform_value('QA_S3_BUCKET') - - def __get_s3_prefix(self): - return self.__get_platform_value('S3_PREFIX') diff --git a/scripts/build/package/Params.py b/scripts/build/package/Params.py deleted file mode 100755 index 994d28486a..0000000000 --- a/scripts/build/package/Params.py +++ /dev/null @@ -1,80 +0,0 @@ -# -# 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 os -import sys -import re -from util import ly_build_error - - -class Params(object): - def __init__(self): - # Cache params - self.__params = {} - - def get(self, param_name): - param_value = self.__params.get(param_name) - if param_value is not None: - return param_value - # Call __get_${param_name} function - func = getattr(self, '_{}__get_{}'.format(self.__class__.__name__, param_name.lower()), None) - if func is not None: - param_value = func() - # Replace all ${env} in value - if isinstance(param_value, str): - param_value = self.__process_string(param_name, param_value) - elif isinstance(param_value, list): - param_value = self.__process_list(param_name, param_value) - elif isinstance(param_value, dict): - param_value = self.__process_dict(param_name, param_value) - # Cache param - self.__params[param_name] = param_value - return param_value - ly_build_error('method __get_{} is not defined in class {}'.format(param_name.lower(), self.__class__.__name__)) - - def set(self, param_name, param_value): - self.__params[param_name] = param_value - - def exists(self, param_name): - try: - self.get(param_name) - except LyBuildError: - return False - return True - - def __process_string(self, param_name, param_value): - # Find all param with format ${param} - params = re.findall('\${(\w+)}', param_value) - # Avoid using the same param name in value, like 'WORKSPACE': '${WORKSPACE} some string' - if param_name in params: - ly_build_error('The use of same parameter name({}) in value is not allowed'.format(param_name)) - # Replace ${param} with actual value - for param in params: - param_value = param_value.replace('${' + param + '}', self.get(param)) - return param_value - - def __process_list(self, param_name, param_value): - processed_list = [] - for entry in param_value: - if isinstance(entry, str): - entry = self.__process_string(param_name, entry) - elif isinstance(entry, list): - entry = self.__process_list(param_name, entry) - elif isinstance(entry, dict): - entry = self.__process_dict(param_name, entry) - processed_list.append(entry) - return processed_list - - def __process_dict(self, param_name, param_value): - for key in param_value: - if isinstance(param_value[key], str): - param_value[key] = self.__process_string(param_name, param_value[key]) - elif isinstance(param_value[key], list): - param_value[key] = self.__process_list(param_name, param_value[key]) - elif isinstance(param_value[key], dict): - param_value[key] = self.__process_dict(param_name, param_value[key]) - return param_value \ No newline at end of file diff --git a/scripts/build/package/Platform/3rdParty/package_env.json b/scripts/build/package/Platform/3rdParty/package_env.json deleted file mode 100644 index 5059132664..0000000000 --- a/scripts/build/package/Platform/3rdParty/package_env.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "local_env": { - "S3_PREFIX": "${BRANCH_NAME}/3rdParty" - }, - "types": { - "3rdParty_all": { - "PACKAGE_TARGETS":[ - { - "FILE_LIST": "3rdParty.json", - "FILE_LIST_TYPE": "3rdParty", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-3rdParty-all-${BUILD_NUMBER}.zip" - } - ], - "BOOTSTRAP_CFG_GAME_FOLDER":"CMakeTestbed", - "SKIP_BUILD": 1, - "SKIP_SCRUBBING": 1 - } - } -} diff --git a/scripts/build/package/Platform/3rdParty/package_filelists/3rdParty.json b/scripts/build/package/Platform/3rdParty/package_filelists/3rdParty.json deleted file mode 100644 index 915368dd0b..0000000000 --- a/scripts/build/package/Platform/3rdParty/package_filelists/3rdParty.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "@3rdParty": { - "3rdParty.txt": "#include", - "AWS/AWSNativeSDK/1.7.167-az.2/**": "#include", - "CMake/3.19.1/**": "#include", - "DirectXShaderCompiler/1.0.1-az.1/**": "#include", - "DirectXShaderCompiler/2020.08.07/**": "#include", - "DirectXShaderCompiler/5.0.0-az/**": "#include", - "dyad/0.2.0-17-amazon/**": "#include", - "etc2comp/2017_04_24-az.2/**": "#include", - "expat/2.1.0-pkg.3/**": "#include", - "FbxSdk/2016.1.2-az.1/**": "#include", - "OpenSSL/1.1.1b-noasm-az/**": "#include", - "Qt/5.15.1.2-az/**": "#include", - "tiff/3.9.5-az.3/**": "#include", - "Wwise/2019.2.8.7432/**": "#include" - } -} \ No newline at end of file diff --git a/scripts/build/package/Platform/Android/package_env.json b/scripts/build/package/Platform/Android/package_env.json deleted file mode 100644 index 017937413a..0000000000 --- a/scripts/build/package/Platform/Android/package_env.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "local_env": { - "S3_PREFIX": "${BRANCH_NAME}/Android" - }, - "types":{ - "all":{ - "PACKAGE_TARGETS":[ - { - "FILE_LIST": "all.json", - "FILE_LIST_TYPE": "All", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-android-all-${BUILD_NUMBER}.zip" - } - ], - "BOOTSTRAP_CFG_GAME_FOLDER":"AutomatedTesting", - "SKIP_BUILD": 0, - "BUILD_TARGETS":[ - { - "BUILD_CONFIG_FILENAME": "build_config.json", - "PLATFORM": "Android", - "TYPE": "profile" - } - ] - } - } -} diff --git a/scripts/build/package/Platform/Mac/package_env.json b/scripts/build/package/Platform/Mac/package_env.json deleted file mode 100644 index f21c9fdaab..0000000000 --- a/scripts/build/package/Platform/Mac/package_env.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "local_env": { - "S3_PREFIX": "${BRANCH_NAME}/Mac" - }, - "types":{ - "all":{ - "PACKAGE_TARGETS":[ - { - "FILE_LIST": "all.json", - "FILE_LIST_TYPE": "All", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-mac-all-${BUILD_NUMBER}.zip" - }, - { - "FILE_LIST": "3rdParty.json", - "FILE_LIST_TYPE": "Mac", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-mac-3rdParty-${BUILD_NUMBER}.zip" - }, - { - "FILE_LIST": "3rdParty.json", - "FILE_LIST_TYPE": "3rdParty", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-mac-3rdParty-Warsaw-${BUILD_NUMBER}.zip" - } - ], - "BOOTSTRAP_CFG_GAME_FOLDER":"CMakeTestbed", - "SKIP_BUILD": 0, - "BUILD_TARGETS":[ - { - "BUILD_CONFIG_FILENAME": "build_config.json", - "PLATFORM": "Mac", - "TYPE": "profile" - }, - { - "BUILD_CONFIG_FILENAME": "build_config.json", - "PLATFORM": "iOS", - "TYPE": "profile" - } - ] - } - } -} diff --git a/scripts/build/package/Platform/Mac/package_filelists/3rdParty.json b/scripts/build/package/Platform/Mac/package_filelists/3rdParty.json deleted file mode 100644 index ff019f701f..0000000000 --- a/scripts/build/package/Platform/Mac/package_filelists/3rdParty.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "@3rdParty":{ - "3rdParty.txt":"#include", - "AWS/AWSNativeSDK/1.7.167-az.2":{ - "*":"#include", - "include/**":"#include", - "LICENSE*":"#include", - "lib/mac/**":"#include", - "bin/mac/**":"#include", - "lib/ios/**":"#include", - "bin/ios/**":"#include" - }, - "DirectXShaderCompiler/1.0.1-az.1":{ - "*":"#include", - "src/**":"#include", - "bin/darwin_x64/**":"#include" - }, - "DirectXShaderCompiler/2020.08.07":{ - "*":"#include", - "bin/darwin_x64/**":"#include" - }, - "DirectXShaderCompiler/5.0.0-az":{ - "*":"#include", - "bin/darwin_x64/**":"#include" - }, - "etc2comp/2017_04_24-az.2":{ - "*":"#include", - "EtcLib/Etc/**":"#include", - "EtcLib/EtcCodec/**":"#include", - "EtcLib/*":"#include", - "EtcLib/OSX_x86/**":"#include" - }, - "expat/2.1.0-pkg.3":{ - "*":"#include", - "amiga/**":"#include", - "bcb5/**":"#include", - "conftools/**":"#include", - "doc/**":"#include", - "examples/**":"#include", - "lib/**":"#include", - "m4/**":"#include", - "tests/**":"#include", - "vms/**":"#include", - "win32/**":"#include", - "xmlwf/**":"#include", - "build/osx/**":"#include" - }, - "FreeType2/2.5.0.1-pkg.3":{ - "freetype-2.5.0.1/**":"#include", - "dist/**":"#include", - "mac/**":"#include", - "ios*/**":"#include", - "build/osx/**":"#include" - }, - "Redistributables/FbxSdk/2016.1.2":{ - "*mac*":"#include" - }, - "OpenSSL/1.1.1b-noasm-az":{ - "include/**":"#include", - "ssl/**":"#include", - "LICENSE":"#include", - "bin/**":"#include", - "lib/darwin*/**":"#include", - "lib/ios*/**":"#include" - }, - "Qt/5.15.1.2-az":{ - "LICENSE":"#include", - "LGPL_EXCEPTION.TXT":"#include", - "LICENSE.GPLV3":"#include", - "LICENSE.LGPLV3":"#include", - "QT-NOTICE.TXT":"#include", - "clang_64/**":"#include" - }, - "tiff/3.9.5-az.3":{ - "COPYRIGHT":"#include", - "README":"#include", - "RELEASE-DATE":"#include", - "VERSION":"#include", - "libtiff/macosx_clang/**":"#include" - } - } -} \ No newline at end of file diff --git a/scripts/build/package/Platform/Windows/package_env.json b/scripts/build/package/Platform/Windows/package_env.json deleted file mode 100644 index bfe526bc16..0000000000 --- a/scripts/build/package/Platform/Windows/package_env.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "local_env": { - "S3_PREFIX": "${BRANCH_NAME}/Windows" - }, - "types":{ - "all":{ - "PACKAGE_TARGETS":[ - { - "FILE_LIST": "all.json", - "FILE_LIST_TYPE": "All", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-windows-all-${BUILD_NUMBER}.zip" - }, - { - "FILE_LIST": "symbols.json", - "FILE_LIST_TYPE": "All", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-windows-all-symbols-${BUILD_NUMBER}.zip" - }, - { - "FILE_LIST": "3rdParty.json", - "FILE_LIST_TYPE": "Windows", - "PACKAGE_NAME": "${PACKAGE_NAME_PATTERN}-windows-3rdparty-${BUILD_NUMBER}.zip" - } - ], - "BOOTSTRAP_CFG_GAME_FOLDER":"CMakeTestbed", - "SKIP_BUILD": 0, - "BUILD_TARGETS":[ - { - "BUILD_CONFIG_FILENAME": "build_config.json", - "PLATFORM": "Windows", - "TYPE": "profile" - } - ] - } - } -} diff --git a/scripts/build/package/Platform/Windows/package_filelists/3rdParty.json b/scripts/build/package/Platform/Windows/package_filelists/3rdParty.json deleted file mode 100644 index d9e5d85090..0000000000 --- a/scripts/build/package/Platform/Windows/package_filelists/3rdParty.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "@3rdParty":{ - "3rdParty.txt":"#include", - "AMD/AGS Lib/2.2":{ - "*":"#include", - "inc/**":"#include", - "lib/x64/**":"#include" - }, - "AWS/AWSNativeSDK/1.7.167-az.2":{ - "*":"#include", - "include/**":"#include", - "LICENSE*":"#include", - "lib/windows/**":"#include", - "bin/windows/**":"#include", - "lib/android/arm64-v8a/**":"#include", - "bin/android/arm64-v8a/**":"#include", - "bin/linux/**":"#include", - "lib/linux/**":"#include" - }, - "DirectXShaderCompiler/1.0.1-az.1":{ - "*":"#include", - "src/**":"#include", - "bin/win_x64/**":"#include" - }, - "DirectXShaderCompiler/2020.08.07":{ - "*":"#include", - "bin/win_x64/**":"#include" - }, - "DirectXShaderCompiler/5.0.0-az":{ - "*":"#include", - "bin/win_x64/**":"#include" - }, - "dyad/0.2.0-17-amazon":{ - "*":"#include", - "doc/**":"#include", - "example/**":"#include", - "projects/**":"#include", - "src/**":"#include", - "lib/x64_v140_Debug/**":"#include", - "lib/x64_v140_Release/**":"#include", - "lib/linux_debug/**":"#include", - "lib/linux_release/**":"#include" - }, - "etc2comp/2017_04_24-az.2":{ - "EtcLib/Etc/**":"#include", - "EtcLib/EtcCodec/**":"#include", - "LICENSE":"#include", - "EtcLib/Windows_x86_64/**":"#include", - "EtcLib/Linux_x64_linux/**":"#include" - }, - "expat/2.1.0-pkg.3":{ - "*":"#include", - "amiga/**":"#include", - "bcb5/**":"#include", - "conftools/**":"#include", - "doc/**":"#include", - "examples/**":"#include", - "lib/**":"#include", - "m4/**":"#include", - "tests/**":"#include", - "vms/**":"#include", - "win32/**":"#include", - "xmlwf/**":"#include", - "build/win_x64/vc140/**":"#include", - "build/win_x64/android_ndk_r12/android-*/**":"#include", - "build/linux/**":"#include" - }, - "FreeType2/2.5.0.1-pkg.3":{ - "freetype-2.5.0.1/**":"#include", - "dist/**":"#include", - "vc140_x64/**":"#include", - "build/win_x64/vc140/**":"#include", - "android*/**":"#include", - "build/win_x64/android_ndk_r12/android-*/**":"#include", - "build/linux/clang-3.4/**":"#include" - }, - "Redistributables/FbxSdk/2016.1.2":{ - "*win*":"#include", - "*vs2013*":"#exclude" - }, - "OpenSSL/1.1.1b-noasm-az":{ - "include/**":"#include", - "ssl/**":"#include", - "LICENSE":"#include", - "bin/**":"#include", - "lib/vc140_x64_debug/**":"#include", - "lib/vc140_x64_release/**":"#include", - "lib/android_ndk_r15c/android-*/**":"#include", - "lib/linux-x86_64-clang-debug/**":"#include", - "lib/linux-x86_64-clang-release/**":"#include" - }, - "Qt/5.15.1.2-az":{ - "LICENSE":"#include", - "LGPL_EXCEPTION.TXT":"#include", - "LICENSE.GPLV3":"#include", - "LICENSE.LGPLV3":"#include", - "QT-NOTICE.TXT":"#include", - "msvc*/**":"#include", - "gcc_64/**":"#include" - }, - "tiff/3.9.5-az.3":{ - "COPYRIGHT":"#include", - "README":"#include", - "RELEASE-DATE":"#include", - "VERSION":"#include", - "libtiff/buildLib32Lib64.bat":"#include", - "libtiff/readme.txt":"#include", - "include/libtiff/*.h":"#include", - "libtiff/*vc140.lib":"#include", - "libtiff/linux_gcc/**":"#include" - } - } -} \ No newline at end of file diff --git a/scripts/build/package/glob3.py b/scripts/build/package/glob3.py deleted file mode 100755 index b46683a4be..0000000000 --- a/scripts/build/package/glob3.py +++ /dev/null @@ -1,163 +0,0 @@ -# -# 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 os -import re -import fnmatch - -__all__ = ["glob", "iglob", "escape"] - -def glob(pathname, recursive=False): - """Return a list of paths matching a pathname pattern. - The pattern may contain simple shell-style wildcards a la - fnmatch. However, unlike fnmatch, filenames starting with a - dot are special cases that are not matched by '*' and '?' - patterns. - If recursive is true, the pattern '**' will match any files and - zero or more directories and subdirectories. - """ - return list(iglob(pathname, recursive=recursive)) - -def iglob(pathname, recursive=False): - """Return an iterator which yields the paths matching a pathname pattern. - The pattern may contain simple shell-style wildcards a la - fnmatch. However, unlike fnmatch, filenames starting with a - dot are special cases that are not matched by '*' and '?' - patterns. - If recursive is true, the pattern '**' will match any files and - zero or more directories and subdirectories. - """ - it = _iglob(pathname, recursive, False) - if recursive and _isrecursive(pathname): - s = next(it) # skip empty string - assert not s - return it - -def _iglob(pathname, recursive, dironly): - dirname, basename = os.path.split(pathname) - if not has_magic(pathname): - assert not dironly - if basename: - if os.path.lexists(pathname): - yield pathname - else: - # Patterns ending with a slash should match only directories - if os.path.isdir(dirname): - yield pathname - return - if not dirname: - if recursive and _isrecursive(basename): - yield _glob2(dirname, basename, dironly) - else: - yield _glob1(dirname, basename, dironly) - return - # `os.path.split()` returns the argument itself as a dirname if it is a - # drive or UNC path. Prevent an infinite recursion if a drive or UNC path - # contains magic characters (i.e. r'\\?\C:'). - if dirname != pathname and has_magic(dirname): - dirs = _iglob(dirname, recursive, True) - else: - dirs = [dirname] - if has_magic(basename): - if recursive and _isrecursive(basename): - glob_in_dir = _glob2 - else: - glob_in_dir = _glob1 - else: - glob_in_dir = _glob0 - for dirname in dirs: - for name in glob_in_dir(dirname, basename, dironly): - yield os.path.join(dirname, name) - -# These 2 helper functions non-recursively glob inside a literal directory. -# They return a list of basenames. _glob1 accepts a pattern while _glob0 -# takes a literal basename (so it only has to check for its existence). - -def _glob1(dirname, pattern, dironly): - names = list(_iterdir(dirname, dironly)) - return fnmatch.filter(names, pattern) - -def _glob0(dirname, basename, dironly): - if not basename: - # `os.path.split()` returns an empty basename for paths ending with a - # directory separator. 'q*x/' should match only directories. - if os.path.isdir(dirname): - return [basename] - else: - if os.path.lexists(os.path.join(dirname, basename)): - return [basename] - return [] - -# Following functions are not public but can be used by third-party code. - -def glob0(dirname, pattern): - return _glob0(dirname, pattern, False) - -def glob1(dirname, pattern): - return _glob1(dirname, pattern, False) - -# This helper function recursively yields relative pathnames inside a literal -# directory. - -def _glob2(dirname, pattern, dironly): - assert _isrecursive(pattern) - return [pattern[:0]] + list(_rlistdir(dirname, dironly)) - -# If dironly is false, yields all file names inside a directory. -# If dironly is true, yields only directory names. -def _iterdir(dirname, dironly): - if not dirname: - if isinstance(dirname, bytes): - dirname = bytes(os.curdir, 'ASCII') - else: - dirname = os.curdir - try: - for entry in os.listdir(dirname): - yield entry - except OSError: - return - -# Recursively yields relative pathnames inside a literal directory. -def _rlistdir(dirname, dironly): - if not os.path.islink(dirname): - names = list(_iterdir(dirname, dironly)) - for x in names: - yield x - path = os.path.join(dirname, x) if dirname else x - for y in _rlistdir(path, dironly): - yield os.path.join(x, y) -magic_check = re.compile('([*?[])') -magic_check_bytes = re.compile(b'([*?[])') - -def has_magic(s): - if isinstance(s, bytes): - match = magic_check_bytes.search(s) - else: - match = magic_check.search(s) - return match is not None - -def _ishidden(path): - return path[0] in ('.', b'.'[0]) - -def _isrecursive(pattern): - if isinstance(pattern, bytes): - return pattern == b'**' - else: - return pattern == '**' - -def escape(pathname): - """Escape all special characters. - """ - # Escaping is done by wrapping any of "*?[" between square brackets. - # Metacharacters do not work in the drive part and shouldn't be escaped. - drive, pathname = os.path.splitdrive(pathname) - if isinstance(pathname, bytes): - pathname = magic_check_bytes.sub(br'[\1]', pathname) - else: - pathname = magic_check.sub(r'[\1]', pathname) - return drive + pathname \ No newline at end of file diff --git a/scripts/build/package/package.py b/scripts/build/package/package.py deleted file mode 100755 index d33601ba45..0000000000 --- a/scripts/build/package/package.py +++ /dev/null @@ -1,187 +0,0 @@ -# -# 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 os -import sys -import zipfile -import timeit -import progressbar -from optparse import OptionParser -from PackageEnv import PackageEnv -cur_dir = cur_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, f'{cur_dir}/..') -from ci_build import build -from util import * -from glob3 import glob - - -def package(options): - package_env = PackageEnv(options.platform, options.type, options.package_env) - - if not package_env.get('SKIP_BUILD'): - print(package_env.get('SKIP_BUILD')) - print('SKIP_BUILD is False, running CMake build...') - cmake_build(package_env) - - # TODO Compile Assets - #if package_env.exists('ASSET_PROCESSOR_PATH'): - # compile_assets(package_env) - - #create packages - package_targets = package_env.get('PACKAGE_TARGETS') - for package_target in package_targets: - create_package(package_env, package_target) - upload_package(package_env, package_target) - - -def get_python_path(package_env): - if sys.platform == 'win32': - return os.path.join(package_env.get('ENGINE_ROOT'), 'python', 'python.cmd') - else: - return os.path.join(package_env.get('ENGINE_ROOT'), 'python', 'python.sh') - - -def cmake_build(package_env): - build_targets = package_env.get('BUILD_TARGETS') - for build_target in build_targets: - build(build_target['BUILD_CONFIG_FILENAME'], build_target['PLATFORM'], build_target['TYPE']) - - -def create_package(package_env, package_target): - print('Creating zipfile for package target {}'.format(package_target)) - cur_dir = os.path.dirname(os.path.abspath(__file__)) - file_list_type = package_target['FILE_LIST_TYPE'] - if file_list_type == 'All': - filelist = os.path.join(cur_dir, 'package_filelists', package_target['FILE_LIST']) - else: - filelist = os.path.join(cur_dir, 'Platform', file_list_type, 'package_filelists', package_target['FILE_LIST']) - with open(filelist, 'r') as source: - data = json.load(source) - lyengine = package_env.get('ENGINE_ROOT') - print('Calculating filelists...') - files = {} - - if '@lyengine' in data: - files.update(filter_files(data['@lyengine'], lyengine)) - if '@3rdParty' in data: - files.update(filter_files(data['@3rdParty'], package_env.get('THIRDPARTY_HOME'))) - package_path = os.path.join(lyengine, package_target['PACKAGE_NAME']) - print('Creating zipfile at {}'.format(package_path)) - start = timeit.default_timer() - with progressbar.ProgressBar(max_value=len(files), redirect_stderr=True) as bar: - with zipfile.ZipFile(package_path, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) as myzip: - i = 0 - bar.update(i) - last_bar_update = timeit.default_timer() - for f in files: - if os.path.islink(f): - zipInfo = zipfile.ZipInfo(files[f]) - zipInfo.create_system = 3 - # long type of hex val of '0xA1ED0000L', - # say, symlink attr magic... - zipInfo.external_attr |= 0xA0000000 - myzip.writestr(zipInfo, os.readlink(f)) - else: - myzip.write(f, files[f]) - i += 1 - # Update progress bar every 2 minutes - if int(timeit.default_timer() - last_bar_update) > 120: - last_bar_update = timeit.default_timer() - bar.update(i) - bar.update(i) - - stop = timeit.default_timer() - total_time = int(stop - start) - print('{} is created. Total time: {} seconds.'.format(package_path, total_time)) - - def get_MD5(file_path): - from hashlib import md5 - chunk_size = 200 * 1024 - h = md5() - with open(file_path, 'rb') as f: - while True: - chunk = f.read(chunk_size) - if len(chunk): - h.update(chunk) - else: - break - return h.hexdigest() - - md5_file = '{}.MD5'.format(package_path) - print('Creating MD5 file at {}'.format(md5_file)) - start = timeit.default_timer() - with open(md5_file, 'w') as output: - output.write(get_MD5(package_path)) - stop = timeit.default_timer() - total_time = int(stop - start) - print('{} is created. Total time: {} seconds.'.format(md5_file, total_time)) - - -def upload_package(package_env, package_target): - package_name = package_target['PACKAGE_NAME'] - engine_root = package_env.get('ENGINE_ROOT') - internal_s3_bucket = package_env.get('INTERNAL_S3_BUCKET') - qa_s3_bucket = package_env.get('QA_S3_BUCKET') - s3_prefix = package_env.get('S3_PREFIX') - print(f'Uploading {package_name} to S3://{internal_s3_bucket}/{s3_prefix}/{package_name}') - cmd = ['aws', 's3', 'cp', os.path.join(engine_root, package_name), f's3://{internal_s3_bucket}/{s3_prefix}/{package_name}'] - execute_system_call(cmd, stdout=subprocess.DEVNULL) - print(f'Uploading {package_name} to S3://{qa_s3_bucket}/{s3_prefix}/{package_name}') - cmd = ['aws', 's3', 'cp', os.path.join(engine_root, package_name), f's3://{qa_s3_bucket}/{s3_prefix}/{package_name}', '--acl', 'bucket-owner-full-control'] - execute_system_call(cmd, stdout=subprocess.DEVNULL) - - -def filter_files(data, base, prefix='', support_symlinks=True): - includes = {} - excludes = set() - for key, value in data.items(): - pattern = os.path.join(base, prefix, key) - if not isinstance(value, dict): - pattern = os.path.normpath(pattern) - result = glob(pattern, recursive=True) - files = [x for x in result if os.path.isfile(x) or (support_symlinks and os.path.islink(x))] - if value == "#exclude": - excludes.update(files) - elif value == "#include": - for file in files: - includes[file] = os.path.relpath(file, base) - else: - if value.startswith('#move:'): - for file in files: - file_name = os.path.relpath(file, os.path.join(base, prefix)) - dst_dir = value.replace('#move:', '').strip(' ') - includes[file] = os.path.join(dst_dir, file_name) - elif value.startswith('#rename:'): - for file in files: - dst_file = value.replace('#rename:', '').strip(' ') - includes[file] = dst_file - else: - warn('Unknown directive {} for pattern {}'.format(value, pattern)) - else: - includes.update(filter_files(value, base, os.path.join(prefix, key), support_symlinks)) - - for exclude in excludes: - try: - includes.pop(exclude) - except KeyError: - pass - return includes - - -def parse_args(): - parser = OptionParser() - parser.add_option("--platform", dest="platform", default='consoles', help="Target platform to package") - parser.add_option("--type", dest="type", default='consoles', help="Package type") - parser.add_option("--package_env", dest="package_env", default="package_env.json", - help="JSON file that defines package environment variables") - (options, args) = parser.parse_args() - return options, args - - -if __name__ == "__main__": - (options, args) = parse_args() - package(options) diff --git a/scripts/build/package/package_env.json b/scripts/build/package/package_env.json deleted file mode 100644 index 732ff12286..0000000000 --- a/scripts/build/package/package_env.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "global_env":{ - "ENGINE_ROOT":"", - "THIRDPARTY_HOME":"", - "BRANCH_NAME":"", - "PACKAGE_NAME_PATTERN":"${BRANCH_NAME}-spectra", - "BUILD_NUMBER":"0", - "INTERNAL_S3_BUCKET": "ly-spectra-packages", - "QA_S3_BUCKET": "amazon.ly.lionbridgeshare/ly-spectra-packages" - } -} diff --git a/scripts/build/package/package_filelists/all.json b/scripts/build/package/package_filelists/all.json deleted file mode 100644 index b1f3f270ca..0000000000 --- a/scripts/build/package/package_filelists/all.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "@lyengine": { - "**": "#include", - ".git/**": "#exclude", - ".gitattributes": "#exclude", - ".gitignore": "#exclude", - ".gitmodules": "#exclude", - ".lfsconfig": "#exclude", - ".p4ignore": "#exclude", - ".submodules": "#exclude", - "**/*.pyc": "#exclude", - "**/*.pdb": "#exclude", - "build/*/packages/*/*.stamp": "#exclude" - } -} \ No newline at end of file diff --git a/scripts/build/package/package_filelists/symbols.json b/scripts/build/package/package_filelists/symbols.json deleted file mode 100644 index 3f30f6ec1f..0000000000 --- a/scripts/build/package/package_filelists/symbols.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "@lyengine": { - "**/*.pdb": "#include" - } -} \ No newline at end of file diff --git a/scripts/build/package/platform_exclusions.json b/scripts/build/package/platform_exclusions.json deleted file mode 100644 index f54aeb07c9..0000000000 --- a/scripts/build/package/platform_exclusions.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "all": { - "@lyengine": { - "**/Gems/Atom/RHI/DX12/External/pix/**": "#exclude", - "**/.idea/**": "#exclude", - "**/*.csproj*": "#exclude", - "**/.owner": "#exclude", - "**/WinPixEventRuntime.dll": "#exclude", - "**/XenonConsole.exe": "#exclude" - } - } -} diff --git a/scripts/build/package/util.py b/scripts/util/util.py old mode 100755 new mode 100644 similarity index 78% rename from scripts/build/package/util.py rename to scripts/util/util.py index bed2b79833..18970e55b9 --- a/scripts/build/package/util.py +++ b/scripts/util/util.py @@ -13,26 +13,11 @@ import sys import subprocess -class LyBuildError(Exception): - def __init__(self, message): - super(LyBuildError, self).__init__(message) - - -def ly_build_error(message): - raise LyBuildError(message) - - def error(message): print(('Error: {}'.format(message))) exit(1) -# Exit with status code 0 means it won't fail the whole build process -def safe_exit_with_error(message): - print(('Error: {}'.format(message))) - exit(0) - - def warn(message): print(('Warning: {}'.format(message))) From 816d1f1b3de8c0c97cbca226a05be45f31a574bf Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Wed, 1 Dec 2021 11:07:11 -0700 Subject: [PATCH 58/72] Add CLI option to enable PIX GPU events without expressing loading the Pix runtime Signed-off-by: Jeremy Ong --- Gems/Atom/RHI/Code/Include/Atom/RHI/Factory.h | 3 +++ Gems/Atom/RHI/Code/Source/RHI/Factory.cpp | 13 +++++++++++++ Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.cpp | 4 ++-- Gems/Atom/RHI/DX12/Code/Source/RHI/Scope.cpp | 4 ++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/Factory.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/Factory.h index 71f9f1605b..1755d45a74 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/Factory.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/Factory.h @@ -112,6 +112,9 @@ namespace AZ //! Returns true if Pix dll is loaded static bool IsPixModuleLoaded(); + //! Returns true if Pix GPU events should be emitted + static bool PixGpuEventsEnabled(); + //! Returns true if Warp is enabled static bool UsingWarpDevice(); diff --git a/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp b/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp index 82b0a13c86..9146175252 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp @@ -26,6 +26,7 @@ static bool s_isRenderDocDllLoaded = false; #if defined(USE_PIX) static AZStd::unique_ptr s_pixModule; static bool s_isPixGpuCaptureDllLoaded = false; +static bool s_pixGpuMarkersEnabled = false; #endif static bool s_usingWarpDevice = false; @@ -62,6 +63,7 @@ namespace AZ #if defined(USE_RENDERDOC) // If RenderDoc is requested, we need to load the library as early as possible (before device queries/factories are made) bool enableRenderDoc = RHI::QueryCommandLineOption("enableRenderDoc"); + s_pixGpuMarkersEnabled = s_pixGpuMarkersEnabled || enableRenderDoc; if (enableRenderDoc && AZ_TRAIT_RENDERDOC_MODULE && !s_renderDocModule) { @@ -119,6 +121,8 @@ namespace AZ //Pix dll can still be injected even if we do not pass in enablePixGPU. This can be done if we launch the app from Pix. s_isPixGpuCaptureDllLoaded = Platform::IsPixDllInjected(AZ_TRAIT_PIX_MODULE); + + s_pixGpuMarkersEnabled = s_pixGpuMarkersEnabled || RHI::QueryCommandLineOption("enablePixGpuMarkers"); #endif } @@ -202,6 +206,15 @@ namespace AZ #endif } + bool Factory::PixGpuEventsEnabled() + { +#if defined(USE_PIX) + return s_pixGpuMarkersEnabled; +#else + return false; +#endif + } + bool Factory::UsingWarpDevice() { return s_usingWarpDevice; diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.cpp index 1ee35c513a..07cf3bf8ad 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/CommandList.cpp @@ -97,7 +97,7 @@ namespace AZ SetName(name); PIXBeginEvent(PIX_MARKER_CMDLIST_COL, name.GetCStr()); - if (RHI::Factory::Get().IsPixModuleLoaded() || RHI::Factory::Get().IsRenderDocModuleLoaded()) + if (RHI::Factory::Get().PixGpuEventsEnabled()) { PIXBeginEvent(GetCommandList(), PIX_MARKER_CMDLIST_COL, name.GetCStr()); } @@ -107,7 +107,7 @@ namespace AZ { FlushBarriers(); PIXEndEvent(); - if (RHI::Factory::Get().IsPixModuleLoaded() || RHI::Factory::Get().IsRenderDocModuleLoaded()) + if (RHI::Factory::Get().PixGpuEventsEnabled()) { PIXEndEvent(GetCommandList()); } diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/Scope.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/Scope.cpp index cea072954a..b29018a2ac 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/Scope.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/Scope.cpp @@ -311,7 +311,7 @@ namespace AZ PIXBeginEvent(0xFFFF00FF, GetId().GetCStr()); - if (RHI::Factory::Get().IsPixModuleLoaded() || RHI::Factory::Get().IsRenderDocModuleLoaded()) + if (RHI::Factory::Get().PixGpuEventsEnabled()) { PIXBeginEvent(commandList.GetCommandList(), 0xFFFF00FF, GetId().GetCStr()); } @@ -428,7 +428,7 @@ namespace AZ } } - if (RHI::Factory::Get().IsPixModuleLoaded() || RHI::Factory::Get().IsRenderDocModuleLoaded()) + if (RHI::Factory::Get().PixGpuEventsEnabled()) { PIXEndEvent(commandList.GetCommandList()); } From e8750f80968dca244dcf1d404196157c1533c9ad Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Wed, 1 Dec 2021 13:16:19 -0600 Subject: [PATCH 59/72] Rename sr_regset-file CVar to sr_regset_file (#6067) The Legacy Cry XConsole code validates that CVars only contain underscore and alphanumeric characters via an Assert in `debug` configurations. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h index 1807a27604..2e37431839 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryConsoleUtils.h @@ -23,7 +23,7 @@ namespace AZ::SettingsRegistryConsoleUtils inline constexpr const char* SettingsRegistryRemove = "sr_regremove"; inline constexpr const char* SettingsRegistryDump = "sr_regdump"; inline constexpr const char* SettingsRegistryDumpAll = "sr_regdumpall"; - inline constexpr const char* SettingsRegistryMergeFile = "sr_regset-file"; + inline constexpr const char* SettingsRegistryMergeFile = "sr_regset_file"; // RAII structure which owns the instances of the Settings Registry Console commands // registered with an AZ Console @@ -53,7 +53,7 @@ namespace AZ::SettingsRegistryConsoleUtils //! "sr_regdumpall" accepts 0 arguments and dumps the entire settings registry //! NOTE: this might result in a large amount of output to the console //! - //! "sr_regset-file" accepts 1 or 2 arguments - [] + //! "sr_regset_file" accepts 1 or 2 arguments - [] //! Merges the json formatted file into the settings registry underneath the root anchor "" //! or if supplied [[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole); From 68bf7c85edca6a1676e40ecb61e4a7e0b19e8e2b Mon Sep 17 00:00:00 2001 From: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> Date: Wed, 1 Dec 2021 13:17:08 -0600 Subject: [PATCH 60/72] Adding setup step to remove temporary level that fails to cleanup (#6056) * Adding setup step to remove temporary level that fails to cleanup with test teardown Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> * Adding new create_level to TestHelper class with additional error logging Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> * Cleaning up custom setup/teardown Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com> --- .../editor_python_test_tools/utils.py | 32 +++++++++++++ ...ynamicSliceInstanceSpawner_Embedded_E2E.py | 4 +- ...ynamicSliceInstanceSpawner_External_E2E.py | 4 +- .../EditorScripts/LayerBlender_E2E_Editor.py | 4 +- .../dyn_veg/TestSuite_Main_Optimized.py | 47 ++++++++++++------- 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py index 481d73274f..212c862efd 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py @@ -34,6 +34,38 @@ class TestHelper: # JIRA: SPEC-2880 # general.idle_wait_frames(1) + @staticmethod + def create_level(level_name: str) -> bool: + """ + :param level_name: The name of the level to be created + :return: True if ECreateLevelResult returns 0, False otherwise with logging to report reason + """ + Report.info(f"Creating level {level_name}") + + # Use these hardcoded values to pass expected values for old terrain system until new create_level API is + # available + heightmap_resolution = 1024 + heightmap_meters_per_pixel = 1 + terrain_texture_resolution = 4096 + use_terrain = False + + result = general.create_level_no_prompt(level_name, heightmap_resolution, heightmap_meters_per_pixel, + terrain_texture_resolution, use_terrain) + + # Result codes are ECreateLevelResult defined in CryEdit.h + if result == 1: + Report.info(f"{level_name} level already exists") + elif result == 2: + Report.info("Failed to create directory") + elif result == 3: + Report.info("Directory length is too long") + elif result != 0: + Report.info("Unknown error, failed to create level") + else: + Report.info(f"{level_name} level created successfully") + + return result == 0 + @staticmethod def open_level(directory : str, level : str): # type: (str, str) -> None diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py index 84c661873c..fa45e057e2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py @@ -72,9 +72,9 @@ def DynamicSliceInstanceSpawner_Embedded_E2E(): # 1) Create a new, temporary level lvl_name = "tmp_level" helper.init_idle() - level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False) + level_created = helper.create_level(lvl_name) general.idle_wait(1.0) - Report.critical_result(Tests.level_created, level_created == 0) + Report.critical_result(Tests.level_created, level_created) general.set_current_view_position(512.0, 480.0, 38.0) # 2) Create a new entity with required vegetation area components and Script Canvas component for launcher test diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py index de2554034f..2353095849 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py @@ -73,9 +73,9 @@ def DynamicSliceInstanceSpawner_External_E2E(): # 1) Create a new, temporary level lvl_name = "tmp_level" helper.init_idle() - level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False) + level_created = helper.create_level(lvl_name) general.idle_wait(1.0) - Report.critical_result(Tests.level_created, level_created == 0) + Report.critical_result(Tests.level_created, level_created) general.set_current_view_position(512.0, 480.0, 38.0) # 2) Create a new entity with required vegetation area components and switch the Vegetation Asset List Source diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py index bf6501f469..130d56937b 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py @@ -76,9 +76,9 @@ def LayerBlender_E2E_Editor(): # 1) Create a new, temporary level lvl_name = "tmp_level" helper.init_idle() - level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False) + level_created = helper.create_level(lvl_name) general.idle_wait(1.0) - Report.critical_result(Tests.level_created, level_created == 0) + Report.critical_result(Tests.level_created, level_created) general.set_current_view_position(500.49, 498.69, 46.66) general.set_current_view_rotation(-42.05, 0.00, -36.33) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py index 2211c28060..673e40e397 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py @@ -18,6 +18,17 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, E class TestAutomation(EditorTestSuite): enable_prefab_system = False + + # Helpers for test asset cleanup + def cleanup_test_level(self, workspace): + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], + True, True) + + def cleanup_test_slices(self, workspace): + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices", + "TestSlice_1.slice")], True, True) + file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices", + "TestSlice_2.slice")], True, True) class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorParallelTest): from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module @@ -37,10 +48,7 @@ class TestAutomation(EditorTestSuite): class test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(EditorSingleTest): # Custom teardown to remove slice asset created during test def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices", - "TestSlice_1.slice")], True, True) - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices", - "TestSlice_2.slice")], True, True) + TestAutomation.cleanup_test_slices(self, workspace) from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorParallelTest): @@ -148,29 +156,32 @@ class TestAutomation(EditorTestSuite): class test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(EditorParallelTest): from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module - @pytest.mark.xfail(reason="Intermittently fails to create level") class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest): from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module - # Custom teardown to remove test level created during test - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], - True, True) + # Custom setup/teardown to remove test level created during test + def setup(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) - @pytest.mark.xfail(reason="Intermittently fails to create level") class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest): from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module - # Custom teardown to remove test level created during test - def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], - True, True) + # Custom setup/teardown to remove test level created during test + def setup(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) - @pytest.mark.xfail(reason="Intermittently fails to create level") class test_LayerBlender_E2E_Editor(EditorSingleTest): from .EditorScripts import LayerBlender_E2E_Editor as test_module - # Custom teardown to remove test level created during test + # Custom setup/teardown to remove test level created during test + def setup(self, request, workspace, editor, editor_test_results, launcher_platform): + TestAutomation.cleanup_test_level(self, workspace) + def teardown(self, request, workspace, editor, editor_test_results, launcher_platform): - file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")], - True, True) + TestAutomation.cleanup_test_level(self, workspace) From e16781e6b6b58b7d9db60b39de3152d8d5f2e9f6 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Wed, 1 Dec 2021 12:24:49 -0800 Subject: [PATCH 61/72] LYN-8629 | Read-Only Entities - Setup (#6059) * Introduce read-only entity interface, handler and unit tests. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Switch from a push paradigm to a pull paradigm - handlers get to implement logic to determine if an entity should be read-only. This allows multiple systems to weigh into whether an entity is read-only. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fixed to missing call in test Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Renaming ReadOnlyEntityQueryNotificationBus to ReadOnlyEntityQueryRequestBus for consistency with engine patterns. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- .../Application/ToolsApplication.cpp | 2 + .../AzToolsFrameworkModule.cpp | 2 + .../Entity/ReadOnly/ReadOnlyEntityBus.h | 63 +++++++++ .../Entity/ReadOnly/ReadOnlyEntityInterface.h | 43 ++++++ .../ReadOnlyEntitySystemComponent.cpp | 99 ++++++++++++++ .../ReadOnly/ReadOnlyEntitySystemComponent.h | 56 ++++++++ .../aztoolsframework_files.cmake | 4 + .../Entity/ReadOnly/ReadOnlyEntityFixture.cpp | 125 ++++++++++++++++++ .../Entity/ReadOnly/ReadOnlyEntityFixture.h | 78 +++++++++++ .../Entity/ReadOnly/ReadOnlyEntityTests.cpp | 99 ++++++++++++++ .../Tests/aztoolsframeworktests_files.cmake | 3 + 11 files changed, 574 insertions(+) create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityBus.h create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.cpp create mode 100644 Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.h create mode 100644 Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.cpp create mode 100644 Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.h create mode 100644 Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityTests.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp index afabbb233b..6c69fc04da 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -268,6 +269,7 @@ namespace AzToolsFramework azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), + azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp index 2cdf409125..dd1ac12a02 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,7 @@ namespace AzToolsFramework EditorEntityFixupComponent::CreateDescriptor(), EntityUtilityComponent::CreateDescriptor(), ContainerEntitySystemComponent::CreateDescriptor(), + ReadOnlyEntitySystemComponent::CreateDescriptor(), FocusModeSystemComponent::CreateDescriptor(), SliceMetadataEntityContextComponent::CreateDescriptor(), SliceRequestComponent::CreateDescriptor(), diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityBus.h new file mode 100644 index 0000000000..051e87c7e0 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityBus.h @@ -0,0 +1,63 @@ +/* + * 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 + +namespace AzToolsFramework +{ + //! Used to notify changes of state for read-only entities. + class ReadOnlyEntityPublicNotifications + : public AZ::EBusTraits + { + public: + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; + using BusIdType = AzFramework::EntityContextId; + ////////////////////////////////////////////////////////////////////////// + + //! Triggered when an entity's read-only status changes. + //! @param entityId The entity whose status has changed. + //! @param readOnly The read-only state the container was changed to. + virtual void OnReadOnlyEntityStatusChanged([[maybe_unused]] const AZ::EntityId& entityId, [[maybe_unused]] bool readOnly) {} + + protected: + ~ReadOnlyEntityPublicNotifications() = default; + }; + using ReadOnlyEntityPublicNotificationBus = AZ::EBus; + + //! Used by the ReadOnlyEntitySystemComponent to query the read-only state of entities as set by systems using the API. + class ReadOnlyEntityQueryRequests + : public AZ::EBusTraits + { + public: + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; + using BusIdType = AzFramework::EntityContextId; + ////////////////////////////////////////////////////////////////////////// + + //! Triggered when an entity's read-only status is queried. + //! Allows multiple systems to weigh in on the read-only status of an entity. + //! @param entityId The entity whose status has changed. + //! @param[out] isReadOnly The output of the query. Should only be changed to true, and left untouched if false. + virtual void IsReadOnly(const AZ::EntityId& entityId, bool& isReadOnly) = 0; + + protected: + ~ReadOnlyEntityQueryRequests() = default; + }; + using ReadOnlyEntityQueryRequestBus = AZ::EBus; + +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h new file mode 100644 index 0000000000..15ac04d0fd --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h @@ -0,0 +1,43 @@ +/* + * 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 + +namespace AzToolsFramework +{ + //! An entity registered as read-only cannot be altered in the editor. + class ReadOnlyEntityPublicInterface + { + public: + AZ_RTTI(ReadOnlyEntityPublicInterface, "{921FE15B-6EBD-47F0-8238-BC63318DEDEA}"); + + //! Returns whether the entity id provided is registered as read-only. + virtual bool IsReadOnly(const AZ::EntityId& entityId) = 0; + }; + + //! An entity registered as read-only cannot be altered in the editor. + class ReadOnlyEntityQueryInterface + { + public: + AZ_RTTI(ReadOnlyEntityQueryInterface, "{2ACD63C5-1F3E-4DE8-880E-8115F857D329}"); + + //! Refreshes the cached read-only status for the entities provided. + //! @param entityIds The entityIds whose read-only state will be queried again. + virtual void RefreshReadOnlyState(const EntityIdList& entityIds) = 0; + + //! Refreshes the cached read-only status for all entities. + //! Useful when disconnecting a handler at runtime. + virtual void RefreshReadOnlyStateForAllEntities() = 0; + }; + +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.cpp new file mode 100644 index 0000000000..f7f36177c9 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.cpp @@ -0,0 +1,99 @@ +/* + * 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 + +namespace AzToolsFramework +{ + void ReadOnlyEntitySystemComponent::Activate() + { + AZ::Interface::Register(this); + AZ::Interface::Register(this); + EditorEntityContextNotificationBus::Handler::BusConnect(); + } + + void ReadOnlyEntitySystemComponent::Deactivate() + { + EditorEntityContextNotificationBus::Handler::BusDisconnect(); + AZ::Interface::Unregister(this); + AZ::Interface::Unregister(this); + } + + void ReadOnlyEntitySystemComponent::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class()->Version(1); + } + } + + void ReadOnlyEntitySystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("ReadOnlyEntityService")); + } + + bool ReadOnlyEntitySystemComponent::IsReadOnly(const AZ::EntityId& entityId) + { + if (!m_readOnlystates.contains(entityId)) + { + QueryReadOnlyStateForEntity(entityId); + } + + return m_readOnlystates[entityId]; + } + + void ReadOnlyEntitySystemComponent::RefreshReadOnlyState(const EntityIdList& entityIds) + { + for (const AZ::EntityId entityId : entityIds) + { + bool wasReadOnly = m_readOnlystates[entityId]; + QueryReadOnlyStateForEntity(entityId); + + if (bool isReadOnly = m_readOnlystates[entityId]; wasReadOnly != isReadOnly) + { + ReadOnlyEntityPublicNotificationBus::Broadcast( + &ReadOnlyEntityPublicNotificationBus::Events::OnReadOnlyEntityStatusChanged, entityId, isReadOnly); + } + } + } + + void ReadOnlyEntitySystemComponent::RefreshReadOnlyStateForAllEntities() + { + for (auto elem : m_readOnlystates) + { + AZ::EntityId entityId = elem.first; + bool wasReadOnly = m_readOnlystates[entityId]; + QueryReadOnlyStateForEntity(entityId); + + if (bool isReadOnly = m_readOnlystates[entityId]; wasReadOnly != isReadOnly) + { + ReadOnlyEntityPublicNotificationBus::Broadcast( + &ReadOnlyEntityPublicNotificationBus::Events::OnReadOnlyEntityStatusChanged, entityId, isReadOnly); + } + } + } + + void ReadOnlyEntitySystemComponent::OnContextReset() + { + m_readOnlystates.clear(); + } + + void ReadOnlyEntitySystemComponent::QueryReadOnlyStateForEntity(const AZ::EntityId& entityId) + { + bool isReadOnly = false; + + ReadOnlyEntityQueryRequestBus::Broadcast( + &ReadOnlyEntityQueryRequestBus::Events::IsReadOnly, entityId, isReadOnly); + + m_readOnlystates[entityId] = isReadOnly; + } + +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.h new file mode 100644 index 0000000000..efc91e9d89 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/ReadOnly/ReadOnlyEntitySystemComponent.h @@ -0,0 +1,56 @@ +/* + * 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 + +namespace AzToolsFramework +{ + //! System Component to track read-only entity registration. + //! An entity registered as ReadOnly cannot be altered in the Editor. + class ReadOnlyEntitySystemComponent final + : public AZ::Component + , private ReadOnlyEntityPublicInterface + , private ReadOnlyEntityQueryInterface + , private EditorEntityContextNotificationBus::Handler + { + public: + AZ_COMPONENT(ReadOnlyEntitySystemComponent, "{B32EB03F-D88F-4B3A-9C16-071AF04DA646}"); + + ReadOnlyEntitySystemComponent() = default; + virtual ~ReadOnlyEntitySystemComponent() = default; + + // AZ::Component overrides ... + void Activate() override; + void Deactivate() override; + + static void Reflect(AZ::ReflectContext* context); + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + + // ReadOnlyEntityPublicNotifications overrides ... + bool IsReadOnly(const AZ::EntityId& entityId) override; + + // ReadOnlyEntityQueryInterface overrides ... + void RefreshReadOnlyState(const EntityIdList& entityIds) override; + void RefreshReadOnlyStateForAllEntities() override; + + // EditorEntityContextNotificationBus overrides ... + void OnContextReset() override; + + private: + void QueryReadOnlyStateForEntity(const AZ::EntityId& entityId); + + AZStd::unordered_map m_readOnlystates; + }; + +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index bdf6abe141..a6c9adb19e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -159,6 +159,10 @@ set(FILES Entity/SliceEditorEntityOwnershipServiceBus.h Entity/EntityUtilityComponent.h Entity/EntityUtilityComponent.cpp + Entity/ReadOnly/ReadOnlyEntityInterface.h + Entity/ReadOnly/ReadOnlyEntityBus.h + Entity/ReadOnly/ReadOnlyEntitySystemComponent.cpp + Entity/ReadOnly/ReadOnlyEntitySystemComponent.h Fingerprinting/TypeFingerprinter.h Fingerprinting/TypeFingerprinter.cpp FocusMode/FocusModeInterface.h diff --git a/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.cpp b/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.cpp new file mode 100644 index 0000000000..d80ecebce0 --- /dev/null +++ b/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.cpp @@ -0,0 +1,125 @@ +/* + * 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 AzToolsFramework +{ + void ReadOnlyEntityFixture::SetUpEditorFixtureImpl() + { + // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is + // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash + // in the unit tests. + AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); + + m_readOnlyEntityPublicInterface = AZ::Interface::Get(); + ASSERT_TRUE(m_readOnlyEntityPublicInterface != nullptr); + + GenerateTestHierarchy(); + } + + void ReadOnlyEntityFixture::TearDownEditorFixtureImpl() + { + } + + void ReadOnlyEntityFixture::GenerateTestHierarchy() + { + /* + * Root + * |_ Child + * |_ GrandChild1 + * |_ GrandChild2 + */ + + m_entityMap[RootEntityName] = CreateEditorEntity(RootEntityName, AZ::EntityId()); + m_entityMap[ChildEntityName] = CreateEditorEntity(ChildEntityName, m_entityMap[RootEntityName]); + m_entityMap[GrandChild1EntityName] = CreateEditorEntity(GrandChild1EntityName, m_entityMap[ChildEntityName]); + m_entityMap[GrandChild2EntityName] = CreateEditorEntity(GrandChild2EntityName, m_entityMap[ChildEntityName]); + } + + AZ::EntityId ReadOnlyEntityFixture::CreateEditorEntity(const char* name, AZ::EntityId parentId) + { + AZ::Entity* entity = nullptr; + UnitTest::CreateDefaultEditorEntity(name, &entity); + + // Parent + AZ::TransformBus::Event(entity->GetId(), &AZ::TransformInterface::SetParent, parentId); + + return entity->GetId(); + } + + ReadOnlyHandlerAlwaysTrue::ReadOnlyHandlerAlwaysTrue() + { + auto editorEntityContextId = AzFramework::EntityContextId::CreateNull(); + EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId); + + ReadOnlyEntityQueryRequestBus::Handler::BusConnect(editorEntityContextId); + } + + ReadOnlyHandlerAlwaysTrue::~ReadOnlyHandlerAlwaysTrue() + { + ReadOnlyEntityQueryRequestBus::Handler::BusDisconnect(); + + if (auto readOnlyEntityQueryInterface = AZ::Interface::Get()) + { + readOnlyEntityQueryInterface->RefreshReadOnlyStateForAllEntities(); + } + } + + void ReadOnlyHandlerAlwaysTrue::IsReadOnly([[maybe_unused]] const AZ::EntityId& entityId, bool& isReadOnly) + { + isReadOnly = true; + } + + ReadOnlyHandlerAlwaysFalse::ReadOnlyHandlerAlwaysFalse() + { + auto editorEntityContextId = AzFramework::EntityContextId::CreateNull(); + EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId); + + ReadOnlyEntityQueryRequestBus::Handler::BusConnect(editorEntityContextId); + } + + ReadOnlyHandlerAlwaysFalse::~ReadOnlyHandlerAlwaysFalse() + { + ReadOnlyEntityQueryRequestBus::Handler::BusDisconnect(); + + if (auto readOnlyEntityQueryInterface = AZ::Interface::Get()) + { + readOnlyEntityQueryInterface->RefreshReadOnlyStateForAllEntities(); + } + } + + ReadOnlyHandlerEntityId::ReadOnlyHandlerEntityId(AZ::EntityId entityId) + : m_entityId(entityId) + { + auto editorEntityContextId = AzFramework::EntityContextId::CreateNull(); + EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId); + + ReadOnlyEntityQueryRequestBus::Handler::BusConnect(editorEntityContextId); + } + + ReadOnlyHandlerEntityId::~ReadOnlyHandlerEntityId() + { + ReadOnlyEntityQueryRequestBus::Handler::BusDisconnect(); + + if (auto readOnlyEntityQueryInterface = AZ::Interface::Get()) + { + readOnlyEntityQueryInterface->RefreshReadOnlyStateForAllEntities(); + } + } + + void ReadOnlyHandlerEntityId::IsReadOnly(const AZ::EntityId& entityId, bool& isReadOnly) + { + if (entityId == m_entityId) + { + isReadOnly = true; + } + } +} diff --git a/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.h b/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.h new file mode 100644 index 0000000000..72fff56c6a --- /dev/null +++ b/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityFixture.h @@ -0,0 +1,78 @@ +/* + * 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 + +namespace AzToolsFramework +{ + class ReadOnlyEntityFixture + : public UnitTest::ToolsApplicationFixture + { + protected: + void SetUpEditorFixtureImpl() override; + void TearDownEditorFixtureImpl() override; + + void GenerateTestHierarchy(); + AZ::EntityId CreateEditorEntity(const char* name, AZ::EntityId parentId); + + AZStd::unordered_map m_entityMap; + + ReadOnlyEntityPublicInterface* m_readOnlyEntityPublicInterface = nullptr; + + public: + inline static const char* RootEntityName = "Root"; + inline static const char* ChildEntityName = "Child"; + inline static const char* GrandChild1EntityName = "GrandChild1"; + inline static const char* GrandChild2EntityName = "GrandChild2"; + }; + + class ReadOnlyHandlerAlwaysTrue + : public ReadOnlyEntityQueryRequestBus::Handler + { + public: + ReadOnlyHandlerAlwaysTrue(); + ~ReadOnlyHandlerAlwaysTrue(); + + // ReadOnlyEntityQueryNotificationBus overrides ... + void IsReadOnly(const AZ::EntityId& entityId, bool& isReadOnly) override; + }; + + class ReadOnlyHandlerAlwaysFalse + : public ReadOnlyEntityQueryRequestBus::Handler + { + public: + ReadOnlyHandlerAlwaysFalse(); + ~ReadOnlyHandlerAlwaysFalse(); + + // ReadOnlyEntityQueryNotificationBus overrides ... + void IsReadOnly([[maybe_unused]] const AZ::EntityId& entityId, [[maybe_unused]] bool& isReadOnly) override {} + }; + + class ReadOnlyHandlerEntityId + : public ReadOnlyEntityQueryRequestBus::Handler + { + public: + ReadOnlyHandlerEntityId(AZ::EntityId entityId); + ~ReadOnlyHandlerEntityId(); + + // ReadOnlyEntityQueryNotificationBus overrides ... + void IsReadOnly(const AZ::EntityId& entityId, bool& isReadOnly) override; + + private: + AZ::EntityId m_entityId; + }; +} diff --git a/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityTests.cpp b/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityTests.cpp new file mode 100644 index 0000000000..532325e208 --- /dev/null +++ b/Code/Framework/AzToolsFramework/Tests/Entity/ReadOnly/ReadOnlyEntityTests.cpp @@ -0,0 +1,99 @@ +/* + * 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 + +namespace AzToolsFramework +{ + TEST_F(ReadOnlyEntityFixture, NoHandlerEntityIsNotReadOnlyByDefault) + { + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + } + + TEST_F(ReadOnlyEntityFixture, SingleHandlerEntityIsReadOnly) + { + // Create a handler that sets all entities to read-only. + ReadOnlyHandlerAlwaysTrue alwaysTrueHandler; + + // All entities should be marked read-only now. + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[RootEntityName])); + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild1EntityName])); + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild2EntityName])); + } + + TEST_F(ReadOnlyEntityFixture, SingleHandlerEntityIsNotReadOnly) + { + // Create a handler that sets all entities to read-only. + ReadOnlyHandlerAlwaysFalse alwaysFalseHandler; + + // All entities should not be marked read-only now. + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[RootEntityName])); + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild1EntityName])); + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild2EntityName])); + } + + TEST_F(ReadOnlyEntityFixture, SingleHandlerWithLogic) + { + // Create a handler that sets just the child entity to read-only. + ReadOnlyHandlerEntityId entityIdHandler(m_entityMap[ChildEntityName]); + + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[RootEntityName])); + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild1EntityName])); + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild2EntityName])); + } + + TEST_F(ReadOnlyEntityFixture, TwoHandlersCanOverlap) + { + // Create two handlers that set different entities to read-only. + ReadOnlyHandlerEntityId entityIdHandler1(m_entityMap[ChildEntityName]); + ReadOnlyHandlerEntityId entityIdHandler2(m_entityMap[GrandChild2EntityName]); + + // Both entities should be marked as read-only, while others aren't. + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[RootEntityName])); + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild1EntityName])); + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[GrandChild2EntityName])); + } + + TEST_F(ReadOnlyEntityFixture, EnsureCacheIsRefreshedCorrectly) + { + // Verify the child entity is not marked as read-only + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + + // Create a handler that sets the child entity to read-only. + ReadOnlyHandlerEntityId entityIdHandler(m_entityMap[ChildEntityName]); + + // Communicate to the ReadOnlyEntitySystemComponent that the read-only state for the child entity may have changed. + // Note that this operation would usually be executed by the handler, hence the Query interface call. + if (auto readOnlyEntityQueryInterface = AZ::Interface::Get()) + { + readOnlyEntityQueryInterface->RefreshReadOnlyState({ m_entityMap[ChildEntityName] }); + } + + // Verify the child entity is marked as read-only + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + } + + TEST_F(ReadOnlyEntityFixture, EnsureCacheIsClearedCorrectly) + { + { + // Create a handler that sets the child entity to read-only. + ReadOnlyHandlerEntityId entityIdHandler(m_entityMap[ChildEntityName]); + + // Verify the child entity is marked as read-only + EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + } + // When the handler goes out of scope, it calls RefreshReadOnlyStateForAllEntities and refreshes the cache. + + // Verify the child entity is no longer marked as read-only + EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName])); + } +} diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 8e0297fb1f..b2b50ca7c6 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -28,6 +28,9 @@ set(FILES Entity/EditorEntitySearchComponentTests.cpp Entity/EditorEntitySelectionTests.cpp Entity/EntityUtilityComponentTests.cpp + Entity/ReadOnly/ReadOnlyEntityFixture.cpp + Entity/ReadOnly/ReadOnlyEntityFixture.h + Entity/ReadOnly/ReadOnlyEntityTests.cpp EntityIdQLabelTests.cpp EntityInspectorTests.cpp EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp From 26e8fd59ebfe4fb47587b7e1955b7f689b96b341 Mon Sep 17 00:00:00 2001 From: tjmgd <92784061+tjmgd@users.noreply.github.com> Date: Wed, 1 Dec 2021 21:05:57 +0000 Subject: [PATCH 62/72] Fix for bug while deleting file. This is due to a problem in the file path. (#5948) Signed-off-by: T.J. McGrath-Daly Co-authored-by: Tobias Alexander Franke --- Gems/AudioSystem/Code/Source/Editor/AudioControlsWriter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/AudioSystem/Code/Source/Editor/AudioControlsWriter.cpp b/Gems/AudioSystem/Code/Source/Editor/AudioControlsWriter.cpp index eb022b706f..86f778bf03 100644 --- a/Gems/AudioSystem/Code/Source/Editor/AudioControlsWriter.cpp +++ b/Gems/AudioSystem/Code/Source/Editor/AudioControlsWriter.cpp @@ -102,7 +102,8 @@ namespace AudioControls for (auto it = librariesToDelete.begin(); it != librariesToDelete.end(); ++it) { - DeleteLibraryFile((*it).c_str()); + auto newPathOpt = fileIO->ResolvePath(AZ::IO::PathView{ *it }); + DeleteLibraryFile(newPathOpt.value().Native()); } previousLibraryPaths = m_foundLibraryPaths; From 8feb4a1ff7a590b2a84c0594ff985e4983dcb139 Mon Sep 17 00:00:00 2001 From: tjmgd <92784061+tjmgd@users.noreply.github.com> Date: Wed, 1 Dec 2021 21:06:22 +0000 Subject: [PATCH 63/72] Fix for bug cause by null pointer when loading audio library (#5945) Signed-off-by: T.J. McGrath-Daly Co-authored-by: Tobias Alexander Franke --- Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp index 9efbd1d881..992434ff79 100644 --- a/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp +++ b/Gems/AudioSystem/Code/Source/Engine/FileCacheManager.cpp @@ -819,6 +819,11 @@ namespace Audio } else { + if (!audioFileEntry->m_asyncStreamRequest) + { + audioFileEntry->m_asyncStreamRequest = streamer->CreateRequest(); + } + streamer->Read( audioFileEntry->m_asyncStreamRequest, audioFileEntry->m_filePath.c_str(), From f97ec14cf8bb8354ca59d845f79d5b4b55897f9d Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 1 Dec 2021 15:44:03 -0600 Subject: [PATCH 64/72] Procedural Prefabs: Add example LOD script (#6057) * Auto LOD script setup Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Working auto LODs Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Correctly selected LODs and added default prefab Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Cleanup code Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Cleanup code Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> * Add missing legal header, move name cleanup to scene_helpers, add documentation Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com> --- AutomatedTesting/Editor/Scripts/auto_lod.py | 124 +++++++++++++++++ .../Editor/Scripts/scene_helpers.py | 95 +++++++++++++ .../Editor/Scripts/scene_mesh_to_prefab.py | 131 ++++++------------ AutomatedTesting/Objects/sphere_5lods.fbx | 3 + .../Objects/sphere_5lods.fbx.assetinfo | 8 ++ 5 files changed, 272 insertions(+), 89 deletions(-) create mode 100644 AutomatedTesting/Editor/Scripts/auto_lod.py create mode 100644 AutomatedTesting/Editor/Scripts/scene_helpers.py create mode 100644 AutomatedTesting/Objects/sphere_5lods.fbx create mode 100644 AutomatedTesting/Objects/sphere_5lods.fbx.assetinfo diff --git a/AutomatedTesting/Editor/Scripts/auto_lod.py b/AutomatedTesting/Editor/Scripts/auto_lod.py new file mode 100644 index 0000000000..058303242a --- /dev/null +++ b/AutomatedTesting/Editor/Scripts/auto_lod.py @@ -0,0 +1,124 @@ +# +# 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 os, traceback, binascii, sys, json, pathlib, logging +import azlmbr.math +import azlmbr.bus +from scene_helpers import * + +# +# SceneAPI Processor +# + +def update_manifest(scene): + import uuid + import azlmbr.scene as sceneApi + import azlmbr.scene.graph + from scene_api import scene_data as sceneData + + graph = sceneData.SceneGraph(scene.graph) + # Get a list of all the mesh nodes, as well as all the nodes + mesh_name_list, all_node_paths = get_mesh_node_names(graph) + mesh_name_list.sort(key=lambda node: str.casefold(node.get_path())) + scene_manifest = sceneData.SceneManifest() + + clean_filename = scene.sourceFilename.replace('.', '_') + + # Compute the filename of the scene file + source_basepath = scene.watchFolder + source_relative_path = os.path.dirname(os.path.relpath(clean_filename, source_basepath)) + source_filename_only = os.path.basename(clean_filename) + + created_entities = [] + previous_entity_id = azlmbr.entity.InvalidEntityId + first_mesh = True + + # Make a list of mesh node paths + mesh_path_list = list(map(lambda node: node.get_path(), mesh_name_list)) + + # Assume the first mesh is the main mesh + main_mesh = mesh_name_list[0] + mesh_path = main_mesh.get_path() + + # Create a unique mesh group name using the filename + node name + mesh_group_name = '{}_{}'.format(source_filename_only, main_mesh.get_name()) + # Remove forbidden filename characters from the name since this will become a file on disk later + mesh_group_name = "".join(char for char in mesh_group_name if char not in "|<>:\"/?*\\") + # Add the MeshGroup to the manifest and give it a unique ID + mesh_group = scene_manifest.add_mesh_group(mesh_group_name) + mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, source_filename_only + mesh_path)) + '}' + # Set our current node as the only node that is included in this MeshGroup + scene_manifest.mesh_group_select_node(mesh_group, mesh_path) + + # Explicitly remove all other nodes to prevent implicit inclusions + for node in mesh_path_list: + if node != mesh_path: + scene_manifest.mesh_group_unselect_node(mesh_group, node) + + # Create a LOD rule + lod_rule = scene_manifest.mesh_group_add_lod_rule(mesh_group) + + # Loop all the mesh nodes after the first + for x in mesh_path_list[1:]: + # Add a new LOD level + lod = scene_manifest.lod_rule_add_lod(lod_rule) + # Select the current mesh for this LOD level + scene_manifest.lod_select_node(lod, x) + + # Unselect every other mesh for this LOD level + for y in mesh_path_list: + if y != x: + scene_manifest.lod_unselect_node(lod, y) + + # Create an editor entity + entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name) + # Add an EditorMeshComponent to the entity + editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "AZ::Render::EditorMeshComponent") + # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just created + the azmodel extension + # The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel + # The assetHint will be converted to an AssetId later during prefab loading + json_update = json.dumps({ + "Controller": { "Configuration": { "ModelAsset": { + "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}} + }); + # Apply the JSON above to the component we created + result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update) + + if not result: + raise RuntimeError("UpdateComponentForEntity failed for Mesh component") + + create_prefab(scene_manifest, source_filename_only, [entity_id]) + + # Convert the manifest to a JSON string and return it + new_manifest = scene_manifest.export() + + return new_manifest + +sceneJobHandler = None + +def on_update_manifest(args): + try: + scene = args[0] + return update_manifest(scene) + except RuntimeError as err: + print (f'ERROR - {err}') + log_exception_traceback() + except: + log_exception_traceback() + + global sceneJobHandler + sceneJobHandler = None + +# try to create SceneAPI handler for processing +try: + import azlmbr.scene as sceneApi + if (sceneJobHandler == None): + sceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler() + sceneJobHandler.connect() + sceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest) +except: + sceneJobHandler = None diff --git a/AutomatedTesting/Editor/Scripts/scene_helpers.py b/AutomatedTesting/Editor/Scripts/scene_helpers.py new file mode 100644 index 0000000000..761068e796 --- /dev/null +++ b/AutomatedTesting/Editor/Scripts/scene_helpers.py @@ -0,0 +1,95 @@ +""" +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 traceback, logging, json +from typing import Tuple, List + +import azlmbr.bus +from scene_api import scene_data as sceneData +from scene_api.scene_data import SceneGraphName + + +def log_exception_traceback(): + """ + Outputs an exception stacktrace. + """ + data = traceback.format_exc() + logger = logging.getLogger('python') + logger.error(data) + + +def sanitize_name_for_disk(name: str): + """ + Removes illegal filename characters from a string. + + :param name: String to clean. + :return: Name with illegal characters removed. + """ + return "".join(char for char in name if char not in "|<>:\"/?*\\") + + +def get_mesh_node_names(scene_graph: sceneData.SceneGraph) -> Tuple[List[SceneGraphName], List[str]]: + """ + Returns a tuple of all the mesh nodes as well as all the node paths + + :param scene_graph: Scene graph to search + :return: Tuple of [Mesh Nodes, All Node Paths] + """ + import azlmbr.scene as sceneApi + import azlmbr.scene.graph + + mesh_data_list = [] + node = scene_graph.get_root() + children = [] + paths = [] + + while node.IsValid(): + # store children to process after siblings + if scene_graph.has_node_child(node): + children.append(scene_graph.get_node_child(node)) + + node_name = sceneData.SceneGraphName(scene_graph.get_node_name(node)) + paths.append(node_name.get_path()) + + # store any node that has mesh data content + node_content = scene_graph.get_node_content(node) + if node_content.CastWithTypeName('MeshData'): + if scene_graph.is_node_end_point(node) is False: + if len(node_name.get_path()): + mesh_data_list.append(sceneData.SceneGraphName(scene_graph.get_node_name(node))) + + # advance to next node + if scene_graph.has_node_sibling(node): + node = scene_graph.get_node_sibling(node) + elif children: + node = children.pop() + else: + node = azlmbr.scene.graph.NodeIndex() + + return mesh_data_list, paths + + +def create_prefab(scene_manifest: sceneData.SceneManifest, prefab_name: str, entities: list) -> None: + prefab_filename = prefab_name + ".prefab" + created_template_id = azlmbr.prefab.PrefabSystemScriptingBus(azlmbr.bus.Broadcast, "CreatePrefab", entities, + prefab_filename) + + if created_template_id is None or created_template_id == azlmbr.prefab.InvalidTemplateId: + raise RuntimeError("CreatePrefab {} failed".format(prefab_filename)) + + # Convert the prefab to a JSON string + output = azlmbr.prefab.PrefabLoaderScriptingBus(azlmbr.bus.Broadcast, "SaveTemplateToString", created_template_id) + + if output is not None and output.IsSuccess(): + json_string = output.GetValue() + uuid = azlmbr.math.Uuid_CreateRandom().ToString() + json_result = json.loads(json_string) + # Add a PrefabGroup to the manifest and store the JSON on it + scene_manifest.add_prefab_group(prefab_name, uuid, json_result) + else: + raise RuntimeError( + "SaveTemplateToString failed for template id {}, prefab {}".format(created_template_id, prefab_filename)) diff --git a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py index 7b9349e270..6151585f26 100644 --- a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py +++ b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py @@ -5,55 +5,16 @@ # SPDX-License-Identifier: Apache-2.0 OR MIT # # -import os, traceback, binascii, sys, json, pathlib, logging -import azlmbr.math import azlmbr.bus +import azlmbr.math + +from scene_helpers import * + # # SceneAPI Processor # - -def log_exception_traceback(): - data = traceback.format_exc() - logger = logging.getLogger('python') - logger.error(data) - -def get_mesh_node_names(sceneGraph): - import azlmbr.scene as sceneApi - import azlmbr.scene.graph - from scene_api import scene_data as sceneData - - meshDataList = [] - node = sceneGraph.get_root() - children = [] - paths = [] - - while node.IsValid(): - # store children to process after siblings - if sceneGraph.has_node_child(node): - children.append(sceneGraph.get_node_child(node)) - - nodeName = sceneData.SceneGraphName(sceneGraph.get_node_name(node)) - paths.append(nodeName.get_path()) - - # store any node that has mesh data content - nodeContent = sceneGraph.get_node_content(node) - if nodeContent.CastWithTypeName('MeshData'): - if sceneGraph.is_node_end_point(node) is False: - if (len(nodeName.get_path())): - meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node))) - - # advance to next node - if sceneGraph.has_node_sibling(node): - node = sceneGraph.get_node_sibling(node) - elif children: - node = children.pop() - else: - node = azlmbr.scene.graph.NodeIndex() - - return meshDataList, paths - def add_material_component(entity_id): # Create an override AZ::Render::EditorMaterialComponent editor_material_component = azlmbr.entity.EntityUtilityBus( @@ -64,24 +25,24 @@ def add_material_component(entity_id): # this fills out the material asset to a known product AZMaterial asset relative path json_update = json.dumps({ - "Controller": { "Configuration": { "materials": [ - { - "Key": {}, - "Value": { "MaterialAsset":{ - "assetHint": "materials/basic_grey.azmaterial" - }} - }] - }} - }); - result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_material_component, json_update) + "Controller": {"Configuration": {"materials": [ + { + "Key": {}, + "Value": {"MaterialAsset": { + "assetHint": "materials/basic_grey.azmaterial" + }} + }] + }} + }) + result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, + editor_material_component, json_update) if not result: raise RuntimeError("UpdateComponentForEntity for editor_material_component failed") + def update_manifest(scene): - import json import uuid, os - import azlmbr.scene as sceneApi import azlmbr.scene.graph from scene_api import scene_data as sceneData @@ -89,9 +50,9 @@ def update_manifest(scene): # Get a list of all the mesh nodes, as well as all the nodes mesh_name_list, all_node_paths = get_mesh_node_names(graph) scene_manifest = sceneData.SceneManifest() - + clean_filename = scene.sourceFilename.replace('.', '_') - + # Compute the filename of the scene file source_basepath = scene.watchFolder source_relative_path = os.path.dirname(os.path.relpath(clean_filename, source_basepath)) @@ -108,7 +69,7 @@ def update_manifest(scene): # Create a unique mesh group name using the filename + node name mesh_group_name = '{}_{}'.format(source_filename_only, mesh_name.get_name()) # Remove forbidden filename characters from the name since this will become a file on disk later - mesh_group_name = "".join(char for char in mesh_group_name if char not in "|<>:\"/?*\\") + mesh_group_name = sanitize_name_for_disk(mesh_group_name) # Add the MeshGroup to the manifest and give it a unique ID mesh_group = scene_manifest.add_mesh_group(mesh_group_name) mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, source_filename_only + mesh_path)) + '}' @@ -129,16 +90,18 @@ def update_manifest(scene): # Create an editor entity entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name) # Add an EditorMeshComponent to the entity - editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "AZ::Render::EditorMeshComponent") - # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just created + the azmodel extension - # The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel - # The assetHint will be converted to an AssetId later during prefab loading + editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", + entity_id, "AZ::Render::EditorMeshComponent") + # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just + # created + the azmodel extension The MeshGroup we created will be output as a product in the asset's path + # named mesh_group_name.azmodel The assetHint will be converted to an AssetId later during prefab loading json_update = json.dumps({ - "Controller": { "Configuration": { "ModelAsset": { - "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}} - }); + "Controller": {"Configuration": {"ModelAsset": { + "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel"}}} + }) # Apply the JSON above to the component we created - result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update) + result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, + editor_mesh_component, json_update) if not result: raise RuntimeError("UpdateComponentForEntity failed for Mesh component") @@ -149,17 +112,19 @@ def update_manifest(scene): add_material_component(entity_id) # Get the transform component - transform_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0") + transform_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", + entity_id, "27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0") # Set this entity to be a child of the last entity we created # This is just an example of how to do parenting and isn't necessarily useful to parent everything like this if previous_entity_id is not None: transform_json = json.dumps({ - "Parent Entity" : previous_entity_id.to_json() - }); + "Parent Entity": previous_entity_id.to_json() + }) # Apply the JSON update - result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, transform_component, transform_json) + result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, + transform_component, transform_json) if not result: raise RuntimeError("UpdateComponentForEntity failed for Transform component") @@ -171,37 +136,23 @@ def update_manifest(scene): created_entities.append(entity_id) # Create a prefab with all our entities - prefab_filename = source_filename_only + ".prefab" - created_template_id = azlmbr.prefab.PrefabSystemScriptingBus(azlmbr.bus.Broadcast, "CreatePrefab", created_entities, prefab_filename) - - if created_template_id == azlmbr.prefab.InvalidTemplateId: - raise RuntimeError("CreatePrefab {} failed".format(prefab_filename)) - - # Convert the prefab to a JSON string - output = azlmbr.prefab.PrefabLoaderScriptingBus(azlmbr.bus.Broadcast, "SaveTemplateToString", created_template_id) - - if output.IsSuccess(): - jsonString = output.GetValue() - uuid = azlmbr.math.Uuid_CreateRandom().ToString() - jsonResult = json.loads(jsonString) - # Add a PrefabGroup to the manifest and store the JSON on it - scene_manifest.add_prefab_group(source_filename_only, uuid, jsonResult) - else: - raise RuntimeError("SaveTemplateToString failed for template id {}, prefab {}".format(created_template_id, prefab_filename)) + create_prefab(scene_manifest, source_filename_only, created_entities) # Convert the manifest to a JSON string and return it new_manifest = scene_manifest.export() return new_manifest + sceneJobHandler = None + def on_update_manifest(args): try: scene = args[0] return update_manifest(scene) except RuntimeError as err: - print (f'ERROR - {err}') + print(f'ERROR - {err}') log_exception_traceback() except: log_exception_traceback() @@ -209,10 +160,12 @@ def on_update_manifest(args): global sceneJobHandler sceneJobHandler = None + # try to create SceneAPI handler for processing try: import azlmbr.scene as sceneApi - if (sceneJobHandler == None): + + if sceneJobHandler is None: sceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler() sceneJobHandler.connect() sceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest) diff --git a/AutomatedTesting/Objects/sphere_5lods.fbx b/AutomatedTesting/Objects/sphere_5lods.fbx new file mode 100644 index 0000000000..965738c933 --- /dev/null +++ b/AutomatedTesting/Objects/sphere_5lods.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e169277bca473325281d5fe043cffc9196bd3ef46f6bffbea6e0b5e3b7194a1 +size 62700 diff --git a/AutomatedTesting/Objects/sphere_5lods.fbx.assetinfo b/AutomatedTesting/Objects/sphere_5lods.fbx.assetinfo new file mode 100644 index 0000000000..d46cbf322a --- /dev/null +++ b/AutomatedTesting/Objects/sphere_5lods.fbx.assetinfo @@ -0,0 +1,8 @@ +{ + "values": [ + { + "$type": "ScriptProcessorRule", + "scriptFilename": "Editor/Scripts/auto_lod.py" + } + ] +} From b15f97ae97ce9ea869745e3e75e41dc2b7907c3b Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Wed, 1 Dec 2021 15:53:00 -0600 Subject: [PATCH 65/72] Adding clearcoat to linear transform cosine light and several bug fixes (#6018) * Adding clearcoat to linear transform cosine lights (quad and polygon lights). Also fixed several warnings in various places in our shaders. Signed-off-by: Ken Pruiksma * Fixes from PR review Signed-off-by: Ken Pruiksma * Updates from review feedback - pulled out some of the duplicate code into functions. This required some minor restucturing. Ran ASV Area light tests to make sure nothing changed and validated clearcoat was working in a separate project. Signed-off-by: Ken Pruiksma --- .../ShaderLib/Atom/Features/PBR/Decals.azsli | 10 +- .../PBR/Lighting/StandardLighting.azsli | 6 +- .../Atom/Features/PBR/LightingUtils.azsli | 2 +- .../Atom/Features/PBR/Lights/Ibl.azsli | 3 +- .../Atom/Features/PBR/Lights/Ltc.azsli | 301 +++++++++++++----- .../Features/PBR/Lights/PolygonLight.azsli | 16 +- .../Atom/Features/PBR/Lights/QuadLight.azsli | 13 +- .../Atom/Features/PBR/Microfacet/Brdf.azsli | 2 +- .../RPI/Assets/ShaderLib/Atom/RPI/Math.azsli | 2 +- 9 files changed, 248 insertions(+), 107 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli index f9ead72ce4..aecb89eb92 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli @@ -76,23 +76,23 @@ void ApplyDecal(uint currDecalIndex, inout Surface surface) { case 0: baseMap = ViewSrg::m_decalTextureArrayDiffuse0.Sample(PassSrg::LinearSampler, decalUV); - normalMap = ViewSrg::m_decalTextureArrayNormalMaps0.Sample(PassSrg::LinearSampler, decalUV); + normalMap = ViewSrg::m_decalTextureArrayNormalMaps0.Sample(PassSrg::LinearSampler, decalUV).rg; break; case 1: baseMap = ViewSrg::m_decalTextureArrayDiffuse1.Sample(PassSrg::LinearSampler, decalUV); - normalMap = ViewSrg::m_decalTextureArrayNormalMaps1.Sample(PassSrg::LinearSampler, decalUV); + normalMap = ViewSrg::m_decalTextureArrayNormalMaps1.Sample(PassSrg::LinearSampler, decalUV).rg; break; case 2: baseMap = ViewSrg::m_decalTextureArrayDiffuse2.Sample(PassSrg::LinearSampler, decalUV); - normalMap = ViewSrg::m_decalTextureArrayNormalMaps2.Sample(PassSrg::LinearSampler, decalUV); + normalMap = ViewSrg::m_decalTextureArrayNormalMaps2.Sample(PassSrg::LinearSampler, decalUV).rg; break; case 3: baseMap = ViewSrg::m_decalTextureArrayDiffuse3.Sample(PassSrg::LinearSampler, decalUV); - normalMap = ViewSrg::m_decalTextureArrayNormalMaps3.Sample(PassSrg::LinearSampler, decalUV); + normalMap = ViewSrg::m_decalTextureArrayNormalMaps3.Sample(PassSrg::LinearSampler, decalUV).rg; break; case 4: baseMap = ViewSrg::m_decalTextureArrayDiffuse4.Sample(PassSrg::LinearSampler, decalUV); - normalMap = ViewSrg::m_decalTextureArrayNormalMaps4.Sample(PassSrg::LinearSampler, decalUV); + normalMap = ViewSrg::m_decalTextureArrayNormalMaps4.Sample(PassSrg::LinearSampler, decalUV).rg; break; } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli index 94d6c199a5..773c86ff0f 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lighting/StandardLighting.azsli @@ -48,9 +48,9 @@ float3 GetSpecularLighting(Surface surface, LightingData lightingData, const flo // HdotV = HdotL due to the definition of half vector float3 clearCoatF = FresnelSchlick(HdotL, 0.04) * surface.clearCoat.factor; float clearCoatRoughness = max(surface.clearCoat.roughness * surface.clearCoat.roughness, 0.0005f); - float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoat.normal, clearCoatRoughness, clearCoatF ); + float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoat.normal, clearCoatRoughness, clearCoatF); - specular = specular * (1.0 - clearCoatF) * (1.0 - clearCoatF) + clearCoatSpecular; + specular = specular * (1.0 - clearCoatF) + clearCoatSpecular; } specular *= lightIntensity; @@ -95,7 +95,7 @@ PbrLightingOutput DebugOutput(float3 color) { PbrLightingOutput output = (PbrLightingOutput)0; - float defaultNormal = float3(0.0f, 0.0f, 1.0f); + float3 defaultNormal = float3(0.0f, 0.0f, 1.0f); output.m_diffuseColor = float4(color.rgb, 1.0f); output.m_normal.rgb = EncodeNormalSignedOctahedron(defaultNormal); diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli index 3248fc83eb..b26b81a7c8 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LightingUtils.azsli @@ -67,6 +67,6 @@ float3 ApplyParallaxCorrectionAABB(float3 aabbMin, float3 aabbMax, float3 aabbPo // compute parallax corrected reflection vector, OBB version float3 ApplyParallaxCorrectionOBB(float4x4 obbTransformInverse, float3 obbHalfExtents, float3 positionWS, float3 reflectDir) { - float4 p = mul(obbTransformInverse, float4(positionWS, 1.0f)); + float3 p = mul(obbTransformInverse, float4(positionWS, 1.0f)).xyz; return ApplyParallaxCorrectionAABB(-obbHalfExtents, obbHalfExtents, float3(0.0f, 0.0f, 0.0f), p, reflectDir); } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli index 3254b8e4ed..abc2d3d3bd 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli @@ -60,7 +60,7 @@ float3 GetIblSpecular( // compute blend amount based on world position in the reflection probe volume float blendAmount = ComputeLerpBetweenInnerOuterOBBs( - ObjectSrg::GetReflectionProbeWorldMatrixInverse(), + (float3x4)ObjectSrg::GetReflectionProbeWorldMatrixInverse(), ObjectSrg::m_reflectionProbeData.m_innerObbHalfLengths, ObjectSrg::m_reflectionProbeData.m_outerObbHalfLengths, position); @@ -121,4 +121,3 @@ void ApplyIBL(Surface surface, inout LightingData lightingData) } } } - diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli index 6e45cf30c8..a98221f60c 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli @@ -256,15 +256,16 @@ void NormalizeQuadPoints(inout float3 p[5], in int vertexCount) } // Transforms the 4 points of a quad into the hemisphere of the normal -void TransformQuadToOrthonormalBasis(in float3 normal, in float3 dirToView, inout float3 p[4]) +void TransformQuadToOrthonormalBasis(in float3 normal, in float3 dirToView, in float3 p[4], out float3 tp[5]) { float3x3 orthoNormalBasis = BuildViewAlignedOrthonormalBasis(normal, dirToView); // Transform points into orthonormal space - p[0] = mul(orthoNormalBasis, p[0]); - p[1] = mul(orthoNormalBasis, p[1]); - p[2] = mul(orthoNormalBasis, p[2]); - p[3] = mul(orthoNormalBasis, p[3]); + tp[0] = mul(orthoNormalBasis, p[0]); + tp[1] = mul(orthoNormalBasis, p[1]); + tp[2] = mul(orthoNormalBasis, p[2]); + tp[3] = mul(orthoNormalBasis, p[3]); + tp[4] = float3(0.0, 0.0, 0.0); // Extra vertex for if quad becomes a pentagon after clipping to hemisphere. } // Integrates the edges of a quad for lambertian diffuse contribution. @@ -325,6 +326,47 @@ float IntegrateQuadSpecular(in float3 v[5], in float vertexCount, in bool double return sum; } +// Transform points p into the normal's hemisphere, then clip them to the hemisphere. Returns total number of points after clipping. +int LtcQuadTransformAndClip( + in float3 normal, + in float3 dirToCamera, + in float3 p[4], + inout float3 polygon[5] + ) +{ + // Transform the points of the light into the space of the normal's hemisphere. + TransformQuadToOrthonormalBasis(normal, dirToCamera, p, polygon); + + // Clip the light polygon to the normal hemisphere. This is done before the LTC matrix is applied to prevent + // parts of the light below the horizon from impacting the surface. The number of points remaining after + // the clip is returned in vertexCount. It's possible for the vertexCount of the resulting clipped quad to be + // 0 - all points clipped (no work to do, so return) + // 3 - 3 points clipped, leaving only a triangular corner of the quad + // 4 - 2 or 0 points clipped, leaving a quad + // 5 - 1 point clipped leaving a pentagon. + int vertexCount = 0; + ClipQuadToHorizon(polygon, vertexCount); + return vertexCount; +} + +// Evaluate the LTC specular reflectance of points in polygon. Does not scale by fresnel. +float LtcEvaluateSpecularUnscaled( + in float2 ltcCoords, + in Texture2D ltcMatrix, + in float3 polygon[5], + in int vertexCount, + in bool doubleSided) +{ + // Look up the values for the LTC matrix based on the roughness and orientation. + float3x3 ltcMat = LtcMatrix(ltcMatrix, ltcCoords); + + // Transform the quad based on the LTC lookup matrix + ApplyLtcMatrixToQuad(ltcMat, polygon, vertexCount); + + // IntegrateQuadSpecular uses more accurate integration than diffuse to handle smooth surfaces correctly. + return IntegrateQuadSpecular(polygon, vertexCount, doubleSided); +} + // Evaluate linear transform cosine lighting for a 4 point quad. // normal - The surface normal // dirToView - Normalized direction from the surface to the view @@ -334,31 +376,21 @@ float IntegrateQuadSpecular(in float3 v[5], in float vertexCount, in bool double // diffuse - The output diffuse response for the quad light // specular - The output specular response for the quad light void LtcQuadEvaluate( - in float3 normal, - in float3 dirToView, - in float3x3 ltcMat, + in Surface surface, + in LightingData lightingData, + in Texture2D ltcMatrix, + in Texture2D ltcAmpMatrix, in float3 p[4], in bool doubleSided, - out float diffuse, - out float specular) + out float diffuseOut, + out float3 specularOut) { - // Transform the points of the light into the space of the normal's hemisphere. - TransformQuadToOrthonormalBasis(normal, dirToView, p); - + // Initialize quad with dummy point at end in case one corner is clipped (resulting in 5 sided polygon) - float3 v[5] = {p[0], p[1], p[2], p[3], float3(0.0, 0.0, 0.0)}; - - // Clip the light polygon to the normal hemisphere. This is done before the LTC matrix is applied to prevent - // parts of the light below the horizon from impacting the surface. The number of points remaining after - // the clip is returned in vertexCount. It's possible for the vertexCount of the resulting clipped quad to be - // 0 - all points clipped (no work to do, so return) - // 3 - 3 points clipped, leaving only a triangular corner of the quad - // 4 - 2 or 0 points clipped, leaving a quad - // 5 - 1 point clipped leaving a pentagon. - - int vertexCount = 0; - ClipQuadToHorizon(v, vertexCount); + float3 polygon[5]; + // Transform the points of the light into the space of the normal's hemisphere and clip to the hemisphere + int vertexCount = LtcQuadTransformAndClip(surface.normal, lightingData.dirToCamera, p, polygon); if (vertexCount == 0) { // Entire light is below the horizon. @@ -366,12 +398,37 @@ void LtcQuadEvaluate( } // IntegrateQuadDiffuse is a cheap approximation compared to specular. - diffuse = IntegrateQuadDiffuse(v, vertexCount, doubleSided); + float diffuse = IntegrateQuadDiffuse(polygon, vertexCount, doubleSided); - ApplyLtcMatrixToQuad(ltcMat, v, vertexCount); + float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear); + float specular = LtcEvaluateSpecularUnscaled(ltcCoords, ltcMatrix, polygon, vertexCount, doubleSided); - // IntegrateQuadSpecular uses more accurate integration to handle smooth surfaces correctly. - specular = IntegrateQuadSpecular(v, vertexCount, doubleSided); + // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) + float2 schlick = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoords).xy; + float3 specularRgb = specular * (schlick.x * surface.specularF0 + (1.0 - surface.specularF0) * schlick.y); + + if(o_clearCoat_feature_enabled) + { + int vertexCountCc = LtcQuadTransformAndClip(surface.clearCoat.normal, lightingData.dirToCamera, p, polygon); + if (vertexCountCc > 0) + { + float2 ltcCoordsCc = LtcCoords(dot(surface.clearCoat.normal, lightingData.dirToCamera), surface.clearCoat.roughness); + float clearCoatSpecular = LtcEvaluateSpecularUnscaled(ltcCoordsCc, ltcMatrix, polygon, vertexCountCc, doubleSided); + + // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) + const float clearCoatSpecularF0 = 0.04; + float2 schlickCc = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoordsCc).xy; + float F = schlickCc.x * clearCoatSpecularF0 + (1.0 - clearCoatSpecularF0) * schlickCc.y; + F *= surface.clearCoat.factor; + + // Attenuate diffuse and specular based on how much light the clearcoat layer reflects + diffuse = diffuse * (1.0 - F); + specularRgb = (specularRgb * (1.0 - F)) + (clearCoatSpecular * F); + } + } + + diffuseOut = diffuse; + specularOut = specularRgb; } // Checks an edge against the horizon and integrates it. @@ -397,7 +454,7 @@ void LtcQuadEvaluate( // 4. Both points are below the horizon // - Do nothing. -void EvaluatePolyEdge(in float3 p0, in float3 p1, inout float3 prevClipPoint, in float3x3 ltcMat, inout float diffuse, inout float specular) +void EvaluatePolyEdge(in float3 p0, in float3 p1, in float3x3 ltcMat, inout float3 prevClipPoint, inout float diffuse, inout float specular) { if (p0.z > 0.0) { @@ -428,6 +485,74 @@ void EvaluatePolyEdge(in float3 p0, in float3 p1, inout float3 prevClipPoint, in } } +// Same as above but only evaluates specular (used for clear coat) +void EvaluatePolyEdgeSpecularOnly(in float3 p0, in float3 p1, in float3x3 ltcMat, inout float3 prevClipPoint, inout float specular) +{ + if (p0.z > 0.0) + { + if (p1.z > 0.0) + { + // Both above horizon + specular += IntegrateEdge(normalize(mul(ltcMat, p0)), normalize(mul(ltcMat, p1))); + } + else + { + // Going from above to below horizon + prevClipPoint = ClipEdge(p0, p1); + specular += IntegrateEdge(normalize(mul(ltcMat, p0)), normalize(mul(ltcMat, prevClipPoint))); + } + } + else if (p1.z > 0.0) + { + // Going from below to above horizon + float3 clipPoint = mul(ltcMat, ClipEdge(p1, p0)); + specular += IntegrateEdge(normalize(mul(ltcMat, prevClipPoint)), normalize(clipPoint)); + specular += IntegrateEdge(normalize(clipPoint), normalize(mul(ltcMat, p1))); + } +} + +// Evaluates the intial points to start looping through a polygon light. The first point in polygon may be below the surface +// so care must be taking to figure out which point to start with and what point to use to close the polygon. +void LtcPolygonEvaluateInitialPoints( + in float3 surfacePosition, + in float3x3 orthonormalMat, + in StructuredBuffer positions, + in uint startIdx, + inout float3 prevClipPoint, + inout float3 closePoint, + inout uint endIdx, + inout float3 p0) +{ + // Prepare initial values + p0 = mul(orthonormalMat, positions[startIdx].xyz - surfacePosition); // First point in polygon + + prevClipPoint = float3(0.0, 0.0, 0.0); // Used to hold previous clip point when polygon dips below horizon. + closePoint = p0; + + // Handle if the first point is below the horizon. + if (p0.z < 0.0) + { + float3 firstPoint = p0; // save the first point so it can be restored later. + + // Find the previous clip point so it can be used when the polygon goes above the horizon by + // searching backwards, updating the endIdx along the way to avoid reprocessing those points later + for ( ; endIdx > startIdx + 1; --endIdx) + { + float3 prevPoint = mul(orthonormalMat, positions[endIdx - 1].xyz - surfacePosition); + if (prevPoint.z > 0.0) + { + prevClipPoint = ClipEdge(prevPoint, p0); + closePoint = prevClipPoint; + break; + } + p0 = prevPoint; + } + + p0 = firstPoint; // Restore the original p0 + } + +} + // Evaluates the LTC result of an arbitrary polygon lighting a surface position. // pos - The surface position // normal - The surface normal @@ -445,72 +570,102 @@ void EvaluatePolyEdge(in float3 p0, in float3 p1, inout float3 prevClipPoint, in // EvaluatePolyEdge() later. During this search it also adjusts the end point index as necessary to avoid processing // those points that are below the horizon. void LtcPolygonEvaluate( - in float3 pos, - in float3 normal, - in float3 dirToView, - in float3x3 ltcMat, + in Surface surface, + in LightingData lightingData, + in Texture2D ltcMatrix, + in Texture2D ltcAmpMatrix, in StructuredBuffer positions, in uint startIdx, in uint endIdx, - out float diffuse, - out float specular + out float diffuseOut, + out float3 specularRgbOut ) { if (endIdx - startIdx < 3) { return; // Must have at least 3 points to form a polygon. } + uint originalEndIdx = endIdx; // Original endIdx may be needed for clearcoat // Rotate ltc matrix - float3x3 orthonormalMat = BuildViewAlignedOrthonormalBasis(normal, dirToView); + float3x3 orthonormalMat = BuildViewAlignedOrthonormalBasis(surface.normal, lightingData.dirToCamera); - // Prepare initial values - float3 p0 = mul(orthonormalMat, positions[startIdx].xyz - pos); // First point in polygon - diffuse = 0.0; - specular = 0.0; - - float3 prevClipPoint = float3(0.0, 0.0, 0.0); // Used to hold previous clip point when polygon dips below horizon. - float3 closePoint = p0; - - // Handle if the first point is below the horizon. - if (p0.z < 0.0) + // Evaluate the starting point (p0), previous point, and point used to close the polygon + float3 p0, prevClipPoint, closePoint; + LtcPolygonEvaluateInitialPoints(surface.position, orthonormalMat, positions, startIdx, prevClipPoint, closePoint, endIdx, p0); + + // Check if all points below horizon + if (endIdx == startIdx + 1) { - float3 firstPoint = p0; // save the first point so it can be restored later. - - // Find the previous clip point so it can be used when the polygon goes above the horizon by - // searching backwards, updating the endIdx along the way to avoid reprocessing those points later - for ( ; endIdx > startIdx + 1; --endIdx) - { - float3 prevPoint = mul(orthonormalMat, positions[endIdx - 1].xyz - pos); - if (prevPoint.z > 0.0) - { - prevClipPoint = ClipEdge(prevPoint, p0); - closePoint = prevClipPoint; - break; - } - p0 = prevPoint; - } - - // Check if all points below horizon - if (endIdx == startIdx + 1) - { - return; - } - - p0 = firstPoint; // Restore the original p0 + return; } + float diffuse = 0.0; + float specular = 0.0; + + float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear); + float3x3 ltcMat = LtcMatrix(ltcMatrix, ltcCoords); + // Evaluate all the points for (uint curIdx = startIdx + 1; curIdx < endIdx; ++curIdx) { - float3 p1 = mul(orthonormalMat, positions[curIdx].xyz - pos); // Current point in polygon - EvaluatePolyEdge(p0, p1, prevClipPoint, ltcMat, diffuse, specular); + float3 p1 = mul(orthonormalMat, positions[curIdx].xyz - surface.position); // Current point in polygon + EvaluatePolyEdge(p0, p1, ltcMat, prevClipPoint, diffuse, specular); p0 = p1; } - EvaluatePolyEdge(p0, closePoint, prevClipPoint, ltcMat, diffuse, specular); + EvaluatePolyEdge(p0, closePoint, ltcMat, prevClipPoint, diffuse, specular); // Note: negated due to winding order diffuse = -diffuse; specular = -specular; + + // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) + float2 schlick = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoords).xy; + float3 specularRgb = specular * ((schlick.x * surface.specularF0) + (1.0 - surface.specularF0) * schlick.y); + + if(o_clearCoat_feature_enabled) + { + // Rotate ltc matrix + float3x3 orthonormalMatCc = BuildViewAlignedOrthonormalBasis(surface.clearCoat.normal, lightingData.dirToCamera); + + // restore original endIdx and re-evaluate initial points with matrix based on the clearcoat normal. + endIdx = originalEndIdx; + LtcPolygonEvaluateInitialPoints(surface.position, orthonormalMatCc, positions, startIdx, prevClipPoint, closePoint, endIdx, p0); + + // Check if all points below horizon + if (endIdx != startIdx + 1) + { + float specularCc = 0.0; + + float2 ltcCoordsCc = LtcCoords(dot(surface.clearCoat.normal, lightingData.dirToCamera), surface.clearCoat.roughness); + float3x3 ltcMatCc = LtcMatrix(ltcMatrix, ltcCoordsCc); + + // Evaluate all the points + for (uint curIdx = startIdx + 1; curIdx < endIdx; ++curIdx) + { + float3 p1 = mul(orthonormalMatCc, positions[curIdx].xyz - surface.position); // Current point in polygon + EvaluatePolyEdgeSpecularOnly(p0, p1, ltcMatCc, prevClipPoint, specularCc); + p0 = p1; + } + + EvaluatePolyEdgeSpecularOnly(p0, closePoint, ltcMatCc, prevClipPoint, specularCc); + + // Note: negated due to winding order + specularCc = -specularCc; + + // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) + const float clearCoatSpecularF0 = 0.04; + float2 schlickCc = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoordsCc).xy; + float F = clearCoatSpecularF0 * schlickCc.x + (1.0 - clearCoatSpecularF0) * schlickCc.y; + F *= surface.clearCoat.factor; + + diffuse = diffuse * (1.0 - F); + specularRgb = (specularRgb * (1.0 - F)) + (specularCc * F); + } + } + + diffuseOut = diffuse; + specularRgbOut = specularRgb; + } diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli index 66f21ec5d8..07fe6d4f00 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli @@ -51,25 +51,19 @@ void ApplyPoylgonLight(ViewSrg::PolygonLight light, Surface surface, inout Light float radiusAttenuation = 1.0 - (falloff * falloff); radiusAttenuation = radiusAttenuation * radiusAttenuation; - float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear); - float3x3 ltcMat = LtcMatrix(SceneSrg::m_ltcMatrix, ltcCoords); - float diffuse = 0.0; - float specular = 0.0; + float3 specularRgb = 0.0; + + LtcPolygonEvaluate(surface, lightingData, SceneSrg::m_ltcMatrix, SceneSrg::m_ltcAmplification, ViewSrg::m_polygonLightPoints, startIndex, endIndex, diffuse, specularRgb); - LtcPolygonEvaluate(surface.position, surface.normal, lightingData.dirToCamera, ltcMat, ViewSrg::m_polygonLightPoints, startIndex, endIndex, diffuse, specular); diffuse = doubleSided ? abs(diffuse) : max(0.0, diffuse); - specular = doubleSided ? abs(specular) : max(0.0, specular); - - // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) - float2 schlick = SceneSrg::m_ltcAmplification.Sample(PassSrg::LinearSampler, ltcCoords).xy; - float3 specularRGB = specular * (schlick.x + (1.0 - surface.specularF0) * schlick.y); + specularRgb = doubleSided ? abs(specularRgb) : max(0.0, specularRgb); // Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity float3 intensity = 0.5 * INV_PI * radiusAttenuation * abs(light.m_rgbIntensityNits); lightingData.diffuseLighting += surface.albedo * diffuse * intensity; - lightingData.specularLighting += surface.specularF0 * specularRGB * intensity; + lightingData.specularLighting += specularRgb * intensity; } void ApplyPolygonLights(Surface surface, inout LightingData lightingData) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli index 43f5095f84..63515339d8 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli @@ -112,22 +112,15 @@ void ApplyQuadLight(ViewSrg::QuadLight light, Surface surface, inout LightingDat { float3 p[4] = {p0, p1, p2, p3}; - float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear); - float3x3 ltcMat = LtcMatrix(SceneSrg::m_ltcMatrix, ltcCoords); - float diffuse = 0.0; - float specular = 0.0; - LtcQuadEvaluate(surface.normal, lightingData.dirToCamera, ltcMat, p, doubleSided, diffuse, specular); - - // Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel) - float2 schlick = SceneSrg::m_ltcAmplification.Sample(PassSrg::LinearSampler, ltcCoords).xy; - float3 specularRGB = specular * (schlick.x + (1.0 - surface.specularF0) * schlick.y); + float3 specular = float3(0.0, 0.0, 0.0); // specularF0 used in LtcQuadEvaluate which is a float3 + LtcQuadEvaluate(surface, lightingData, SceneSrg::m_ltcMatrix, SceneSrg::m_ltcAmplification, p, doubleSided, diffuse, specular); // Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity float3 intensity = 0.5 * INV_PI * radiusAttenuation * light.m_rgbIntensityNits; lightingData.diffuseLighting += surface.albedo * diffuse * intensity; - lightingData.specularLighting += surface.specularF0 * specularRGB * intensity; + lightingData.specularLighting += specular * intensity; } else { diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli index 0f3e3c913d..e7904fefdf 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Microfacet/Brdf.azsli @@ -22,7 +22,7 @@ // ------- Diffuse Lighting ------- //! Simple Lambertian BRDF. -float3 DiffuseLambertian(float3 albedo, float3 normal, float3 dirToLight, float diffuseResponse) +float3 DiffuseLambertian(float3 albedo, float3 normal, float3 dirToLight, float3 diffuseResponse) { float NdotL = saturate(dot(normal, dirToLight)); return albedo * NdotL * INV_PI * diffuseResponse; diff --git a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli index 6ffdb6e815..344ccac1fb 100644 --- a/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli +++ b/Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/Math.azsli @@ -177,7 +177,7 @@ float ComputeLerpBetweenInnerOuterAABBs(float3 innerAabbMin, float3 innerAabbMax bool ObbContainsPoint(float4x4 obbTransformInverse, float3 obbHalfExtents, float3 testPoint) { // get the position in Obb local space, force to positive quadrant with abs() - float4 p = abs(mul(obbTransformInverse, float4(testPoint, 1.0f))); + float3 p = abs(mul(obbTransformInverse, float4(testPoint, 1.0f)).xyz); return AabbContainsPoint(-obbHalfExtents, obbHalfExtents, p); } From 028f3e05dbd771c66497540fdf69a9392adf19b5 Mon Sep 17 00:00:00 2001 From: Junbo Liang <68558268+junbo75@users.noreply.github.com> Date: Wed, 1 Dec 2021 14:28:09 -0800 Subject: [PATCH 66/72] Update the folder structure for the AWSMetrics gem following the latest O3DE guidline (#5028) Signed-off-by: Junbo Liang <68558268+junbo75@users.noreply.github.com> --- Gems/AWSMetrics/Code/CMakeLists.txt | 12 +++---- .../Code/Include/{Public => }/AWSMetricsBus.h | 0 .../Include/{Public => }/MetricsAttribute.h | 0 .../Private => Source}/AWSMetricsConstant.h | 0 .../Private => Source}/AWSMetricsModule.h | 0 .../Private => Source}/AWSMetricsServiceApi.h | 0 .../AWSMetricsSystemComponent.h | 0 .../Private => Source}/ClientConfiguration.h | 0 .../DefaultClientIdProvider.h | 0 .../Private => Source}/GlobalStatistics.h | 0 .../Private => Source}/IdentityProvider.h | 0 .../Private => Source}/MetricsEvent.h | 0 .../Private => Source}/MetricsEventBuilder.h | 0 .../Private => Source}/MetricsManager.h | 0 .../Private => Source}/MetricsQueue.h | 0 Gems/AWSMetrics/Code/awsmetrics_files.cmake | 35 ++++++++++--------- .../Code/awsmetrics_shared_files.cmake | 2 +- 17 files changed, 25 insertions(+), 24 deletions(-) rename Gems/AWSMetrics/Code/Include/{Public => }/AWSMetricsBus.h (100%) rename Gems/AWSMetrics/Code/Include/{Public => }/MetricsAttribute.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/AWSMetricsConstant.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/AWSMetricsModule.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/AWSMetricsServiceApi.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/AWSMetricsSystemComponent.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/ClientConfiguration.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/DefaultClientIdProvider.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/GlobalStatistics.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/IdentityProvider.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/MetricsEvent.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/MetricsEventBuilder.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/MetricsManager.h (100%) rename Gems/AWSMetrics/Code/{Include/Private => Source}/MetricsQueue.h (100%) diff --git a/Gems/AWSMetrics/Code/CMakeLists.txt b/Gems/AWSMetrics/Code/CMakeLists.txt index 2e78ee8c42..1da4e7f96f 100644 --- a/Gems/AWSMetrics/Code/CMakeLists.txt +++ b/Gems/AWSMetrics/Code/CMakeLists.txt @@ -13,9 +13,9 @@ ly_add_target( awsmetrics_files.cmake INCLUDE_DIRECTORIES PUBLIC - Include/Public + Include PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE AZ::AzCore @@ -32,9 +32,9 @@ ly_add_target( awsmetrics_shared_files.cmake INCLUDE_DIRECTORIES PUBLIC - Include/Public + Include PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE AZ::AzCore @@ -88,8 +88,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) awsmetrics_tests_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private - Include/Public + Include + Source Tests BUILD_DEPENDENCIES PRIVATE diff --git a/Gems/AWSMetrics/Code/Include/Public/AWSMetricsBus.h b/Gems/AWSMetrics/Code/Include/AWSMetricsBus.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Public/AWSMetricsBus.h rename to Gems/AWSMetrics/Code/Include/AWSMetricsBus.h diff --git a/Gems/AWSMetrics/Code/Include/Public/MetricsAttribute.h b/Gems/AWSMetrics/Code/Include/MetricsAttribute.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Public/MetricsAttribute.h rename to Gems/AWSMetrics/Code/Include/MetricsAttribute.h diff --git a/Gems/AWSMetrics/Code/Include/Private/AWSMetricsConstant.h b/Gems/AWSMetrics/Code/Source/AWSMetricsConstant.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/AWSMetricsConstant.h rename to Gems/AWSMetrics/Code/Source/AWSMetricsConstant.h diff --git a/Gems/AWSMetrics/Code/Include/Private/AWSMetricsModule.h b/Gems/AWSMetrics/Code/Source/AWSMetricsModule.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/AWSMetricsModule.h rename to Gems/AWSMetrics/Code/Source/AWSMetricsModule.h diff --git a/Gems/AWSMetrics/Code/Include/Private/AWSMetricsServiceApi.h b/Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/AWSMetricsServiceApi.h rename to Gems/AWSMetrics/Code/Source/AWSMetricsServiceApi.h diff --git a/Gems/AWSMetrics/Code/Include/Private/AWSMetricsSystemComponent.h b/Gems/AWSMetrics/Code/Source/AWSMetricsSystemComponent.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/AWSMetricsSystemComponent.h rename to Gems/AWSMetrics/Code/Source/AWSMetricsSystemComponent.h diff --git a/Gems/AWSMetrics/Code/Include/Private/ClientConfiguration.h b/Gems/AWSMetrics/Code/Source/ClientConfiguration.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/ClientConfiguration.h rename to Gems/AWSMetrics/Code/Source/ClientConfiguration.h diff --git a/Gems/AWSMetrics/Code/Include/Private/DefaultClientIdProvider.h b/Gems/AWSMetrics/Code/Source/DefaultClientIdProvider.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/DefaultClientIdProvider.h rename to Gems/AWSMetrics/Code/Source/DefaultClientIdProvider.h diff --git a/Gems/AWSMetrics/Code/Include/Private/GlobalStatistics.h b/Gems/AWSMetrics/Code/Source/GlobalStatistics.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/GlobalStatistics.h rename to Gems/AWSMetrics/Code/Source/GlobalStatistics.h diff --git a/Gems/AWSMetrics/Code/Include/Private/IdentityProvider.h b/Gems/AWSMetrics/Code/Source/IdentityProvider.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/IdentityProvider.h rename to Gems/AWSMetrics/Code/Source/IdentityProvider.h diff --git a/Gems/AWSMetrics/Code/Include/Private/MetricsEvent.h b/Gems/AWSMetrics/Code/Source/MetricsEvent.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/MetricsEvent.h rename to Gems/AWSMetrics/Code/Source/MetricsEvent.h diff --git a/Gems/AWSMetrics/Code/Include/Private/MetricsEventBuilder.h b/Gems/AWSMetrics/Code/Source/MetricsEventBuilder.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/MetricsEventBuilder.h rename to Gems/AWSMetrics/Code/Source/MetricsEventBuilder.h diff --git a/Gems/AWSMetrics/Code/Include/Private/MetricsManager.h b/Gems/AWSMetrics/Code/Source/MetricsManager.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/MetricsManager.h rename to Gems/AWSMetrics/Code/Source/MetricsManager.h diff --git a/Gems/AWSMetrics/Code/Include/Private/MetricsQueue.h b/Gems/AWSMetrics/Code/Source/MetricsQueue.h similarity index 100% rename from Gems/AWSMetrics/Code/Include/Private/MetricsQueue.h rename to Gems/AWSMetrics/Code/Source/MetricsQueue.h diff --git a/Gems/AWSMetrics/Code/awsmetrics_files.cmake b/Gems/AWSMetrics/Code/awsmetrics_files.cmake index b1a3a647df..936c5634e1 100644 --- a/Gems/AWSMetrics/Code/awsmetrics_files.cmake +++ b/Gems/AWSMetrics/Code/awsmetrics_files.cmake @@ -7,27 +7,28 @@ # set(FILES - Include/Public/AWSMetricsBus.h - Include/Public/MetricsAttribute.h - Include/Private/AWSMetricsConstant.h - Include/Private/AWSMetricsServiceApi.h - Include/Private/AWSMetricsSystemComponent.h - Include/Private/ClientConfiguration.h - Include/Private/DefaultClientIdProvider.h - Include/Private/GlobalStatistics.h - Include/Private/IdentityProvider.h - Include/Private/MetricsEvent.h - Include/Private/MetricsEventBuilder.h - Include/Private/MetricsManager.h - Include/Private/MetricsQueue.h - Source/ClientConfiguration.cpp - Source/DefaultClientIdProvider.cpp + Include/AWSMetricsBus.h + Include/MetricsAttribute.h + + Source/AWSMetricsConstant.h Source/AWSMetricsServiceApi.cpp + Source/AWSMetricsServiceApi.h Source/AWSMetricsSystemComponent.cpp + Source/AWSMetricsSystemComponent.h + Source/ClientConfiguration.cpp + Source/ClientConfiguration.h + Source/DefaultClientIdProvider.h + Source/DefaultClientIdProvider.cpp + Source/GlobalStatistics.h Source/IdentityProvider.cpp - Source/MetricsEvent.cpp - Source/MetricsEventBuilder.cpp + Source/IdentityProvider.h Source/MetricsAttribute.cpp + Source/MetricsEvent.cpp + Source/MetricsEvent.h + Source/MetricsEventBuilder.cpp + Source/MetricsEventBuilder.h Source/MetricsManager.cpp + Source/MetricsManager.h Source/MetricsQueue.cpp + Source/MetricsQueue.h ) diff --git a/Gems/AWSMetrics/Code/awsmetrics_shared_files.cmake b/Gems/AWSMetrics/Code/awsmetrics_shared_files.cmake index 3366363152..fee62c6f12 100644 --- a/Gems/AWSMetrics/Code/awsmetrics_shared_files.cmake +++ b/Gems/AWSMetrics/Code/awsmetrics_shared_files.cmake @@ -7,6 +7,6 @@ # set(FILES - Include/Private/AWSMetricsModule.h Source/AWSMetricsModule.cpp + Source/AWSMetricsModule.h ) From a486d1a8ad7fa349313fd2742fa762c347d21c88 Mon Sep 17 00:00:00 2001 From: Junbo Liang <68558268+junbo75@users.noreply.github.com> Date: Wed, 1 Dec 2021 14:28:27 -0800 Subject: [PATCH 67/72] Move the header files in the AWS Core gem based on the latest gem structure guideline (#5178) Signed-off-by: Junbo Liang <68558268+junbo75@users.noreply.github.com> --- Gems/AWSCore/Code/CMakeLists.txt | 22 ++--- .../Code/Include/{Public => }/AWSCoreBus.h | 0 .../Credential/AWSCredentialBus.h | 0 .../{Public => }/Framework/AWSApiClientJob.h | 0 .../Framework/AWSApiClientJobConfig.h | 0 .../{Public => }/Framework/AWSApiJob.h | 0 .../{Public => }/Framework/AWSApiJobConfig.h | 0 .../{Public => }/Framework/AWSApiRequestJob.h | 0 .../Framework/AWSApiRequestJobConfig.h | 0 .../Include/{Public => }/Framework/Error.h | 0 .../Framework/HttpClientComponent.h | 0 .../{Public => }/Framework/HttpRequestJob.h | 0 .../Framework/HttpRequestJobConfig.h | 0 .../{Public => }/Framework/JobExecuter.h | 0 .../Framework/JsonObjectHandler.h | 0 .../{Public => }/Framework/JsonWriter.h | 0 .../Framework/MultipartFormData.h | 0 .../{Public => }/Framework/RequestBuilder.h | 0 .../{Public => }/Framework/ServiceClientJob.h | 0 .../Framework/ServiceClientJobConfig.h | 0 .../{Public => }/Framework/ServiceJob.h | 0 .../{Public => }/Framework/ServiceJobConfig.h | 0 .../{Public => }/Framework/ServiceJobUtil.h | 0 .../Framework/ServiceRequestJob.h | 0 .../Framework/ServiceRequestJobConfig.h | 0 .../Include/{Public => }/Framework/Util.h | 0 .../ResourceMapping/AWSResourceMappingBus.h | 0 .../ScriptCanvas/AWSScriptBehaviorDynamoDB.h | 0 .../ScriptCanvas/AWSScriptBehaviorLambda.h | 0 .../ScriptCanvas/AWSScriptBehaviorS3.h | 0 .../AWSScriptBehaviorsComponent.h | 0 .../Private => Source}/AWSCoreEditorModule.h | 0 .../AWSCoreEditorSystemComponent.h | 0 .../Private => Source}/AWSCoreInternalBus.h | 0 .../Private => Source}/AWSCoreModule.h | 0 .../AWSCoreSystemComponent.h | 0 .../Configuration/AWSCoreConfiguration.h | 0 .../Credential/AWSCVarCredentialHandler.h | 0 .../Credential/AWSCredentialManager.h | 0 .../Credential/AWSDefaultCredentialHandler.h | 0 .../Editor/AWSCoreEditorManager.h | 0 .../Attribution/AWSAttributionServiceApi.h | 0 .../AWSCoreAttributionConsentDialog.h | 0 .../Attribution/AWSCoreAttributionConstant.h | 0 .../Attribution/AWSCoreAttributionManager.h | 0 .../Attribution/AWSCoreAttributionMetric.h | 0 .../AWSCoreAttributionSystemComponent.h | 0 .../Editor/Constants/AWSCoreEditorMenuLinks.h | 0 .../Editor/Constants/AWSCoreEditorMenuNames.h | 0 .../Editor/UI/AWSCoreEditorMenu.h | 0 .../UI/AWSCoreResourceMappingToolAction.h | 0 .../AWSResourceMappingConstants.h | 0 .../AWSResourceMappingManager.h | 0 .../ResourceMapping/AWSResourceMappingUtils.h | 0 Gems/AWSCore/Code/awscore_editor_files.cmake | 26 +++--- .../Code/awscore_editor_shared_files.cmake | 2 +- Gems/AWSCore/Code/awscore_files.cmake | 84 ++++++++++--------- Gems/AWSCore/Code/awscore_shared_files.cmake | 2 +- 58 files changed, 69 insertions(+), 67 deletions(-) rename Gems/AWSCore/Code/Include/{Public => }/AWSCoreBus.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Credential/AWSCredentialBus.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/AWSApiClientJob.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/AWSApiClientJobConfig.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/AWSApiJob.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/AWSApiJobConfig.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/AWSApiRequestJob.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/AWSApiRequestJobConfig.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/Error.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/HttpClientComponent.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/HttpRequestJob.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/HttpRequestJobConfig.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/JobExecuter.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/JsonObjectHandler.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/JsonWriter.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/MultipartFormData.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/RequestBuilder.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/ServiceClientJob.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/ServiceClientJobConfig.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/ServiceJob.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/ServiceJobConfig.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/ServiceJobUtil.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/ServiceRequestJob.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/ServiceRequestJobConfig.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/Framework/Util.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/ResourceMapping/AWSResourceMappingBus.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/ScriptCanvas/AWSScriptBehaviorDynamoDB.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/ScriptCanvas/AWSScriptBehaviorLambda.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/ScriptCanvas/AWSScriptBehaviorS3.h (100%) rename Gems/AWSCore/Code/Include/{Public => }/ScriptCanvas/AWSScriptBehaviorsComponent.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/AWSCoreEditorModule.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/AWSCoreEditorSystemComponent.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/AWSCoreInternalBus.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/AWSCoreModule.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/AWSCoreSystemComponent.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Configuration/AWSCoreConfiguration.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Credential/AWSCVarCredentialHandler.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Credential/AWSCredentialManager.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Credential/AWSDefaultCredentialHandler.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/AWSCoreEditorManager.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Attribution/AWSAttributionServiceApi.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Attribution/AWSCoreAttributionConsentDialog.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Attribution/AWSCoreAttributionConstant.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Attribution/AWSCoreAttributionManager.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Attribution/AWSCoreAttributionMetric.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Attribution/AWSCoreAttributionSystemComponent.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Constants/AWSCoreEditorMenuLinks.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/Constants/AWSCoreEditorMenuNames.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/UI/AWSCoreEditorMenu.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/Editor/UI/AWSCoreResourceMappingToolAction.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/ResourceMapping/AWSResourceMappingConstants.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/ResourceMapping/AWSResourceMappingManager.h (100%) rename Gems/AWSCore/Code/{Include/Private => Source}/ResourceMapping/AWSResourceMappingUtils.h (100%) diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index be7d975016..974f3f03bf 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -16,10 +16,10 @@ ly_add_target( ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC - Include/Public + Include ${pal_dir} PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE AZ::AzCore @@ -36,7 +36,7 @@ ly_add_target( awscore_shared_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE AZ::AzCore @@ -71,10 +71,10 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_editor_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private + Source ${pal_dir} PUBLIC - Include/Public + Include BUILD_DEPENDENCIES PRIVATE AZ::AzQtComponents @@ -93,7 +93,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) awscore_editor_shared_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE AZ::AzCore @@ -112,7 +112,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) awscore_resourcemappingtool_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE Gem::AWSCore.Editor.Static @@ -156,8 +156,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) awscore_tests_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private - Include/Public + Source + Include Tests BUILD_DEPENDENCIES PRIVATE @@ -190,9 +190,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_editor_tests_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private + Source ${pal_dir} - Include/Public + Include Tests COMPILE_DEFINITIONS PRIVATE diff --git a/Gems/AWSCore/Code/Include/Public/AWSCoreBus.h b/Gems/AWSCore/Code/Include/AWSCoreBus.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/AWSCoreBus.h rename to Gems/AWSCore/Code/Include/AWSCoreBus.h diff --git a/Gems/AWSCore/Code/Include/Public/Credential/AWSCredentialBus.h b/Gems/AWSCore/Code/Include/Credential/AWSCredentialBus.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Credential/AWSCredentialBus.h rename to Gems/AWSCore/Code/Include/Credential/AWSCredentialBus.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/AWSApiClientJob.h b/Gems/AWSCore/Code/Include/Framework/AWSApiClientJob.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/AWSApiClientJob.h rename to Gems/AWSCore/Code/Include/Framework/AWSApiClientJob.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/AWSApiClientJobConfig.h b/Gems/AWSCore/Code/Include/Framework/AWSApiClientJobConfig.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/AWSApiClientJobConfig.h rename to Gems/AWSCore/Code/Include/Framework/AWSApiClientJobConfig.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/AWSApiJob.h b/Gems/AWSCore/Code/Include/Framework/AWSApiJob.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/AWSApiJob.h rename to Gems/AWSCore/Code/Include/Framework/AWSApiJob.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/AWSApiJobConfig.h b/Gems/AWSCore/Code/Include/Framework/AWSApiJobConfig.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/AWSApiJobConfig.h rename to Gems/AWSCore/Code/Include/Framework/AWSApiJobConfig.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/AWSApiRequestJob.h b/Gems/AWSCore/Code/Include/Framework/AWSApiRequestJob.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/AWSApiRequestJob.h rename to Gems/AWSCore/Code/Include/Framework/AWSApiRequestJob.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/AWSApiRequestJobConfig.h b/Gems/AWSCore/Code/Include/Framework/AWSApiRequestJobConfig.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/AWSApiRequestJobConfig.h rename to Gems/AWSCore/Code/Include/Framework/AWSApiRequestJobConfig.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/Error.h b/Gems/AWSCore/Code/Include/Framework/Error.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/Error.h rename to Gems/AWSCore/Code/Include/Framework/Error.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/HttpClientComponent.h b/Gems/AWSCore/Code/Include/Framework/HttpClientComponent.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/HttpClientComponent.h rename to Gems/AWSCore/Code/Include/Framework/HttpClientComponent.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/HttpRequestJob.h b/Gems/AWSCore/Code/Include/Framework/HttpRequestJob.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/HttpRequestJob.h rename to Gems/AWSCore/Code/Include/Framework/HttpRequestJob.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/HttpRequestJobConfig.h b/Gems/AWSCore/Code/Include/Framework/HttpRequestJobConfig.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/HttpRequestJobConfig.h rename to Gems/AWSCore/Code/Include/Framework/HttpRequestJobConfig.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/JobExecuter.h b/Gems/AWSCore/Code/Include/Framework/JobExecuter.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/JobExecuter.h rename to Gems/AWSCore/Code/Include/Framework/JobExecuter.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/JsonObjectHandler.h b/Gems/AWSCore/Code/Include/Framework/JsonObjectHandler.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/JsonObjectHandler.h rename to Gems/AWSCore/Code/Include/Framework/JsonObjectHandler.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/JsonWriter.h b/Gems/AWSCore/Code/Include/Framework/JsonWriter.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/JsonWriter.h rename to Gems/AWSCore/Code/Include/Framework/JsonWriter.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/MultipartFormData.h b/Gems/AWSCore/Code/Include/Framework/MultipartFormData.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/MultipartFormData.h rename to Gems/AWSCore/Code/Include/Framework/MultipartFormData.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/RequestBuilder.h b/Gems/AWSCore/Code/Include/Framework/RequestBuilder.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/RequestBuilder.h rename to Gems/AWSCore/Code/Include/Framework/RequestBuilder.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJob.h b/Gems/AWSCore/Code/Include/Framework/ServiceClientJob.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJob.h rename to Gems/AWSCore/Code/Include/Framework/ServiceClientJob.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJobConfig.h b/Gems/AWSCore/Code/Include/Framework/ServiceClientJobConfig.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/ServiceClientJobConfig.h rename to Gems/AWSCore/Code/Include/Framework/ServiceClientJobConfig.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceJob.h b/Gems/AWSCore/Code/Include/Framework/ServiceJob.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/ServiceJob.h rename to Gems/AWSCore/Code/Include/Framework/ServiceJob.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceJobConfig.h b/Gems/AWSCore/Code/Include/Framework/ServiceJobConfig.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/ServiceJobConfig.h rename to Gems/AWSCore/Code/Include/Framework/ServiceJobConfig.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceJobUtil.h b/Gems/AWSCore/Code/Include/Framework/ServiceJobUtil.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/ServiceJobUtil.h rename to Gems/AWSCore/Code/Include/Framework/ServiceJobUtil.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJob.h b/Gems/AWSCore/Code/Include/Framework/ServiceRequestJob.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJob.h rename to Gems/AWSCore/Code/Include/Framework/ServiceRequestJob.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJobConfig.h b/Gems/AWSCore/Code/Include/Framework/ServiceRequestJobConfig.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJobConfig.h rename to Gems/AWSCore/Code/Include/Framework/ServiceRequestJobConfig.h diff --git a/Gems/AWSCore/Code/Include/Public/Framework/Util.h b/Gems/AWSCore/Code/Include/Framework/Util.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/Framework/Util.h rename to Gems/AWSCore/Code/Include/Framework/Util.h diff --git a/Gems/AWSCore/Code/Include/Public/ResourceMapping/AWSResourceMappingBus.h b/Gems/AWSCore/Code/Include/ResourceMapping/AWSResourceMappingBus.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/ResourceMapping/AWSResourceMappingBus.h rename to Gems/AWSCore/Code/Include/ResourceMapping/AWSResourceMappingBus.h diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h b/Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorDynamoDB.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h rename to Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorDynamoDB.h diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h b/Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorLambda.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h rename to Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorLambda.h diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h b/Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorS3.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h rename to Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorS3.h diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h b/Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorsComponent.h similarity index 100% rename from Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h rename to Gems/AWSCore/Code/Include/ScriptCanvas/AWSScriptBehaviorsComponent.h diff --git a/Gems/AWSCore/Code/Include/Private/AWSCoreEditorModule.h b/Gems/AWSCore/Code/Source/AWSCoreEditorModule.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/AWSCoreEditorModule.h rename to Gems/AWSCore/Code/Source/AWSCoreEditorModule.h diff --git a/Gems/AWSCore/Code/Include/Private/AWSCoreEditorSystemComponent.h b/Gems/AWSCore/Code/Source/AWSCoreEditorSystemComponent.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/AWSCoreEditorSystemComponent.h rename to Gems/AWSCore/Code/Source/AWSCoreEditorSystemComponent.h diff --git a/Gems/AWSCore/Code/Include/Private/AWSCoreInternalBus.h b/Gems/AWSCore/Code/Source/AWSCoreInternalBus.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/AWSCoreInternalBus.h rename to Gems/AWSCore/Code/Source/AWSCoreInternalBus.h diff --git a/Gems/AWSCore/Code/Include/Private/AWSCoreModule.h b/Gems/AWSCore/Code/Source/AWSCoreModule.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/AWSCoreModule.h rename to Gems/AWSCore/Code/Source/AWSCoreModule.h diff --git a/Gems/AWSCore/Code/Include/Private/AWSCoreSystemComponent.h b/Gems/AWSCore/Code/Source/AWSCoreSystemComponent.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/AWSCoreSystemComponent.h rename to Gems/AWSCore/Code/Source/AWSCoreSystemComponent.h diff --git a/Gems/AWSCore/Code/Include/Private/Configuration/AWSCoreConfiguration.h b/Gems/AWSCore/Code/Source/Configuration/AWSCoreConfiguration.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Configuration/AWSCoreConfiguration.h rename to Gems/AWSCore/Code/Source/Configuration/AWSCoreConfiguration.h diff --git a/Gems/AWSCore/Code/Include/Private/Credential/AWSCVarCredentialHandler.h b/Gems/AWSCore/Code/Source/Credential/AWSCVarCredentialHandler.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Credential/AWSCVarCredentialHandler.h rename to Gems/AWSCore/Code/Source/Credential/AWSCVarCredentialHandler.h diff --git a/Gems/AWSCore/Code/Include/Private/Credential/AWSCredentialManager.h b/Gems/AWSCore/Code/Source/Credential/AWSCredentialManager.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Credential/AWSCredentialManager.h rename to Gems/AWSCore/Code/Source/Credential/AWSCredentialManager.h diff --git a/Gems/AWSCore/Code/Include/Private/Credential/AWSDefaultCredentialHandler.h b/Gems/AWSCore/Code/Source/Credential/AWSDefaultCredentialHandler.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Credential/AWSDefaultCredentialHandler.h rename to Gems/AWSCore/Code/Source/Credential/AWSDefaultCredentialHandler.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/AWSCoreEditorManager.h b/Gems/AWSCore/Code/Source/Editor/AWSCoreEditorManager.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/AWSCoreEditorManager.h rename to Gems/AWSCore/Code/Source/Editor/AWSCoreEditorManager.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSAttributionServiceApi.h b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSAttributionServiceApi.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSAttributionServiceApi.h rename to Gems/AWSCore/Code/Source/Editor/Attribution/AWSAttributionServiceApi.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConsentDialog.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h rename to Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConsentDialog.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConstant.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h rename to Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionConstant.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionManager.h rename to Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionMetric.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h rename to Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionMetric.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h rename to Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionSystemComponent.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Constants/AWSCoreEditorMenuLinks.h b/Gems/AWSCore/Code/Source/Editor/Constants/AWSCoreEditorMenuLinks.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Constants/AWSCoreEditorMenuLinks.h rename to Gems/AWSCore/Code/Source/Editor/Constants/AWSCoreEditorMenuLinks.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/Constants/AWSCoreEditorMenuNames.h b/Gems/AWSCore/Code/Source/Editor/Constants/AWSCoreEditorMenuNames.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/Constants/AWSCoreEditorMenuNames.h rename to Gems/AWSCore/Code/Source/Editor/Constants/AWSCoreEditorMenuNames.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreEditorMenu.h b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreEditorMenu.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreEditorMenu.h rename to Gems/AWSCore/Code/Source/Editor/UI/AWSCoreEditorMenu.h diff --git a/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h rename to Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.h diff --git a/Gems/AWSCore/Code/Include/Private/ResourceMapping/AWSResourceMappingConstants.h b/Gems/AWSCore/Code/Source/ResourceMapping/AWSResourceMappingConstants.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/ResourceMapping/AWSResourceMappingConstants.h rename to Gems/AWSCore/Code/Source/ResourceMapping/AWSResourceMappingConstants.h diff --git a/Gems/AWSCore/Code/Include/Private/ResourceMapping/AWSResourceMappingManager.h b/Gems/AWSCore/Code/Source/ResourceMapping/AWSResourceMappingManager.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/ResourceMapping/AWSResourceMappingManager.h rename to Gems/AWSCore/Code/Source/ResourceMapping/AWSResourceMappingManager.h diff --git a/Gems/AWSCore/Code/Include/Private/ResourceMapping/AWSResourceMappingUtils.h b/Gems/AWSCore/Code/Source/ResourceMapping/AWSResourceMappingUtils.h similarity index 100% rename from Gems/AWSCore/Code/Include/Private/ResourceMapping/AWSResourceMappingUtils.h rename to Gems/AWSCore/Code/Source/ResourceMapping/AWSResourceMappingUtils.h diff --git a/Gems/AWSCore/Code/awscore_editor_files.cmake b/Gems/AWSCore/Code/awscore_editor_files.cmake index 44ba91a5d3..ebca45454e 100644 --- a/Gems/AWSCore/Code/awscore_editor_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_files.cmake @@ -7,25 +7,25 @@ # set(FILES - Include/Private/AWSCoreEditorSystemComponent.h - Include/Private/Editor/Attribution/AWSCoreAttributionConstant.h - Include/Private/Editor/Attribution/AWSCoreAttributionMetric.h - Include/Private/Editor/Attribution/AWSCoreAttributionManager.h - Include/Private/Editor/Attribution/AWSCoreAttributionSystemComponent.h - Include/Private/Editor/Attribution/AWSAttributionServiceApi.h - Include/Private/Editor/Attribution/AWSCoreAttributionConsentDialog.h - Include/Private/Editor/AWSCoreEditorManager.h - Include/Private/Editor/Constants/AWSCoreEditorMenuLinks.h - Include/Private/Editor/Constants/AWSCoreEditorMenuNames.h - Include/Private/Editor/UI/AWSCoreEditorMenu.h - Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h Source/AWSCoreEditorSystemComponent.cpp - Source/Editor/AWSCoreEditorManager.cpp + Source/AWSCoreEditorSystemComponent.h + Source/Editor/Attribution/AWSCoreAttributionConstant.h Source/Editor/Attribution/AWSCoreAttributionMetric.cpp + Source/Editor/Attribution/AWSCoreAttributionMetric.h Source/Editor/Attribution/AWSCoreAttributionManager.cpp + Source/Editor/Attribution/AWSCoreAttributionManager.h Source/Editor/Attribution/AWSCoreAttributionSystemComponent.cpp + Source/Editor/Attribution/AWSCoreAttributionSystemComponent.h Source/Editor/Attribution/AWSAttributionServiceApi.cpp + Source/Editor/Attribution/AWSAttributionServiceApi.h Source/Editor/Attribution/AWSCoreAttributionConsentDialog.cpp + Source/Editor/Attribution/AWSCoreAttributionConsentDialog.h + Source/Editor/AWSCoreEditorManager.cpp + Source/Editor/AWSCoreEditorManager.h + Source/Editor/Constants/AWSCoreEditorMenuLinks.h + Source/Editor/Constants/AWSCoreEditorMenuNames.h Source/Editor/UI/AWSCoreEditorMenu.cpp + Source/Editor/UI/AWSCoreEditorMenu.h Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp + Source/Editor/UI/AWSCoreResourceMappingToolAction.h ) diff --git a/Gems/AWSCore/Code/awscore_editor_shared_files.cmake b/Gems/AWSCore/Code/awscore_editor_shared_files.cmake index b44a9ffcb1..8bf2abc7e0 100644 --- a/Gems/AWSCore/Code/awscore_editor_shared_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_shared_files.cmake @@ -7,6 +7,6 @@ # set(FILES - Include/Private/AWSCoreEditorModule.h Source/AWSCoreEditorModule.cpp + Source/AWSCoreEditorModule.h ) diff --git a/Gems/AWSCore/Code/awscore_files.cmake b/Gems/AWSCore/Code/awscore_files.cmake index 34c05891a7..9abc162f8a 100644 --- a/Gems/AWSCore/Code/awscore_files.cmake +++ b/Gems/AWSCore/Code/awscore_files.cmake @@ -7,50 +7,54 @@ # set(FILES - Include/Public/AWSCoreBus.h - Include/Public/Credential/AWSCredentialBus.h - Include/Public/Framework/AWSApiClientJob.h - Include/Public/Framework/AWSApiClientJobConfig.h - Include/Public/Framework/AWSApiJob.h - Include/Public/Framework/AWSApiJobConfig.h - Include/Public/Framework/AWSApiRequestJob.h - Include/Public/Framework/AWSApiRequestJobConfig.h - Include/Public/Framework/Error.h - Include/Public/Framework/HttpClientComponent.h - Include/Public/Framework/HttpRequestJob.h - Include/Public/Framework/HttpRequestJobConfig.h - Include/Public/Framework/JobExecuter.h - Include/Public/Framework/JsonObjectHandler.h - Include/Public/Framework/JsonWriter.h - Include/Public/Framework/MultipartFormData.h - Include/Public/Framework/RequestBuilder.h - Include/Public/Framework/ServiceClientJob.h - Include/Public/Framework/ServiceClientJobConfig.h - Include/Public/Framework/ServiceJob.h - Include/Public/Framework/ServiceJobConfig.h - Include/Public/Framework/ServiceJobUtil.h - Include/Public/Framework/ServiceRequestJob.h - Include/Public/Framework/ServiceRequestJobConfig.h - Include/Public/Framework/Util.h - Include/Public/ResourceMapping/AWSResourceMappingBus.h - Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h - Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h - Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h - Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h - Include/Private/AWSCoreInternalBus.h - Include/Private/AWSCoreSystemComponent.h - Include/Private/Configuration/AWSCoreConfiguration.h - Include/Private/Credential/AWSCredentialManager.h - Include/Private/Credential/AWSCVarCredentialHandler.h - Include/Private/Credential/AWSDefaultCredentialHandler.h - Include/Private/ResourceMapping/AWSResourceMappingConstants.h - Include/Private/ResourceMapping/AWSResourceMappingManager.h - Include/Private/ResourceMapping/AWSResourceMappingUtils.h + Include/AWSCoreBus.h + Include/Credential/AWSCredentialBus.h + Include/Framework/AWSApiClientJob.h + Include/Framework/AWSApiClientJobConfig.h + Include/Framework/AWSApiJob.h + Include/Framework/AWSApiJobConfig.h + Include/Framework/AWSApiRequestJob.h + Include/Framework/AWSApiRequestJobConfig.h + Include/Framework/Error.h + Include/Framework/HttpClientComponent.h + Include/Framework/HttpRequestJob.h + Include/Framework/HttpRequestJobConfig.h + Include/Framework/JobExecuter.h + Include/Framework/JsonObjectHandler.h + Include/Framework/JsonWriter.h + Include/Framework/MultipartFormData.h + Include/Framework/RequestBuilder.h + Include/Framework/ServiceClientJob.h + Include/Framework/ServiceClientJobConfig.h + Include/Framework/ServiceJob.h + Include/Framework/ServiceJobConfig.h + Include/Framework/ServiceJobUtil.h + Include/Framework/ServiceRequestJob.h + Include/Framework/ServiceRequestJobConfig.h + Include/Framework/Util.h + Include/ResourceMapping/AWSResourceMappingBus.h + Include/ScriptCanvas/AWSScriptBehaviorDynamoDB.h + Include/ScriptCanvas/AWSScriptBehaviorLambda.h + Include/ScriptCanvas/AWSScriptBehaviorS3.h + Include/ScriptCanvas/AWSScriptBehaviorsComponent.h + + Source/AWSCoreInternalBus.h Source/AWSCoreSystemComponent.cpp + Source/AWSCoreSystemComponent.h Source/Configuration/AWSCoreConfiguration.cpp + Source/Configuration/AWSCoreConfiguration.h Source/Credential/AWSCredentialManager.cpp + Source/Credential/AWSCredentialManager.h Source/Credential/AWSCVarCredentialHandler.cpp + Source/Credential/AWSCVarCredentialHandler.h Source/Credential/AWSDefaultCredentialHandler.cpp + Source/Credential/AWSDefaultCredentialHandler.h + Source/ResourceMapping/AWSResourceMappingConstants.h + Source/ResourceMapping/AWSResourceMappingManager.cpp + Source/ResourceMapping/AWSResourceMappingManager.h + Source/ResourceMapping/AWSResourceMappingUtils.cpp + Source/ResourceMapping/AWSResourceMappingUtils.h + Source/Framework/AWSApiJob.cpp Source/Framework/AWSApiJobConfig.cpp Source/Framework/Error.cpp @@ -61,8 +65,6 @@ set(FILES Source/Framework/RequestBuilder.cpp Source/Framework/ServiceJob.cpp Source/Framework/ServiceJobConfig.cpp - Source/ResourceMapping/AWSResourceMappingManager.cpp - Source/ResourceMapping/AWSResourceMappingUtils.cpp Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp Source/ScriptCanvas/AWSScriptBehaviorS3.cpp diff --git a/Gems/AWSCore/Code/awscore_shared_files.cmake b/Gems/AWSCore/Code/awscore_shared_files.cmake index efe6966b26..4ce375b95a 100644 --- a/Gems/AWSCore/Code/awscore_shared_files.cmake +++ b/Gems/AWSCore/Code/awscore_shared_files.cmake @@ -7,6 +7,6 @@ # set(FILES - Include/Private/AWSCoreModule.h Source/AWSCoreModule.cpp + Source/AWSCoreModule.h ) From d3c50419a07c92c5e2a118566800122998b9ba4e Mon Sep 17 00:00:00 2001 From: godpiao <32320029+godpiao@users.noreply.github.com> Date: Thu, 2 Dec 2021 06:30:32 +0800 Subject: [PATCH 68/72] optimization ReverseUpAndDown function (#5972) change CImageEx:: ReverseUpDown function to avoid new uint32(width*height). Signed-off-by: godpiao --- Code/Editor/Util/Image.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Code/Editor/Util/Image.cpp b/Code/Editor/Util/Image.cpp index 773bfa93d2..8b26f54075 100644 --- a/Code/Editor/Util/Image.cpp +++ b/Code/Editor/Util/Image.cpp @@ -75,17 +75,16 @@ void CImageEx::ReverseUpDown() } uint32* pPixData = GetData(); - uint32* pReversePix = new uint32[GetWidth() * GetHeight()]; - - for (int i = GetHeight() - 1, i2 = 0; i >= 0; i--, i2++) + const int height = GetHeight(); + const int width = GetWidth(); + for (int i = 0; i < height / 2; i++) { - for (int k = 0; k < GetWidth(); k++) + for (int j = 0; j < width; j++) { - pReversePix[i2 * GetWidth() + k] = pPixData[i * GetWidth() + k]; + AZStd::swap(pPixData[i * width + j], pPixData[(height - 1 - i) * width + j]); } } - Attach(pReversePix, GetWidth(), GetHeight()); } void CImageEx::FillAlpha(unsigned char value) From c3461868d981aaac8828b362bdb79f2215bd7093 Mon Sep 17 00:00:00 2001 From: Junbo Liang <68558268+junbo75@users.noreply.github.com> Date: Wed, 1 Dec 2021 15:24:02 -0800 Subject: [PATCH 69/72] Move the header files in the AWS ClientAuth gem based on the latest gem structure guideline" (#5177) Signed-off-by: Junbo Liang <68558268+junbo75@users.noreply.github.com> --- Gems/AWSClientAuth/Code/CMakeLists.txt | 10 +-- .../AuthenticationProviderBus.h | 0 .../Authentication/AuthenticationTokens.h | 0 .../AWSCognitoAuthorizationBus.h | 0 .../Authorization/ClientAuthAWSCredentials.h | 0 .../AWSCognitoUserManagementBus.h | 0 .../Private => Source}/AWSClientAuthBus.h | 0 .../Private => Source}/AWSClientAuthModule.h | 0 .../AWSClientAuthResourceMappingConstants.h | 0 .../AWSClientAuthSystemComponent.h | 0 .../AWSCognitoAuthenticationProvider.h | 0 ...enticationNotificationBusBehaviorHandler.h | 0 .../AuthenticationProviderInterface.h | 0 .../AuthenticationProviderManager.h | 0 .../AuthenticationProviderScriptCanvasBus.h | 0 .../AuthenticationProviderTypes.h | 0 .../GoogleAuthenticationProvider.h | 0 .../LWAAuthenticationProvider.h | 0 .../Authentication/OAuthConstants.h | 0 ...oCachingAuthenticatedCredentialsProvider.h | 0 ...entAuthPersistentCognitoIdentityProvider.h | 0 .../AWSCognitoAuthorizationController.h | 0 ...horizationNotificationBusBehaviorHandler.h | 0 .../AWSCognitoUserManagementController.h | 0 ...ManagementNotificationBusBehaviorHandler.h | 0 .../Code/awsclientauth_files.cmake | 69 +++++++++---------- .../Code/awsclientauth_shared_files.cmake | 2 +- 27 files changed, 39 insertions(+), 42 deletions(-) rename Gems/AWSClientAuth/Code/Include/{Public => }/Authentication/AuthenticationProviderBus.h (100%) rename Gems/AWSClientAuth/Code/Include/{Public => }/Authentication/AuthenticationTokens.h (100%) rename Gems/AWSClientAuth/Code/Include/{Public => }/Authorization/AWSCognitoAuthorizationBus.h (100%) rename Gems/AWSClientAuth/Code/Include/{Public => }/Authorization/ClientAuthAWSCredentials.h (100%) rename Gems/AWSClientAuth/Code/Include/{Public => }/UserManagement/AWSCognitoUserManagementBus.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/AWSClientAuthBus.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/AWSClientAuthModule.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/AWSClientAuthResourceMappingConstants.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/AWSClientAuthSystemComponent.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/AWSCognitoAuthenticationProvider.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/AuthenticationNotificationBusBehaviorHandler.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/AuthenticationProviderInterface.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/AuthenticationProviderManager.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/AuthenticationProviderScriptCanvasBus.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/AuthenticationProviderTypes.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/GoogleAuthenticationProvider.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/LWAAuthenticationProvider.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authentication/OAuthConstants.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authorization/AWSCognitoAuthorizationController.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/UserManagement/AWSCognitoUserManagementController.h (100%) rename Gems/AWSClientAuth/Code/{Include/Private => Source}/UserManagement/UserManagementNotificationBusBehaviorHandler.h (100%) diff --git a/Gems/AWSClientAuth/Code/CMakeLists.txt b/Gems/AWSClientAuth/Code/CMakeLists.txt index bd8b174b65..1f0c119f5a 100644 --- a/Gems/AWSClientAuth/Code/CMakeLists.txt +++ b/Gems/AWSClientAuth/Code/CMakeLists.txt @@ -15,9 +15,9 @@ ly_add_target( awsclientauth_files.cmake INCLUDE_DIRECTORIES PUBLIC - Include/Public + Include PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE AZ::AzCore @@ -35,7 +35,7 @@ ly_add_target( awsclientauth_shared_files.cmake INCLUDE_DIRECTORIES PRIVATE - Include/Private + Source BUILD_DEPENDENCIES PRIVATE AZ::AzCore @@ -97,8 +97,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) awsclientauth_test_files.cmake INCLUDE_DIRECTORIES PRIVATE - "Include/Private" - "Include/Public" + Source + Include Tests BUILD_DEPENDENCIES PRIVATE diff --git a/Gems/AWSClientAuth/Code/Include/Public/Authentication/AuthenticationProviderBus.h b/Gems/AWSClientAuth/Code/Include/Authentication/AuthenticationProviderBus.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Public/Authentication/AuthenticationProviderBus.h rename to Gems/AWSClientAuth/Code/Include/Authentication/AuthenticationProviderBus.h diff --git a/Gems/AWSClientAuth/Code/Include/Public/Authentication/AuthenticationTokens.h b/Gems/AWSClientAuth/Code/Include/Authentication/AuthenticationTokens.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Public/Authentication/AuthenticationTokens.h rename to Gems/AWSClientAuth/Code/Include/Authentication/AuthenticationTokens.h diff --git a/Gems/AWSClientAuth/Code/Include/Public/Authorization/AWSCognitoAuthorizationBus.h b/Gems/AWSClientAuth/Code/Include/Authorization/AWSCognitoAuthorizationBus.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Public/Authorization/AWSCognitoAuthorizationBus.h rename to Gems/AWSClientAuth/Code/Include/Authorization/AWSCognitoAuthorizationBus.h diff --git a/Gems/AWSClientAuth/Code/Include/Public/Authorization/ClientAuthAWSCredentials.h b/Gems/AWSClientAuth/Code/Include/Authorization/ClientAuthAWSCredentials.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Public/Authorization/ClientAuthAWSCredentials.h rename to Gems/AWSClientAuth/Code/Include/Authorization/ClientAuthAWSCredentials.h diff --git a/Gems/AWSClientAuth/Code/Include/Public/UserManagement/AWSCognitoUserManagementBus.h b/Gems/AWSClientAuth/Code/Include/UserManagement/AWSCognitoUserManagementBus.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Public/UserManagement/AWSCognitoUserManagementBus.h rename to Gems/AWSClientAuth/Code/Include/UserManagement/AWSCognitoUserManagementBus.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthBus.h b/Gems/AWSClientAuth/Code/Source/AWSClientAuthBus.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthBus.h rename to Gems/AWSClientAuth/Code/Source/AWSClientAuthBus.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthModule.h b/Gems/AWSClientAuth/Code/Source/AWSClientAuthModule.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthModule.h rename to Gems/AWSClientAuth/Code/Source/AWSClientAuthModule.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthResourceMappingConstants.h b/Gems/AWSClientAuth/Code/Source/AWSClientAuthResourceMappingConstants.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthResourceMappingConstants.h rename to Gems/AWSClientAuth/Code/Source/AWSClientAuthResourceMappingConstants.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthSystemComponent.h b/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/AWSClientAuthSystemComponent.h rename to Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/AWSCognitoAuthenticationProvider.h b/Gems/AWSClientAuth/Code/Source/Authentication/AWSCognitoAuthenticationProvider.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/AWSCognitoAuthenticationProvider.h rename to Gems/AWSClientAuth/Code/Source/Authentication/AWSCognitoAuthenticationProvider.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationNotificationBusBehaviorHandler.h b/Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationNotificationBusBehaviorHandler.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationNotificationBusBehaviorHandler.h rename to Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationNotificationBusBehaviorHandler.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderInterface.h b/Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderInterface.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderInterface.h rename to Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderInterface.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderManager.h b/Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderManager.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderManager.h rename to Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderManager.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderScriptCanvasBus.h b/Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderScriptCanvasBus.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderScriptCanvasBus.h rename to Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderScriptCanvasBus.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderTypes.h b/Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderTypes.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/AuthenticationProviderTypes.h rename to Gems/AWSClientAuth/Code/Source/Authentication/AuthenticationProviderTypes.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/GoogleAuthenticationProvider.h b/Gems/AWSClientAuth/Code/Source/Authentication/GoogleAuthenticationProvider.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/GoogleAuthenticationProvider.h rename to Gems/AWSClientAuth/Code/Source/Authentication/GoogleAuthenticationProvider.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/LWAAuthenticationProvider.h b/Gems/AWSClientAuth/Code/Source/Authentication/LWAAuthenticationProvider.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/LWAAuthenticationProvider.h rename to Gems/AWSClientAuth/Code/Source/Authentication/LWAAuthenticationProvider.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authentication/OAuthConstants.h b/Gems/AWSClientAuth/Code/Source/Authentication/OAuthConstants.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authentication/OAuthConstants.h rename to Gems/AWSClientAuth/Code/Source/Authentication/OAuthConstants.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h b/Gems/AWSClientAuth/Code/Source/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h rename to Gems/AWSClientAuth/Code/Source/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h b/Gems/AWSClientAuth/Code/Source/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h rename to Gems/AWSClientAuth/Code/Source/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSCognitoAuthorizationController.h b/Gems/AWSClientAuth/Code/Source/Authorization/AWSCognitoAuthorizationController.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSCognitoAuthorizationController.h rename to Gems/AWSClientAuth/Code/Source/Authorization/AWSCognitoAuthorizationController.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h b/Gems/AWSClientAuth/Code/Source/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h rename to Gems/AWSClientAuth/Code/Source/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/UserManagement/AWSCognitoUserManagementController.h b/Gems/AWSClientAuth/Code/Source/UserManagement/AWSCognitoUserManagementController.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/UserManagement/AWSCognitoUserManagementController.h rename to Gems/AWSClientAuth/Code/Source/UserManagement/AWSCognitoUserManagementController.h diff --git a/Gems/AWSClientAuth/Code/Include/Private/UserManagement/UserManagementNotificationBusBehaviorHandler.h b/Gems/AWSClientAuth/Code/Source/UserManagement/UserManagementNotificationBusBehaviorHandler.h similarity index 100% rename from Gems/AWSClientAuth/Code/Include/Private/UserManagement/UserManagementNotificationBusBehaviorHandler.h rename to Gems/AWSClientAuth/Code/Source/UserManagement/UserManagementNotificationBusBehaviorHandler.h diff --git a/Gems/AWSClientAuth/Code/awsclientauth_files.cmake b/Gems/AWSClientAuth/Code/awsclientauth_files.cmake index 3b07b710e7..5de71210af 100644 --- a/Gems/AWSClientAuth/Code/awsclientauth_files.cmake +++ b/Gems/AWSClientAuth/Code/awsclientauth_files.cmake @@ -7,46 +7,43 @@ # set(FILES - Include/Public/Authentication/AuthenticationProviderBus.h - Include/Public/Authentication/AuthenticationTokens.h - Include/Public/Authorization/AWSCognitoAuthorizationBus.h - Include/Public/Authorization/ClientAuthAWSCredentials.h - Include/Public/UserManagement/AWSCognitoUserManagementBus.h + Include/Authentication/AuthenticationProviderBus.h + Include/Authentication/AuthenticationTokens.h + Include/Authorization/AWSCognitoAuthorizationBus.h + Include/Authorization/ClientAuthAWSCredentials.h + Include/UserManagement/AWSCognitoUserManagementBus.h - Include/Private/AWSClientAuthSystemComponent.h - Include/Private/AWSClientAuthBus.h - Include/Private/AWSClientAuthResourceMappingConstants.h - Include/Private/Authentication/AuthenticationProviderTypes.h - Include/Private/Authentication/AuthenticationProviderScriptCanvasBus.h - Include/Private/Authentication/AuthenticationProviderManager.h - Include/Private/Authentication/AuthenticationNotificationBusBehaviorHandler.h - - Include/Private/Authorization/AWSCognitoAuthorizationController.h - Include/Private/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h - Include/Private/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h - Include/Private/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h - - Include/Private/UserManagement/AWSCognitoUserManagementController.h - Include/Private/UserManagement/UserManagementNotificationBusBehaviorHandler.h - - Include/Private/Authentication/AuthenticationProviderInterface.h - Include/Private/Authentication/OAuthConstants.h - Include/Private/Authentication/AWSCognitoAuthenticationProvider.h - Include/Private/Authentication/LWAAuthenticationProvider.h - Include/Private/Authentication/GoogleAuthenticationProvider.h - Source/AWSClientAuthSystemComponent.cpp - Source/Authentication/AuthenticationTokens.cpp - Source/Authentication/AuthenticationProviderInterface.cpp - Source/Authentication/AuthenticationProviderManager.cpp - Source/Authentication/AWSCognitoAuthenticationProvider.cpp - Source/Authentication/LWAAuthenticationProvider.cpp - Source/Authentication/GoogleAuthenticationProvider.cpp + Source/AWSClientAuthSystemComponent.h + Source/AWSClientAuthBus.h + Source/AWSClientAuthResourceMappingConstants.h + + Source/Authentication/AuthenticationNotificationBusBehaviorHandler.h + Source/Authentication/AuthenticationProviderInterface.cpp + Source/Authentication/AuthenticationProviderInterface.h + Source/Authentication/AuthenticationProviderManager.cpp + Source/Authentication/AuthenticationProviderManager.h + Source/Authentication/AuthenticationProviderScriptCanvasBus.h + Source/Authentication/AuthenticationProviderTypes.h + Source/Authentication/AuthenticationTokens.cpp + Source/Authentication/AWSCognitoAuthenticationProvider.cpp + Source/Authentication/AWSCognitoAuthenticationProvider.h + Source/Authentication/LWAAuthenticationProvider.cpp + Source/Authentication/LWAAuthenticationProvider.h + Source/Authentication/GoogleAuthenticationProvider.cpp + Source/Authentication/GoogleAuthenticationProvider.h + Source/Authentication/OAuthConstants.h - Source/Authorization/ClientAuthAWSCredentials.cpp - Source/Authorization/AWSCognitoAuthorizationController.cpp - Source/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.cpp Source/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.cpp + Source/Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h + Source/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.cpp + Source/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h + Source/Authorization/AWSCognitoAuthorizationController.cpp + Source/Authorization/AWSCognitoAuthorizationController.h + Source/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h + Source/Authorization/ClientAuthAWSCredentials.cpp Source/UserManagement/AWSCognitoUserManagementController.cpp + Source/UserManagement/AWSCognitoUserManagementController.h + Source/UserManagement/UserManagementNotificationBusBehaviorHandler.h ) diff --git a/Gems/AWSClientAuth/Code/awsclientauth_shared_files.cmake b/Gems/AWSClientAuth/Code/awsclientauth_shared_files.cmake index 6297f400fd..cca6184641 100644 --- a/Gems/AWSClientAuth/Code/awsclientauth_shared_files.cmake +++ b/Gems/AWSClientAuth/Code/awsclientauth_shared_files.cmake @@ -7,6 +7,6 @@ # set(FILES - Include/Private/AWSClientAuthModule.h Source/AWSClientAuthModule.cpp + Source/AWSClientAuthModule.h ) From 8b3c76d8b8326fa714fcf80bcc755ed0ea21edf6 Mon Sep 17 00:00:00 2001 From: Mike Chang Date: Wed, 1 Dec 2021 17:14:00 -0800 Subject: [PATCH 70/72] Add platform specific codesign script and modifications for Linux and Windows installer packaging (#5893) Signed-off-by: Mike Chang --- cmake/Packaging.cmake | 1 + .../Linux/PackagingCodeSign_linux.cmake | 33 +++++++++++ .../Linux/PackagingPostBuild_linux.cmake | 10 ++-- .../Linux/PackagingPreBuild_linux.cmake | 4 +- .../Platform/Linux/platform_linux_files.cmake | 1 + .../Windows/PackagingCodeSign_windows.cmake | 56 +++++++++++++++++++ .../Windows/PackagingPostBuild_windows.cmake | 48 +--------------- .../Windows/PackagingPreBuild_windows.cmake | 46 +-------------- .../Windows/platform_windows_files.cmake | 1 + .../build/Platform/Linux/build_config.json | 3 + scripts/signer/Platform/Linux/signer.sh | 0 11 files changed, 107 insertions(+), 96 deletions(-) create mode 100644 cmake/Platform/Linux/PackagingCodeSign_linux.cmake create mode 100644 cmake/Platform/Windows/PackagingCodeSign_windows.cmake mode change 100644 => 100755 scripts/signer/Platform/Linux/signer.sh diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake index d716efb225..4ba4e750de 100644 --- a/cmake/Packaging.cmake +++ b/cmake/Packaging.cmake @@ -111,6 +111,7 @@ set(CPACK_STRIP_FILES TRUE) # always strip symbols on packaging set(CPACK_PACKAGE_CHECKSUM SHA256) # Generate checksum file set(CPACK_PRE_BUILD_SCRIPTS ${pal_dir}/PackagingPreBuild_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake) set(CPACK_POST_BUILD_SCRIPTS ${pal_dir}/PackagingPostBuild_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake) +set(CPACK_CODESIGN_SCRIPT ${pal_dir}/PackagingCodeSign_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake) set(CPACK_LY_PYTHON_CMD ${LY_PYTHON_CMD}) # IMPORTANT: required to be included AFTER setting all property overrides diff --git a/cmake/Platform/Linux/PackagingCodeSign_linux.cmake b/cmake/Platform/Linux/PackagingCodeSign_linux.cmake new file mode 100644 index 0000000000..c4b6375385 --- /dev/null +++ b/cmake/Platform/Linux/PackagingCodeSign_linux.cmake @@ -0,0 +1,33 @@ +# +# 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 +# +# + +function(ly_sign_binaries in_path) + message(STATUS "Executing package signing...") + file(REAL_PATH "${CPACK_SOURCE_DIR}/.." _root_path) + unset(_signing_command) + + cmake_path(SET _sign_script "${_root_path}/scripts/signer/Platform/Linux/signer.sh") + + list(APPEND _signing_command + ${_sign_script} + ) + message(STATUS "Signing package files in ${in_path}") + execute_process( + COMMAND ${_signing_command} ${in_path} + RESULT_VARIABLE _signing_result + ERROR_VARIABLE _signing_errors + OUTPUT_VARIABLE _signing_output + ECHO_OUTPUT_VARIABLE + ) + + if(NOT ${_signing_result} EQUAL 0) + message(FATAL_ERROR "An error occurred during signing files. ${_signing_errors}") + else() + message(STATUS "Signing complete!") + endif() +endfunction() diff --git a/cmake/Platform/Linux/PackagingPostBuild_linux.cmake b/cmake/Platform/Linux/PackagingPostBuild_linux.cmake index d92ee908fd..ebeefe3833 100644 --- a/cmake/Platform/Linux/PackagingPostBuild_linux.cmake +++ b/cmake/Platform/Linux/PackagingPostBuild_linux.cmake @@ -8,6 +8,7 @@ file(REAL_PATH "${CPACK_SOURCE_DIR}/.." LY_ROOT_FOLDER) include(${LY_ROOT_FOLDER}/cmake/Platform/Common/PackagingPostBuild_common.cmake) +include(${CPACK_CODESIGN_SCRIPT}) file(${CPACK_PACKAGE_CHECKSUM} ${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}.deb file_checksum) file(WRITE ${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}.deb.sha256 "${file_checksum} ${CPACK_PACKAGE_FILE_NAME}.deb") @@ -19,6 +20,10 @@ if(CPACK_UPLOAD_URL) set(CPACK_UPLOAD_DIRECTORY ${CPACK_PACKAGE_DIRECTORY}/CPackUploads) endif() + # Sign and regenerate checksum + ly_sign_binaries("${CPACK_TOPLEVEL_DIRECTORY}/*.deb" "") + file(WRITE ${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}.deb.sha256 "${file_checksum} ${CPACK_PACKAGE_FILE_NAME}.deb") + # Copy the artifacts intended to be uploaded to a remote server into the folder specified # through CPACK_UPLOAD_DIRECTORY. This mimics the same process cpack does natively for # some other frameworks that have built-in online installer support. @@ -27,14 +32,13 @@ if(CPACK_UPLOAD_URL) file(GLOB _artifacts "${CPACK_TOPLEVEL_DIRECTORY}/*.deb" "${CPACK_TOPLEVEL_DIRECTORY}/*.sha256" + "${LY_ROOT_FOLDER}/scripts/signer/Platform/Linux/*.gpg" ) file(COPY ${_artifacts} DESTINATION ${CPACK_UPLOAD_DIRECTORY} ) message(STATUS "Artifacts copied to ${CPACK_UPLOAD_DIRECTORY}") - # TODO: copy gpg file to CPACK_UPLOAD_DIRECTORY - ly_upload_to_url( ${CPACK_UPLOAD_URL} ${CPACK_UPLOAD_DIRECTORY} @@ -51,8 +55,6 @@ if(CPACK_UPLOAD_URL) ${latest_deb_package} ) ly_upload_to_latest(${CPACK_UPLOAD_URL} ${latest_deb_package}) - - # TODO: upload gpg file to latest # Generate a checksum file for latest and upload it set(latest_hash_file "${CPACK_UPLOAD_DIRECTORY}/${CPACK_PACKAGE_NAME}_latest.deb.sha256") diff --git a/cmake/Platform/Linux/PackagingPreBuild_linux.cmake b/cmake/Platform/Linux/PackagingPreBuild_linux.cmake index 31dc393307..39108355ea 100644 --- a/cmake/Platform/Linux/PackagingPreBuild_linux.cmake +++ b/cmake/Platform/Linux/PackagingPreBuild_linux.cmake @@ -9,8 +9,6 @@ file(REAL_PATH "${CPACK_SOURCE_DIR}/.." LY_ROOT_FOLDER) include(${LY_ROOT_FOLDER}/cmake/Platform/Common/PackagingPreBuild_common.cmake) -if(NOT CPACK_UPLOAD_URL) # Skip signing if we are not uploading the package +if(NOT CPACK_UPLOAD_URL) # Skip this step if we are not uploading the package return() endif() - -# TODO: do signing diff --git a/cmake/Platform/Linux/platform_linux_files.cmake b/cmake/Platform/Linux/platform_linux_files.cmake index d30959b8d2..dd10c47ca6 100644 --- a/cmake/Platform/Linux/platform_linux_files.cmake +++ b/cmake/Platform/Linux/platform_linux_files.cmake @@ -18,6 +18,7 @@ set(FILES LYTestWrappers_linux.cmake LYWrappers_linux.cmake Packaging_linux.cmake + PackagingCodeSign_linux.cmake PackagingPostBuild_linux.cmake PackagingPreBuild_linux.cmake PAL_linux.cmake diff --git a/cmake/Platform/Windows/PackagingCodeSign_windows.cmake b/cmake/Platform/Windows/PackagingCodeSign_windows.cmake new file mode 100644 index 0000000000..8ef7f79e40 --- /dev/null +++ b/cmake/Platform/Windows/PackagingCodeSign_windows.cmake @@ -0,0 +1,56 @@ +# +# 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 +# +# + +function(ly_sign_binaries in_path in_path_type) + message(STATUS "Executing package signing...") + file(REAL_PATH "${CPACK_SOURCE_DIR}/.." _root_path) + unset(_signing_command) + + cmake_path(SET _sign_script "${_root_path}/scripts/signer/Platform/Windows/signer.ps1") + + find_program(_psiexec_path psexec.exe) + if(_psiexec_path) + list(APPEND _signing_command + ${_psiexec_path} + -accepteula + -nobanner + -s + ) + endif() + + find_program(_powershell_path powershell.exe REQUIRED) + list(APPEND _signing_command + ${_powershell_path} + -NoLogo + -ExecutionPolicy Bypass + -File ${_sign_script} + ) + + # This requires to have a valid local certificate. In continuous integration, these certificates are stored + # in the machine directly. + # You can generate a test certificate to be able to run this in a PowerShell elevated promp with: + # New-SelfSignedCertificate -DnsName foo.o3de.com -Type CodeSigning -CertStoreLocation Cert:\CurrentUser\My + # Export-Certificate -Cert (Get-ChildItem Cert:\CurrentUser\My\) -Filepath "c:\selfsigned.crt" + # Import-Certificate -FilePath "c:\selfsigned.crt" -Cert Cert:\CurrentUser\TrustedPublisher + # Import-Certificate -FilePath "c:\selfsigned.crt" -Cert Cert:\CurrentUser\Root + + message(STATUS "Signing ${in_path_type} files in ${in_path}") + execute_process( + COMMAND ${_signing_command} -${in_path_type} ${in_path} + RESULT_VARIABLE _signing_result + ERROR_VARIABLE _signing_errors + OUTPUT_VARIABLE _signing_output + ECHO_OUTPUT_VARIABLE + ) + + if(NOT ${_signing_result} EQUAL 0) + message(FATAL_ERROR "An error occurred during signing files for ${in_path_type}. ${_signing_errors}") + else() + message(STATUS "Signing complete!") + endif() +endfunction() diff --git a/cmake/Platform/Windows/PackagingPostBuild_windows.cmake b/cmake/Platform/Windows/PackagingPostBuild_windows.cmake index 0993135c23..10f0f902a3 100644 --- a/cmake/Platform/Windows/PackagingPostBuild_windows.cmake +++ b/cmake/Platform/Windows/PackagingPostBuild_windows.cmake @@ -8,6 +8,7 @@ file(REAL_PATH "${CPACK_SOURCE_DIR}/.." LY_ROOT_FOLDER) include(${LY_ROOT_FOLDER}/cmake/Platform/Common/PackagingPostBuild_common.cmake) +include(${CPACK_CODESIGN_SCRIPT}) # convert the path to a windows style path using string replace because TO_NATIVE_PATH # only works on real paths @@ -59,39 +60,7 @@ set(_light_command ) if(CPACK_UPLOAD_URL) # Skip signing if we are not uploading the package - file(TO_NATIVE_PATH "${LY_ROOT_FOLDER}/scripts/signer/Platform/Windows/signer.ps1" _sign_script) - - unset(_signing_command) - find_program(_psiexec_path psexec.exe) - if(_psiexec_path) - list(APPEND _signing_command - ${_psiexec_path} - -accepteula - -nobanner - -s - ) - endif() - - find_program(_powershell_path powershell.exe REQUIRED) - list(APPEND _signing_command - ${_powershell_path} - -NoLogo - -ExecutionPolicy Bypass - -File ${_sign_script} - ) - - message(STATUS "Signing package files in ${_cpack_wix_out_dir}") - execute_process( - COMMAND ${_signing_command} -packagePath ${_cpack_wix_out_dir} - RESULT_VARIABLE _signing_result - ERROR_VARIABLE _signing_errors - OUTPUT_VARIABLE _signing_output - ECHO_OUTPUT_VARIABLE - ) - - if(NOT ${_signing_result} EQUAL 0) - message(FATAL_ERROR "An error occurred during signing package files. ${_signing_errors}") - endif() + ly_sign_binaries("${_cpack_wix_out_dir}" "packagePath") endif() message(STATUS "Creating Bootstrap Installer...") @@ -116,18 +85,7 @@ endif() message(STATUS "Bootstrap installer generated to ${_bootstrap_output_file}") if(CPACK_UPLOAD_URL) # Skip signing if we are not uploading the package - message(STATUS "Signing bootstrap installer in ${_bootstrap_output_file}") - execute_process( - COMMAND ${_signing_command} -bootstrapPath ${_bootstrap_output_file} - RESULT_VARIABLE _signing_result - ERROR_VARIABLE _signing_errors - OUTPUT_VARIABLE _signing_output - ECHO_OUTPUT_VARIABLE - ) - - if(NOT ${_signing_result} EQUAL 0) - message(FATAL_ERROR "An error occurred during signing bootstrap installer. ${_signing_errors}") - endif() + ly_sign_binaries("${_bootstrap_output_file}" "bootstrapPath") endif() # use the internal default path if somehow not specified from cpack_configure_downloads diff --git a/cmake/Platform/Windows/PackagingPreBuild_windows.cmake b/cmake/Platform/Windows/PackagingPreBuild_windows.cmake index 29995518da..b6b5708a8c 100644 --- a/cmake/Platform/Windows/PackagingPreBuild_windows.cmake +++ b/cmake/Platform/Windows/PackagingPreBuild_windows.cmake @@ -8,53 +8,11 @@ file(REAL_PATH "${CPACK_SOURCE_DIR}/.." LY_ROOT_FOLDER) include(${LY_ROOT_FOLDER}/cmake/Platform/Common/PackagingPreBuild_common.cmake) +include(${CPACK_CODESIGN_SCRIPT}) if(NOT CPACK_UPLOAD_URL) # Skip signing if we are not uploading the package return() endif() -file(REAL_PATH "${CPACK_SOURCE_DIR}/.." _root_path) set(_cpack_wix_out_dir ${CPACK_TOPLEVEL_DIRECTORY}) -file(TO_NATIVE_PATH "${_root_path}/scripts/signer/Platform/Windows/signer.ps1" _sign_script) - -unset(_signing_command) -find_program(_psiexec_path psexec.exe) -if(_psiexec_path) - list(APPEND _signing_command - ${_psiexec_path} - -accepteula - -nobanner - -s - ) -endif() - -find_program(_powershell_path powershell.exe REQUIRED) -list(APPEND _signing_command - ${_powershell_path} - -NoLogo - -ExecutionPolicy Bypass - -File ${_sign_script} -) - -# This requires to have a valid local certificate. In continuous integration, these certificates are stored -# in the machine directly. -# You can generate a test certificate to be able to run this in a PowerShell elevated promp with: -# New-SelfSignedCertificate -DnsName foo.o3de.com -Type CodeSigning -CertStoreLocation Cert:\CurrentUser\My -# Export-Certificate -Cert (Get-ChildItem Cert:\CurrentUser\My\) -Filepath "c:\selfsigned.crt" -# Import-Certificate -FilePath "c:\selfsigned.crt" -Cert Cert:\CurrentUser\TrustedPublisher -# Import-Certificate -FilePath "c:\selfsigned.crt" -Cert Cert:\CurrentUser\Root - -message(STATUS "Signing executable files in ${_cpack_wix_out_dir}") -execute_process( - COMMAND ${_signing_command} -exePath ${_cpack_wix_out_dir} - RESULT_VARIABLE _signing_result - ERROR_VARIABLE _signing_errors - OUTPUT_VARIABLE _signing_output - ECHO_OUTPUT_VARIABLE -) - -if(NOT ${_signing_result} EQUAL 0) - message(FATAL_ERROR "An error occurred during signing executable files. ${_signing_errors}") -else() - message(STATUS "Signing exes complete!") -endif() +ly_sign_binaries("${_cpack_wix_out_dir}" "exePath") \ No newline at end of file diff --git a/cmake/Platform/Windows/platform_windows_files.cmake b/cmake/Platform/Windows/platform_windows_files.cmake index 984d985380..8ad242f842 100644 --- a/cmake/Platform/Windows/platform_windows_files.cmake +++ b/cmake/Platform/Windows/platform_windows_files.cmake @@ -25,6 +25,7 @@ set(FILES PALDetection_windows.cmake Install_windows.cmake Packaging_windows.cmake + PackagingCodeSign_windows.cmake PackagingPostBuild_windows.cmake PackagingPreBuild_windows.cmake Packaging/Bootstrapper.wxs diff --git a/scripts/build/Platform/Linux/build_config.json b/scripts/build/Platform/Linux/build_config.json index db9e2e7b8a..b6fcd5b0ba 100644 --- a/scripts/build/Platform/Linux/build_config.json +++ b/scripts/build/Platform/Linux/build_config.json @@ -230,6 +230,9 @@ "nightly-clean", "nightly-installer" ], + "PIPELINE_ENV":{ + "NODE_LABEL":"linux-707531fc7-packaging" + }, "COMMAND": "build_installer_linux.sh", "PARAMETERS": { "CONFIGURATION": "profile", diff --git a/scripts/signer/Platform/Linux/signer.sh b/scripts/signer/Platform/Linux/signer.sh old mode 100644 new mode 100755 From b897b2084c54627617a8dfd1ebebb3a36ec5576f Mon Sep 17 00:00:00 2001 From: Roman <69218254+amzn-rhhong@users.noreply.github.com> Date: Wed, 1 Dec 2021 20:50:51 -0800 Subject: [PATCH 71/72] BUGFIX improve the start up time of the atom render plugin (#6065) Signed-off-by: rhhong --- .../EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp index 396042c9f6..ef6ff4681a 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp @@ -128,6 +128,7 @@ namespace EMStudio m_groundEntity->CreateComponent(AZ::Render::MeshComponentTypeId); m_groundEntity->CreateComponent(AZ::Render::MaterialComponentTypeId); m_groundEntity->CreateComponent(azrtti_typeid()); + m_groundEntity->Init(); m_groundEntity->Activate(); Reinit(); From bd1c8ec96165da04e202f3dd74abde688195bf0d Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Thu, 2 Dec 2021 01:28:29 -0800 Subject: [PATCH 72/72] chore: remove duplicate instance of FancyDockingDropZoneConstants (#5827) * chore: remove duplicate instance of FancyDockingDropZoneConstants Signed-off-by: Michael Pollind * chore: move to namespace Signed-off-by: Michael Pollind --- .../Components/FancyDocking.cpp | 43 +++++++++---------- .../Components/FancyDockingDropZoneWidget.cpp | 34 +++------------ .../Components/FancyDockingDropZoneWidget.h | 37 +++++++--------- 3 files changed, 44 insertions(+), 70 deletions(-) diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp index af902f97a0..7e78f64778 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp @@ -53,7 +53,6 @@ static void OptimizedSetParent(QWidget* widget, QWidget* parent) namespace AzQtComponents { - static const FancyDockingDropZoneConstants g_FancyDockingConstants; // Constant for the threshold in pixels for snapping to edges while dragging for docking static const int g_snapThresholdInPixels = 15; @@ -155,7 +154,7 @@ namespace AzQtComponents // Timer for updating our hovered drop zone opacity QObject::connect(m_dropZoneHoverFadeInTimer, &QTimer::timeout, this, &FancyDocking::onDropZoneHoverFadeInUpdate); - m_dropZoneHoverFadeInTimer->setInterval(g_FancyDockingConstants.dropZoneHoverFadeUpdateIntervalMS); + m_dropZoneHoverFadeInTimer->setInterval(FancyDockingDropZoneConstants::dropZoneHoverFadeUpdateIntervalMS); QIcon dragIcon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg")); m_dragCursor = QCursor(dragIcon.pixmap(16), 5, 2); } @@ -333,13 +332,13 @@ namespace AzQtComponents */ void FancyDocking::onDropZoneHoverFadeInUpdate() { - const qreal dropZoneHoverOpacity = g_FancyDockingConstants.dropZoneHoverFadeIncrement + m_dropZoneState.dropZoneHoverOpacity(); + const qreal dropZoneHoverOpacity = FancyDockingDropZoneConstants::dropZoneHoverFadeIncrement + m_dropZoneState.dropZoneHoverOpacity(); // Once we've reached the full drop zone opacity, cut it off in case we // went over and stop the timer - if (dropZoneHoverOpacity >= g_FancyDockingConstants.dropZoneOpacity) + if (dropZoneHoverOpacity >= FancyDockingDropZoneConstants::dropZoneOpacity) { - m_dropZoneState.setDropZoneHoverOpacity(g_FancyDockingConstants.dropZoneOpacity); + m_dropZoneState.setDropZoneHoverOpacity(FancyDockingDropZoneConstants::dropZoneOpacity); m_dropZoneHoverFadeInTimer->stop(); } else @@ -792,12 +791,12 @@ namespace AzQtComponents QPoint mainWindowTopLeft = multiscreenMapFromGlobal(mainWindow->mapToGlobal(mainWindowRect.topLeft())); QPoint mainWindowTopRight = multiscreenMapFromGlobal(mainWindow->mapToGlobal(mainWindowRect.topRight())); QPoint mainWindowBottomLeft = multiscreenMapFromGlobal(mainWindow->mapToGlobal(mainWindowRect.bottomLeft())); - QSize absoluteLeftRightSize(g_FancyDockingConstants.absoluteDropZoneSizeInPixels, mainWindowRect.height()); + QSize absoluteLeftRightSize(FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels, mainWindowRect.height()); QRect absoluteLeftDropZone(mainWindowTopLeft, absoluteLeftRightSize); - QRect absoluteRightDropZone(mainWindowTopRight - QPoint(g_FancyDockingConstants.absoluteDropZoneSizeInPixels, 0), absoluteLeftRightSize); - QSize absoluteTopBottomSize(mainWindowRect.width(), g_FancyDockingConstants.absoluteDropZoneSizeInPixels); + QRect absoluteRightDropZone(mainWindowTopRight - QPoint(FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels, 0), absoluteLeftRightSize); + QSize absoluteTopBottomSize(mainWindowRect.width(), FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels); QRect absoluteTopDropZone(mainWindowTopLeft, absoluteTopBottomSize); - QRect absoluteBottomDropZone(mainWindowBottomLeft - QPoint(0, g_FancyDockingConstants.absoluteDropZoneSizeInPixels), absoluteTopBottomSize); + QRect absoluteBottomDropZone(mainWindowBottomLeft - QPoint(0, FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels), absoluteTopBottomSize); // If the drop target is a main window, then we will only show the absolute // drop zone if the cursor is in that zone already @@ -986,16 +985,16 @@ namespace AzQtComponents switch (m_dropZoneState.absoluteDropZoneArea()) { case Qt::LeftDockWidgetArea: - dockRect.setX(dockRect.x() + g_FancyDockingConstants.absoluteDropZoneSizeInPixels); + dockRect.setX(dockRect.x() + FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels); break; case Qt::RightDockWidgetArea: - dockRect.setWidth(dockRect.width() - g_FancyDockingConstants.absoluteDropZoneSizeInPixels); + dockRect.setWidth(dockRect.width() - FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels); break; case Qt::TopDockWidgetArea: - dockRect.setY(dockRect.y() + g_FancyDockingConstants.absoluteDropZoneSizeInPixels); + dockRect.setY(dockRect.y() + FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels); break; case Qt::BottomDockWidgetArea: - dockRect.setHeight(dockRect.height() - g_FancyDockingConstants.absoluteDropZoneSizeInPixels); + dockRect.setHeight(dockRect.height() - FancyDockingDropZoneConstants::absoluteDropZoneSizeInPixels); break; } @@ -1034,15 +1033,15 @@ namespace AzQtComponents // Set the drop zone width/height to the default, but if the dock widget // width and/or height is below the threshold, then switch to scaling them // down accordingly - int dropZoneWidth = g_FancyDockingConstants.dropZoneSizeInPixels; - if (dockWidth < g_FancyDockingConstants.minDockSizeBeforeDropZoneScalingInPixels) + int dropZoneWidth = FancyDockingDropZoneConstants::dropZoneSizeInPixels; + if (dockWidth < FancyDockingDropZoneConstants::minDockSizeBeforeDropZoneScalingInPixels) { - dropZoneWidth = aznumeric_cast(dockWidth * g_FancyDockingConstants.dropZoneScaleFactor); + dropZoneWidth = aznumeric_cast(dockWidth * FancyDockingDropZoneConstants::dropZoneScaleFactor); } - int dropZoneHeight = g_FancyDockingConstants.dropZoneSizeInPixels; - if (dockHeight < g_FancyDockingConstants.minDockSizeBeforeDropZoneScalingInPixels) + int dropZoneHeight = FancyDockingDropZoneConstants::dropZoneSizeInPixels; + if (dockHeight < FancyDockingDropZoneConstants::minDockSizeBeforeDropZoneScalingInPixels) { - dropZoneHeight = aznumeric_cast(dockHeight * g_FancyDockingConstants.dropZoneScaleFactor); + dropZoneHeight = aznumeric_cast(dockHeight * FancyDockingDropZoneConstants::dropZoneScaleFactor); } // Calculate the inner corners to be used when constructing the drop zone polygons @@ -1078,7 +1077,7 @@ namespace AzQtComponents int innerDropZoneWidth = m_dropZoneState.innerDropZoneRect().width(); int innerDropZoneHeight = m_dropZoneState.innerDropZoneRect().height(); int centerDropZoneDiameter = (innerDropZoneWidth < innerDropZoneHeight) ? innerDropZoneWidth : innerDropZoneHeight; - centerDropZoneDiameter = aznumeric_cast(centerDropZoneDiameter * g_FancyDockingConstants.centerTabDropZoneScale); + centerDropZoneDiameter = aznumeric_cast(centerDropZoneDiameter * FancyDockingDropZoneConstants::centerTabDropZoneScale); // Setup our center tab drop zone const QSize centerDropZoneSize(centerDropZoneDiameter, centerDropZoneDiameter); @@ -1986,7 +1985,7 @@ namespace AzQtComponents // hasn't faded in all the way yet, then ignore the drop zone area // which will make the widget floating bool modifiedKeyPressed = FancyDockingDropZoneWidget::CheckModifierKey(); - if (modifiedKeyPressed || m_dropZoneState.dropZoneHoverOpacity() != g_FancyDockingConstants.dropZoneOpacity) + if (modifiedKeyPressed || m_dropZoneState.dropZoneHoverOpacity() != FancyDockingDropZoneConstants::dropZoneOpacity) { area = Qt::NoDockWidgetArea; } @@ -3026,7 +3025,7 @@ namespace AzQtComponents { bool modifiedKeyPressed = FancyDockingDropZoneWidget::CheckModifierKey(); - m_ghostWidget->setWindowOpacity(modifiedKeyPressed ? 1.0f : g_FancyDockingConstants.draggingDockWidgetOpacity); + m_ghostWidget->setWindowOpacity(modifiedKeyPressed ? 1.0f : FancyDockingDropZoneConstants::draggingDockWidgetOpacity); m_ghostWidget->setPixmap(m_state.dockWidgetScreenGrab.screenGrab, m_state.placeholder(), m_state.placeholderScreen()); } } diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.cpp index 1451094ea1..3873f0389b 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.cpp +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.cpp @@ -19,26 +19,6 @@ namespace AzQtComponents { - static const FancyDockingDropZoneConstants g_Constants; - - FancyDockingDropZoneConstants::FancyDockingDropZoneConstants() - { - draggingDockWidgetOpacity = 0.6; - dropZoneOpacity = 0.4; - dropZoneSizeInPixels = 40; - minDockSizeBeforeDropZoneScalingInPixels = dropZoneSizeInPixels * 3; - dropZoneScaleFactor = 0.25; - centerTabDropZoneScale = 0.5; - centerTabIconScale = 0.5; - dropZoneColor = QColor(155, 155, 155); - dropZoneBorderColor = Qt::black; - dropZoneBorderInPixels = 1; - absoluteDropZoneSizeInPixels = 25; - dockingTargetDelayMS = 110; - dropZoneHoverFadeUpdateIntervalMS = 20; - dropZoneHoverFadeIncrement = dropZoneOpacity / (dockingTargetDelayMS / dropZoneHoverFadeUpdateIntervalMS); - centerDropZoneIconPath = QString(":/stylesheet/img/UI20/docking/tabs_icon.svg"); - } FancyDockingDropZoneWidget::FancyDockingDropZoneWidget(QMainWindow* mainWindow, QWidget* coordinatesRelativeTo, QScreen* screen, FancyDockingDropZoneState* dropZoneState) // NOTE: this will not work with multiple monitors if this widget has a parent. The floating drop zone @@ -154,7 +134,7 @@ namespace AzQtComponents // Draw all of the normal drop zones if they exist (if a dock widget is hovered over) painter.setPen(Qt::NoPen); - painter.setOpacity(g_Constants.dropZoneOpacity); + painter.setOpacity(FancyDockingDropZoneConstants::dropZoneOpacity); auto dropZones = m_dropZoneState->dropZones(); for (auto it = dropZones.cbegin(); it != dropZones.cend(); ++it) { @@ -189,7 +169,7 @@ namespace AzQtComponents // Otherwise, set the normal color else { - painter.setBrush(g_Constants.dropZoneColor); + painter.setBrush(FancyDockingDropZoneConstants::dropZoneColor); } // negate the window position to offset everything by that much @@ -214,8 +194,8 @@ namespace AzQtComponents // Scale the tabs icon based on the drop zone size and our specified offset // Doing this through QIcon to make sure that SVG is rendered already in desired resolution const QSize& dropZoneSize = dropZoneRect.size(); - const QSize requestedIconSize = dropZoneSize * g_Constants.centerTabIconScale; - const QIcon dropZoneIcon = QIcon(g_Constants.centerDropZoneIconPath); + const QSize requestedIconSize = dropZoneSize * FancyDockingDropZoneConstants::centerTabIconScale; + const QIcon dropZoneIcon = QIcon(FancyDockingDropZoneConstants::centerDropZoneIconPath); const QPixmap dropZonePixmap = dropZoneIcon.pixmap(requestedIconSize); const QSize receivedIconSize = dropZoneIcon.actualSize(requestedIconSize); @@ -264,7 +244,7 @@ namespace AzQtComponents } else { - painter.setBrush(g_Constants.dropZoneColor); + painter.setBrush(FancyDockingDropZoneConstants::dropZoneColor); } painter.drawRect(absoluteDropZoneRect); @@ -313,8 +293,8 @@ namespace AzQtComponents const QPoint innerBottomRight = innerDropZoneRect.bottomRight(); // Draw the lines using the appropriate pen - QPen dropZoneBorderPen(g_Constants.dropZoneBorderColor); - dropZoneBorderPen.setWidth(g_Constants.dropZoneBorderInPixels); + QPen dropZoneBorderPen(FancyDockingDropZoneConstants::dropZoneBorderColor); + dropZoneBorderPen.setWidth(FancyDockingDropZoneConstants::dropZoneBorderInPixels); painter.setPen(dropZoneBorderPen); painter.setOpacity(1); painter.drawLine(topLeft, innerTopLeft); diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.h index 94a6792833..865adcea59 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.h +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDockingDropZoneWidget.h @@ -28,63 +28,58 @@ class QPainter; namespace AzQtComponents { - struct AZ_QT_COMPONENTS_API FancyDockingDropZoneConstants + namespace FancyDockingDropZoneConstants { // Constant for the opacity of the screen grab for the dock widget being dragged - qreal draggingDockWidgetOpacity; + static constexpr qreal draggingDockWidgetOpacity = 0.6; // Constant for the opacity of the normal drop zones - qreal dropZoneOpacity; + static constexpr qreal dropZoneOpacity = 0.4; // Constant for the default drop zone size (in pixels) - int dropZoneSizeInPixels; + static constexpr int dropZoneSizeInPixels = 40; // Constant for the dock width/height size (in pixels) before we need to start // scaling down the drop zone sizes, or else they will overlap with the center // tab icon or each other - int minDockSizeBeforeDropZoneScalingInPixels; + static constexpr int minDockSizeBeforeDropZoneScalingInPixels = dropZoneSizeInPixels * 3; // Constant for the factor by which we must scale down the drop zone sizes once // the dock width/height size is too small - qreal dropZoneScaleFactor; + static constexpr qreal dropZoneScaleFactor = 0.25; // Constant for the percentage to scale down the inner drop zone rectangle for the center tab drop zone - qreal centerTabDropZoneScale; + static constexpr qreal centerTabDropZoneScale = 0.5; // Constant for the percentage to scale down the center tab drop zone for the center tab icon - qreal centerTabIconScale; + static constexpr qreal centerTabIconScale = 0.5; // Constant for the drop zone hotspot default color - QColor dropZoneColor; + static const QColor dropZoneColor = QColor(155, 155, 155); // Constant for the drop zone border color - QColor dropZoneBorderColor; + static const QColor dropZoneBorderColor = Qt::black; // Constant for the border width in pixels separating the drop zones - int dropZoneBorderInPixels; + static constexpr int dropZoneBorderInPixels = 1; // Constant for the border width in pixels separating the drop zones - int absoluteDropZoneSizeInPixels; + static constexpr int absoluteDropZoneSizeInPixels = 25; // Constant for the delay (in milliseconds) before a drop zone becomes active // once it is hovered over - int dockingTargetDelayMS; + static constexpr int dockingTargetDelayMS = 110; // Constant for the rate at which we will update (fade in) the drop zone opacity // when hovered over (in milliseconds) - int dropZoneHoverFadeUpdateIntervalMS; + static constexpr int dropZoneHoverFadeUpdateIntervalMS = 20; // Constant for the incremental opacity increase for the hovered drop zone // that will fade in to the full drop zone opacity in the desired time - qreal dropZoneHoverFadeIncrement; + static constexpr qreal dropZoneHoverFadeIncrement = dropZoneOpacity / (dockingTargetDelayMS / dropZoneHoverFadeUpdateIntervalMS); // Constant for the path to the center drop zone tabs icon - QString centerDropZoneIconPath; - - FancyDockingDropZoneConstants(); - - FancyDockingDropZoneConstants(const FancyDockingDropZoneConstants&) = delete; - FancyDockingDropZoneConstants& operator=(const FancyDockingDropZoneConstants&) = delete; + static const QString centerDropZoneIconPath = QStringLiteral(":/stylesheet/img/UI20/docking/tabs_icon.svg"); }; class FancyDockingDropZoneState