From bc903f22cd020cfa60bf0730114996bf722b0b12 Mon Sep 17 00:00:00 2001 From: sweeneys Date: Tue, 30 Nov 2021 18:23:36 -0800 Subject: [PATCH 01/13] Remove remote console flag suppressing game logs in GameLauncher and ServerLauncher apps Signed-off-by: sweeneys --- .../launchers/platforms/linux/launcher.py | 6 +++--- .../launchers/platforms/win/launcher.py | 16 ---------------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py index 112629b349..e8931ba07f 100644 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py @@ -179,20 +179,20 @@ class LinuxLauncher(Launcher): class DedicatedLinuxLauncher(LinuxLauncher): - def setup(self, backupFiles=True, launch_ap=False): + def setup(self, backupFiles=True, launch_ap=False, configure_settings=True): """ Perform setup of this launcher, must be called before launching. Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files :param backupFiles: Bool to backup setup files - :param lauch_ap: Bool to lauch the asset processor + :param launch_ap: Bool to launch the asset processor :return: None """ # Base setup defaults to None if launch_ap is None: launch_ap = False - super(DedicatedLinuxLauncher, self).setup(backupFiles, launch_ap) + super(DedicatedLinuxLauncher, self).setup(backupFiles, launch_ap, configure_settings) def binary_path(self): """ diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index d18431ba82..ec2b3b966c 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -169,7 +169,6 @@ class WinLauncher(Launcher): host_ip = '127.0.0.1' self.args.append(f'--regset="/Amazon/AzCore/Bootstrap/project_path={self.workspace.paths.project()}"') self.args.append(f'--regset="/Amazon/AzCore/Bootstrap/remote_ip={host_ip}"') - self.args.append('--regset="/Amazon/AzCore/Bootstrap/wait_for_connect=1"') self.args.append(f'--regset="/Amazon/AzCore/Bootstrap/allowed_list={host_ip}"') self.workspace.settings.modify_platform_setting("log_RemoteConsoleAllowedAddresses", host_ip) @@ -177,21 +176,6 @@ class WinLauncher(Launcher): class DedicatedWinLauncher(WinLauncher): - def setup(self, backupFiles=True, launch_ap=False): - """ - Perform setup of this launcher, must be called before launching. - Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files - - :param backupFiles: Bool to backup setup files - :param lauch_ap: Bool to lauch the asset processor - :return: None - """ - # Base setup defaults to None - if launch_ap is None: - launch_ap = False - - super(DedicatedWinLauncher, self).setup(backupFiles, launch_ap) - def binary_path(self): """ Return full path to the dedicated server launcher for the build directory. From a5cb5b7f802ca93c093f448557b2f8767dd63b17 Mon Sep 17 00:00:00 2001 From: sweeneys Date: Tue, 30 Nov 2021 23:07:29 -0800 Subject: [PATCH 02/13] Make different launchers handle args the same way, fix missing docstrings Signed-off-by: sweeneys --- .../launchers/platforms/android/launcher.py | 20 ++++++++++++++++--- .../ly_test_tools/launchers/platforms/base.py | 2 ++ .../launchers/platforms/linux/launcher.py | 10 +++++++--- .../launchers/platforms/win/launcher.py | 7 ++++--- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py index 75eaa65e94..7c3efd9e9d 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py @@ -163,9 +163,23 @@ class AndroidLauncher(Launcher): return True - def setup(self): + def setup(self, backupFiles=True, launch_ap=True, configure_settings=True): + """ + Perform setup of this launcher, must be called before launching. + Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files + + :param backupFiles: Bool to backup setup files + :param launch_ap: Bool to launch the asset processor + :param configure_settings: Bool to update settings caches + :return: None + """ # Backup - self.backup_settings() + if backupFiles: + self.backup_settings() + + # Base setup defaults to None + if launch_ap is None: + launch_ap = True # Enable Android capabilities and verify environment is setup before continuing. self._is_valid_android_environment() @@ -174,7 +188,7 @@ class AndroidLauncher(Launcher): # Modify and re-configure self.configure_settings() self.workspace.shader_compiler.start() - super(AndroidLauncher, self).setup() + super(AndroidLauncher, self).setup(backupFiles, launch_ap, configure_settings) def teardown(self): ly_test_tools.mobile.android.undo_tcp_port_changes(self._device_id) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py index c9458899b4..e1b5dab1b6 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py @@ -75,6 +75,8 @@ class Launcher(object): ~/ly_test_tools/devices.ini (a.k.a. %USERPROFILE%/ly_test_tools/devices.ini) :param backupFiles: Bool to backup setup files + :param launch_ap: Bool to launch the asset processor + :param configure_settings: Bool to update settings caches :return: None """ # Remove existing logs and dmp files before launching for self.save_project_log_files() diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py index e8931ba07f..96e827069e 100644 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py @@ -162,7 +162,7 @@ class LinuxLauncher(Launcher): def configure_settings(self): """ - Configures system level settings and syncs the launcher to the targeted console IP. + Configures system level settings :return: None """ @@ -170,7 +170,6 @@ class LinuxLauncher(Launcher): host_ip = '127.0.0.1' self.args.append(f'--regset="/Amazon/AzCore/Bootstrap/project_path={self.workspace.paths.project()}"') self.args.append(f'--regset="/Amazon/AzCore/Bootstrap/remote_ip={host_ip}"') - self.args.append('--regset="/Amazon/AzCore/Bootstrap/wait_for_connect=1"') self.args.append(f'--regset="/Amazon/AzCore/Bootstrap/allowed_list={host_ip}"') self.workspace.settings.modify_platform_setting("r_ShaderCompilerServer", host_ip) @@ -186,11 +185,16 @@ class DedicatedLinuxLauncher(LinuxLauncher): :param backupFiles: Bool to backup setup files :param launch_ap: Bool to launch the asset processor + :param configure_settings: Bool to update settings caches :return: None """ + # Backup + if backupFiles: + self.backup_settings() + # Base setup defaults to None if launch_ap is None: - launch_ap = False + launch_ap = True super(DedicatedLinuxLauncher, self).setup(backupFiles, launch_ap, configure_settings) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index ec2b3b966c..f989f7bd19 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -44,7 +44,8 @@ class WinLauncher(Launcher): Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files :param backupFiles: Bool to backup setup files - :param lauch_ap: Bool to lauch the asset processor + :param launch_ap: Bool to lauch the asset processor + :param configure_settings: Bool to update settings caches :return: None """ # Backup @@ -58,7 +59,7 @@ class WinLauncher(Launcher): # Modify and re-configure if configure_settings: self.configure_settings() - super(WinLauncher, self).setup(backupFiles, launch_ap) + super(WinLauncher, self).setup(backupFiles, launch_ap, configure_settings) def launch(self): """ @@ -161,7 +162,7 @@ class WinLauncher(Launcher): def configure_settings(self): """ - Configures system level settings and syncs the launcher to the targeted console IP. + Configures system level settings :return: None """ From fd45a37c7b2504522f5faa63f70d0e6dbf36fa3f Mon Sep 17 00:00:00 2001 From: sweeneys Date: Wed, 1 Dec 2021 14:13:13 -0800 Subject: [PATCH 03/13] Restore defaults, clarify comment Signed-off-by: sweeneys --- .../launchers/platforms/android/launcher.py | 2 +- .../launchers/platforms/linux/launcher.py | 6 ++--- .../launchers/platforms/win/launcher.py | 22 ++++++++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py index 7c3efd9e9d..9433f426b5 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/android/launcher.py @@ -177,7 +177,7 @@ class AndroidLauncher(Launcher): if backupFiles: self.backup_settings() - # Base setup defaults to None + # None reverts to function default if launch_ap is None: launch_ap = True diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py index 96e827069e..377121f2e0 100644 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/linux/launcher.py @@ -52,7 +52,7 @@ class LinuxLauncher(Launcher): if backupFiles: self.backup_settings() - # Base setup defaults to None + # None reverts to function default if launch_ap is None: launch_ap = True @@ -192,9 +192,9 @@ class DedicatedLinuxLauncher(LinuxLauncher): if backupFiles: self.backup_settings() - # Base setup defaults to None + # None reverts to function default if launch_ap is None: - launch_ap = True + launch_ap = False super(DedicatedLinuxLauncher, self).setup(backupFiles, launch_ap, configure_settings) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index f989f7bd19..c29aa7b10b 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -52,7 +52,7 @@ class WinLauncher(Launcher): if backupFiles: self.backup_settings() - # Base setup defaults to None + # None reverts to function default if launch_ap is None: launch_ap = True @@ -177,6 +177,26 @@ class WinLauncher(Launcher): class DedicatedWinLauncher(WinLauncher): + def setup(self, backupFiles=True, launch_ap=False, configure_settings=True): + """ + Perform setup of this launcher, must be called before launching. + Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files + + :param backupFiles: Bool to backup setup files + :param launch_ap: Bool to launch the asset processor + :param configure_settings: Bool to update settings caches + :return: None + """ + # Backup + if backupFiles: + self.backup_settings() + + # None reverts to function default + if launch_ap is None: + launch_ap = False + + super(DedicatedWinLauncher, self).setup(backupFiles, launch_ap, configure_settings) + def binary_path(self): """ Return full path to the dedicated server launcher for the build directory. From 6f074f2f9ffa54603d6f829fabe793473d01e336 Mon Sep 17 00:00:00 2001 From: antonmic <56370189+antonmic@users.noreply.github.com> Date: Thu, 2 Dec 2021 11:03:53 -0800 Subject: [PATCH 04/13] Fixing build fail when Renderdoc is enabled Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com> --- Gems/Atom/RHI/Code/Source/RHI/Factory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp b/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp index 9146175252..2d714ed551 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp @@ -15,6 +15,7 @@ #if defined(USE_RENDERDOC) || defined(USE_PIX) #include #include +static bool s_pixGpuMarkersEnabled = false; #endif #if defined(USE_RENDERDOC) @@ -26,7 +27,6 @@ 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; @@ -208,7 +208,7 @@ namespace AZ bool Factory::PixGpuEventsEnabled() { -#if defined(USE_PIX) +#if defined(USE_PIX) || defined(USE_RENDERDOC) return s_pixGpuMarkersEnabled; #else return false; From 51794f9c5286820d3c78383d484fb70d96c299f8 Mon Sep 17 00:00:00 2001 From: antonmic <56370189+antonmic@users.noreply.github.com> Date: Thu, 2 Dec 2021 11:24:11 -0800 Subject: [PATCH 05/13] Changing fix after offline discussion Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com> --- Gems/Atom/RHI/Code/Source/RHI/Factory.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp b/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp index 2d714ed551..ce0f4ce44b 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/Factory.cpp @@ -15,7 +15,6 @@ #if defined(USE_RENDERDOC) || defined(USE_PIX) #include #include -static bool s_pixGpuMarkersEnabled = false; #endif #if defined(USE_RENDERDOC) @@ -27,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; @@ -63,8 +63,9 @@ 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"); +#if defined(USE_PIX) s_pixGpuMarkersEnabled = s_pixGpuMarkersEnabled || enableRenderDoc; - +#endif if (enableRenderDoc && AZ_TRAIT_RENDERDOC_MODULE && !s_renderDocModule) { s_renderDocModule = DynamicModuleHandle::Create(AZ_TRAIT_RENDERDOC_MODULE); @@ -208,7 +209,7 @@ namespace AZ bool Factory::PixGpuEventsEnabled() { -#if defined(USE_PIX) || defined(USE_RENDERDOC) +#if defined(USE_PIX) return s_pixGpuMarkersEnabled; #else return false; From 393c36905558e7ebf797e95b90be456d20ec16e3 Mon Sep 17 00:00:00 2001 From: antonmic <56370189+antonmic@users.noreply.github.com> Date: Thu, 2 Dec 2021 23:33:56 -0800 Subject: [PATCH 06/13] Fixed pass warning in ASV Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com> --- .../RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h | 8 +++++++- Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h index 9dd1bf6842..a5980000fd 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h @@ -43,6 +43,9 @@ namespace AZ // Rendering -> Idle // -> Queued (Rendering will transition to Queued if a pass was queued with the PassSystem during Rendering) // + // Any State -> Orphaned (transition to Orphaned state can be outside the jurisdiction of the pass and so can happen from any state) + // Orphaned -> Queued (Orphaned state transitions back to idle. + // enum class PassState : u8 { // Default value, you should only ever see this in the Pass constructor @@ -92,7 +95,10 @@ namespace AZ // | // V // Pass is currently rendering. Pass must be in Idle state before entering this state - Rendering + Rendering, + + // Special state: Orphaned State, pass was removed from it's parent and is awaiting deletion + Orphaned }; // This enum keeps track of what actions the pass is queued for with the pass system diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp index d04a35a10b..4a135ab6d6 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp @@ -147,6 +147,11 @@ namespace AZ m_treeDepth = m_parent->m_treeDepth + 1; m_path = ConcatPassName(m_parent->m_path, m_name); m_flags.m_partOfHierarchy = m_parent->m_flags.m_partOfHierarchy; + + if (m_state == PassState::Orphaned) + { + QueueForBuildAndInitialization(); + } } void Pass::RemoveFromParent() @@ -154,7 +159,7 @@ namespace AZ AZ_RPI_PASS_ASSERT(m_parent != nullptr, "Trying to remove pass from parent but pointer to the parent pass is null."); m_parent->RemoveChild(Ptr(this)); m_queueState = PassQueueState::NoQueue; - m_state = PassState::Idle; + m_state = PassState::Orphaned; } void Pass::OnOrphan() @@ -162,6 +167,8 @@ namespace AZ m_parent = nullptr; m_flags.m_partOfHierarchy = false; m_treeDepth = 0; + m_queueState = PassQueueState::NoQueue; + m_state = PassState::Orphaned; } // --- Getters & Setters --- From e24d8d3f833b3bdaa499507e62b59576204cbcf1 Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Fri, 3 Dec 2021 08:55:13 -0800 Subject: [PATCH 07/13] Resaved LY_SC_UnitTest_NodeableDelay.scriptcanvas to update to json format Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../LY_SC_UnitTest_NodeableDelay.scriptcanvas | 5609 +++++++---------- 1 file changed, 2173 insertions(+), 3436 deletions(-) diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_NodeableDelay.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_NodeableDelay.scriptcanvas index a5d22135c7..b9ccf8d42b 100644 --- a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_NodeableDelay.scriptcanvas +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_NodeableDelay.scriptcanvas @@ -1,3436 +1,2173 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "ScriptCanvasData", + "ClassData": { + "m_scriptCanvas": { + "Id": { + "id": 7992795709152 + }, + "Name": "LY_SC_UnitTest_NodeableDelay", + "Components": { + "Component_[13769957497174641973]": { + "$type": "EditorGraphVariableManagerComponent", + "Id": 13769957497174641973, + "m_variableData": { + "m_nameVariableMap": [ + { + "Key": { + "m_id": "{13A4B0B3-756F-403C-A9E0-CC40DA27EE2C}" + }, + "Value": { + "Datum": { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 2.0, + "label": "Number" + }, + "VariableId": { + "m_id": "{13A4B0B3-756F-403C-A9E0-CC40DA27EE2C}" + }, + "VariableName": "Two" + } + }, + { + "Key": { + "m_id": "{A3A19E5B-D7BE-46D4-B876-9832C1D26D0B}" + }, + "Value": { + "Datum": { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 1.0, + "label": "Number" + }, + "VariableId": { + "m_id": "{A3A19E5B-D7BE-46D4-B876-9832C1D26D0B}" + }, + "VariableName": "One" + } + }, + { + "Key": { + "m_id": "{AD81163D-DA91-4E66-AE45-ADEDC64CAAF0}" + }, + "Value": { + "Datum": { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": true, + "label": "Boolean" + }, + "VariableId": { + "m_id": "{AD81163D-DA91-4E66-AE45-ADEDC64CAAF0}" + }, + "VariableName": "Switch" + } + } + ] + }, + "CopiedVariableRemapping": [ + { + "Key": { + "m_id": "{53E25781-037F-4D34-905C-0151A205EC74}" + }, + "Value": { + "m_id": "{AD81163D-DA91-4E66-AE45-ADEDC64CAAF0}" + } + }, + { + "Key": { + "m_id": "{6ACE5B7C-104E-4B49-8386-8718283621A5}" + }, + "Value": { + "m_id": "{A3A19E5B-D7BE-46D4-B876-9832C1D26D0B}" + } + }, + { + "Key": { + "m_id": "{DA754EF7-9F41-46E5-A603-751C5AECABC1}" + }, + "Value": { + "m_id": "{13A4B0B3-756F-403C-A9E0-CC40DA27EE2C}" + } + } + ] + }, + "Component_[6702463496795695700]": { + "$type": "{4D755CA9-AB92-462C-B24F-0B3376F19967} Graph", + "Id": 6702463496795695700, + "m_graphData": { + "m_nodes": [ + { + "Id": { + "id": 8022860480224 + }, + "Name": "SC Node(GetVariable)", + "Components": { + "Component_[10003864966711545946]": { + "$type": "GetVariableNode", + "Id": 10003864966711545946, + "Slots": [ + { + "id": { + "m_id": "{8650478F-4E17-40B5-B13C-E8C02A524201}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "When signaled sends the property referenced by this node to a Data Output slot", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{273B6C2E-CBE7-479A-B6C6-4CC6E51636B6}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled after the referenced property has been pushed to the Data Output slot", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{12714A1C-FDCF-4A0C-8127-1B6B17A804CC}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Number", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "m_variableId": { + "m_id": "{A3A19E5B-D7BE-46D4-B876-9832C1D26D0B}" + }, + "m_variableDataOutSlotId": { + "m_id": "{12714A1C-FDCF-4A0C-8127-1B6B17A804CC}" + } + } + } + }, + { + "Id": { + "id": 8005680611040 + }, + "Name": "SC-Node(Mark Complete)", + "Components": { + "Component_[1561479662366255748]": { + "$type": "{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF} Method", + "Id": 1561479662366255748, + "Slots": [ + { + "isVisibile": false, + "id": { + "m_id": "{C1E634E4-B55F-46D0-95EB-B3947D5E99ED}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "EntityID: 0", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{A585F499-C8AE-4B8A-9EB2-46C95DA2BFC8}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Report", + "toolTip": "additional notes for the test report", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{1A41311D-2629-4A55-8469-AB6EA8F8E00F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{B0C71D36-F38C-48FC-80B7-58641E38A45F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 1 + }, + "isNullPointer": false, + "$type": "EntityId", + "value": { + "id": 4276206253 + } + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 5 + }, + "isNullPointer": false, + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "value": "Delay test complete", + "label": "Report" + } + ], + "methodType": 2, + "methodName": "Mark Complete", + "className": "Unit Testing", + "resultSlotIDs": [ + {} + ], + "prettyClassName": "Unit Testing" + } + } + }, + { + "Id": { + "id": 8018565512928 + }, + "Name": "SC-Node(DelayNodeableNode)", + "Components": { + "Component_[18208529655338450188]": { + "$type": "DelayNodeableNode", + "Id": 18208529655338450188, + "Slots": [ + { + "id": { + "m_id": "{F8445BAB-538D-411E-B386-51DA322E636F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "DisallowReentrantExecutionContract" + } + ], + "slotName": "Start", + "toolTip": "When signaled, execution is delayed at this node according to the specified properties.", + "DisplayGroup": { + "Value": 2675529103 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{FCE9085E-1FBB-4C65-BF21-A4886EE2B83B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Start: Time", + "toolTip": "Amount of time to delay, in seconds.", + "DisplayGroup": { + "Value": 2675529103 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{AB0955E5-BC42-4C62-BB8D-C14ECE24AA28}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Start: Loop", + "toolTip": "If true, the delay will restart after triggering the Out slot.", + "DisplayGroup": { + "Value": 2675529103 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{00BF555A-CCC7-45F0-BDA1-7FCA587F5DF6}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Start: Hold", + "toolTip": "Amount of time to wait before restarting, in seconds.", + "DisplayGroup": { + "Value": 2675529103 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{6C92F041-AD12-4EDB-BD7D-2A1B126A0AE1}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "On Start", + "toolTip": "When signaled, execution is delayed at this node according to the specified properties.", + "DisplayGroup": { + "Value": 2675529103 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{C84ED69D-1250-441D-99EC-1FA09EBD4A33}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "DisallowReentrantExecutionContract" + } + ], + "slotName": "Reset", + "toolTip": "When signaled, execution is delayed at this node according to the specified properties.", + "DisplayGroup": { + "Value": 1352515405 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{24A2AD52-B382-4875-B3F7-45072F3D95DC}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Reset: Time", + "toolTip": "Amount of time to delay, in seconds.", + "DisplayGroup": { + "Value": 1352515405 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{6CCC46D4-1ACA-4ED3-8F41-CE21DBB074BE}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Reset: Loop", + "toolTip": "If true, the delay will restart after triggering the Out slot.", + "DisplayGroup": { + "Value": 1352515405 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{3BA65C96-1800-44A7-9132-E8618EC309CE}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Reset: Hold", + "toolTip": "Amount of time to wait before restarting, in seconds.", + "DisplayGroup": { + "Value": 1352515405 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{7B52E7FE-906E-4E96-9025-DFD220C9A532}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "On Reset", + "toolTip": "When signaled, execution is delayed at this node according to the specified properties.", + "DisplayGroup": { + "Value": 1352515405 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7311AE3A-E23F-476D-BCC5-2D6A7B39AD53}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "DisallowReentrantExecutionContract" + } + ], + "slotName": "Cancel", + "toolTip": "Cancels the current delay.", + "DisplayGroup": { + "Value": 1444332914 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{017884F2-6FB0-4E88-BBE8-FE9277108BD3}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "On Cancel", + "toolTip": "Cancels the current delay.", + "DisplayGroup": { + "Value": 1444332914 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{6249B81E-1341-41B1-B843-F4658C1EAE31}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Done", + "toolTip": "Signaled when the delay reaches zero.", + "DisplayGroup": { + "Value": 271442091 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + }, + "IsLatent": true + }, + { + "id": { + "m_id": "{1A0F9D41-14F3-4CF0-8C00-7E2374129768}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Elapsed", + "toolTip": "The amount of time that has elapsed since the delay began.", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 271442091 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Start: Time" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Start: Loop" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Start: Hold" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Reset: Time" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Reset: Loop" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Reset: Hold" + } + ], + "slotExecutionMap": { + "ins": [ + { + "_slotId": { + "m_id": "{F8445BAB-538D-411E-B386-51DA322E636F}" + }, + "_inputs": [ + { + "_slotId": { + "m_id": "{FCE9085E-1FBB-4C65-BF21-A4886EE2B83B}" + } + }, + { + "_slotId": { + "m_id": "{AB0955E5-BC42-4C62-BB8D-C14ECE24AA28}" + } + }, + { + "_slotId": { + "m_id": "{00BF555A-CCC7-45F0-BDA1-7FCA587F5DF6}" + } + } + ], + "_outs": [ + { + "_slotId": { + "m_id": "{6C92F041-AD12-4EDB-BD7D-2A1B126A0AE1}" + }, + "_name": "On Start", + "_interfaceSourceId": "{33362E36-3930-0000-0000-D138AF020000}" + } + ], + "_interfaceSourceId": "{B86FAF85-CA00-0000-296D-0737FD7F0000}" + }, + { + "_slotId": { + "m_id": "{C84ED69D-1250-441D-99EC-1FA09EBD4A33}" + }, + "_inputs": [ + { + "_slotId": { + "m_id": "{24A2AD52-B382-4875-B3F7-45072F3D95DC}" + } + }, + { + "_slotId": { + "m_id": "{6CCC46D4-1ACA-4ED3-8F41-CE21DBB074BE}" + } + }, + { + "_slotId": { + "m_id": "{3BA65C96-1800-44A7-9132-E8618EC309CE}" + } + } + ], + "_outs": [ + { + "_slotId": { + "m_id": "{7B52E7FE-906E-4E96-9025-DFD220C9A532}" + }, + "_name": "On Reset", + "_interfaceSourceId": "{33362E36-3930-0000-0000-D138AF020000}" + } + ], + "_interfaceSourceId": "{B86FAF85-CA00-0000-296D-0737FD7F0000}" + }, + { + "_slotId": { + "m_id": "{7311AE3A-E23F-476D-BCC5-2D6A7B39AD53}" + }, + "_outs": [ + { + "_slotId": { + "m_id": "{017884F2-6FB0-4E88-BBE8-FE9277108BD3}" + }, + "_name": "On Cancel", + "_interfaceSourceId": "{33362E36-3930-0000-0000-D138AF020000}" + } + ], + "_interfaceSourceId": "{B86FAF85-CA00-0000-296D-0737FD7F0000}" + } + ], + "latents": [ + { + "_slotId": { + "m_id": "{6249B81E-1341-41B1-B843-F4658C1EAE31}" + }, + "_name": "Done", + "_outputs": [ + { + "_slotId": { + "m_id": "{1A0F9D41-14F3-4CF0-8C00-7E2374129768}" + } + } + ], + "_interfaceSourceId": "{B86FAF85-CA00-0000-296D-0737FD7F0000}" + } + ] + } + } + } + }, + { + "Id": { + "id": 8031450414816 + }, + "Name": "SC-Node(Expect Greater Than Equal)", + "Components": { + "Component_[408430974986181037]": { + "$type": "MethodOverloaded", + "Id": 408430974986181037, + "Slots": [ + { + "isVisibile": false, + "id": { + "m_id": "{2EABD0D3-B2DE-4AED-9069-ACC8A92B54DE}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "EntityID: 0", + "DisplayDataType": { + "m_type": 1 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "IsOverload": true, + "id": { + "m_id": "{B9873274-15A8-4642-BCB8-423D302618FD}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Candidate", + "toolTip": "left of >=", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "IsOverload": true, + "id": { + "m_id": "{DCB3BEE9-00E3-4421-BC84-5B1380607AA5}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Reference", + "toolTip": "right of >=", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{A3A19E5B-D7BE-46D4-B876-9832C1D26D0B}" + } + }, + { + "id": { + "m_id": "{01E90D0B-05A6-4C3F-9E86-FEC7139E4322}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Report", + "toolTip": "additional notes for the test report", + "DisplayDataType": { + "m_type": 5 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{5BB85516-23AA-4860-8D8E-4E25F83AAF27}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{21EA60AA-6B22-4623-997C-22363E687A4B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 1 + }, + "isNullPointer": false, + "$type": "EntityId", + "value": { + "id": 4276206253 + }, + "label": "EntityID: 0" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Candidate" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Reference" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 5 + }, + "isNullPointer": false, + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "value": "Elapsed should be more than 1 after start", + "label": "Report" + } + ], + "methodType": 2, + "methodName": "Expect Greater Than Equal", + "className": "Unit Testing", + "resultSlotIDs": [ + {} + ], + "prettyClassName": "Unit Testing", + "orderedInputSlotIds": [ + { + "m_id": "{2EABD0D3-B2DE-4AED-9069-ACC8A92B54DE}" + }, + { + "m_id": "{B9873274-15A8-4642-BCB8-423D302618FD}" + }, + { + "m_id": "{DCB3BEE9-00E3-4421-BC84-5B1380607AA5}" + }, + { + "m_id": "{01E90D0B-05A6-4C3F-9E86-FEC7139E4322}" + } + ] + } + } + }, + { + "Id": { + "id": 8009975578336 + }, + "Name": "SC-Node(Gate)", + "Components": { + "Component_[5398707513550245442]": { + "$type": "Gate", + "Id": 5398707513550245442, + "Slots": [ + { + "id": { + "m_id": "{BF03B031-321A-4DD1-A00A-ECFF9E03518F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Input signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{B1583C42-4290-4016-B123-A8F3CBFDE3D1}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "True", + "toolTip": "Signaled if the condition provided evaluates to true.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{BD9FC7E9-30C7-4155-AB5A-A09819A44FD5}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "False", + "toolTip": "Signaled if the condition provided evaluates to false.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{4B14B289-18EA-4BFA-B35C-D307A6F64B37}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Condition", + "toolTip": "If true the node will signal the Output and proceed execution", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{AD81163D-DA91-4E66-AE45-ADEDC64CAAF0}" + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Condition" + } + ] + } + } + }, + { + "Id": { + "id": 8001385643744 + }, + "Name": "SC-Node(Expect Greater Than Equal)", + "Components": { + "Component_[7351797194887752307]": { + "$type": "MethodOverloaded", + "Id": 7351797194887752307, + "Slots": [ + { + "isVisibile": false, + "id": { + "m_id": "{34C9C07C-C858-4F59-A249-AAC3C29B587E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "EntityID: 0", + "DisplayDataType": { + "m_type": 1 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "IsOverload": true, + "id": { + "m_id": "{38A5CD98-69C7-4DA5-BF7D-C562F7458B07}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Candidate", + "toolTip": "left of >=", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "IsOverload": true, + "id": { + "m_id": "{3B50E608-A44A-4DBC-A34C-C2ECA322DAD6}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Reference", + "toolTip": "right of >=", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{13A4B0B3-756F-403C-A9E0-CC40DA27EE2C}" + } + }, + { + "id": { + "m_id": "{628B2C9B-841D-4E63-ABBB-2AA8601B5C7A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Report", + "toolTip": "additional notes for the test report", + "DisplayDataType": { + "m_type": 5 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{95EA03BD-BE8E-4DC1-8291-D8127AD75A37}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{9617463C-E5F5-4292-99C3-C7C92891246F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 1 + }, + "isNullPointer": false, + "$type": "EntityId", + "value": { + "id": 4276206253 + }, + "label": "EntityID: 0" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Candidate" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Reference" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 5 + }, + "isNullPointer": false, + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "value": "Elapsed should be more than 2 after reset", + "label": "Report" + } + ], + "methodType": 2, + "methodName": "Expect Greater Than Equal", + "className": "Unit Testing", + "resultSlotIDs": [ + {} + ], + "prettyClassName": "Unit Testing", + "orderedInputSlotIds": [ + { + "m_id": "{34C9C07C-C858-4F59-A249-AAC3C29B587E}" + }, + { + "m_id": "{38A5CD98-69C7-4DA5-BF7D-C562F7458B07}" + }, + { + "m_id": "{3B50E608-A44A-4DBC-A34C-C2ECA322DAD6}" + }, + { + "m_id": "{628B2C9B-841D-4E63-ABBB-2AA8601B5C7A}" + } + ] + } + } + }, + { + "Id": { + "id": 7997090676448 + }, + "Name": "SC Node(SetVariable)", + "Components": { + "Component_[8054056332975461684]": { + "$type": "SetVariableNode", + "Id": 8054056332975461684, + "Slots": [ + { + "id": { + "m_id": "{D29241A9-9B27-42C0-9A30-A75AA4AA3F0F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "When signaled sends the variable referenced by this node to a Data Output slot", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{49682E58-579D-474A-A3E0-52E7DDDA4A7C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled after the referenced variable has been pushed to the Data Output slot", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{CCE01CC2-4E14-4F15-AC5A-219A4509CE94}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Boolean", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{CC6D2BF3-87BC-4B14-A27B-82D5C0E3DF2D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Boolean", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Boolean" + } + ], + "m_variableId": { + "m_id": "{AD81163D-DA91-4E66-AE45-ADEDC64CAAF0}" + }, + "m_variableDataInSlotId": { + "m_id": "{CCE01CC2-4E14-4F15-AC5A-219A4509CE94}" + }, + "m_variableDataOutSlotId": { + "m_id": "{CC6D2BF3-87BC-4B14-A27B-82D5C0E3DF2D}" + } + } + } + }, + { + "Id": { + "id": 8027155447520 + }, + "Name": "SC Node(GetVariable)", + "Components": { + "Component_[8637439810651459247]": { + "$type": "GetVariableNode", + "Id": 8637439810651459247, + "Slots": [ + { + "id": { + "m_id": "{C8560B11-DD0D-4A18-98A1-228FB7911DD1}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "When signaled sends the property referenced by this node to a Data Output slot", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{AB6805D8-5CAA-446B-8C36-CB8A2C30347D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled after the referenced property has been pushed to the Data Output slot", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{D9BC724B-4BDF-4F62-AF73-238559A85E94}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Number", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "m_variableId": { + "m_id": "{13A4B0B3-756F-403C-A9E0-CC40DA27EE2C}" + }, + "m_variableDataOutSlotId": { + "m_id": "{D9BC724B-4BDF-4F62-AF73-238559A85E94}" + } + } + } + }, + { + "Id": { + "id": 8014270545632 + }, + "Name": "SC-Node(Start)", + "Components": { + "Component_[9134219784961524494]": { + "$type": "Start", + "Id": 9134219784961524494, + "Slots": [ + { + "id": { + "m_id": "{11EB8AA6-BB4E-480D-93DA-85D5969F4ECB}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled when the entity that owns this graph is fully activated.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + } + ], + "m_connections": [ + { + "Id": { + "id": 8035745382112 + }, + "Name": "srcEndpoint=(If: True), destEndpoint=(Expect Greater Than Equal: In)", + "Components": { + "Component_[5647411303754655744]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 5647411303754655744, + "sourceEndpoint": { + "nodeId": { + "id": 8009975578336 + }, + "slotId": { + "m_id": "{B1583C42-4290-4016-B123-A8F3CBFDE3D1}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8031450414816 + }, + "slotId": { + "m_id": "{5BB85516-23AA-4860-8D8E-4E25F83AAF27}" + } + } + } + } + }, + { + "Id": { + "id": 8040040349408 + }, + "Name": "srcEndpoint=(Expect Greater Than Equal: Out), destEndpoint=(Set Variable: In)", + "Components": { + "Component_[15155445988139558066]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 15155445988139558066, + "sourceEndpoint": { + "nodeId": { + "id": 8031450414816 + }, + "slotId": { + "m_id": "{21EA60AA-6B22-4623-997C-22363E687A4B}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 7997090676448 + }, + "slotId": { + "m_id": "{D29241A9-9B27-42C0-9A30-A75AA4AA3F0F}" + } + } + } + } + }, + { + "Id": { + "id": 8044335316704 + }, + "Name": "srcEndpoint=(On Graph Start: Out), destEndpoint=(Get Variable: In)", + "Components": { + "Component_[2459001120525165713]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 2459001120525165713, + "sourceEndpoint": { + "nodeId": { + "id": 8014270545632 + }, + "slotId": { + "m_id": "{11EB8AA6-BB4E-480D-93DA-85D5969F4ECB}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8022860480224 + }, + "slotId": { + "m_id": "{8650478F-4E17-40B5-B13C-E8C02A524201}" + } + } + } + } + }, + { + "Id": { + "id": 8048630284000 + }, + "Name": "srcEndpoint=(If: False), destEndpoint=(Expect Greater Than Equal: In)", + "Components": { + "Component_[10745739214458161764]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 10745739214458161764, + "sourceEndpoint": { + "nodeId": { + "id": 8009975578336 + }, + "slotId": { + "m_id": "{BD9FC7E9-30C7-4155-AB5A-A09819A44FD5}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8001385643744 + }, + "slotId": { + "m_id": "{95EA03BD-BE8E-4DC1-8291-D8127AD75A37}" + } + } + } + } + }, + { + "Id": { + "id": 8052925251296 + }, + "Name": "srcEndpoint=(Set Variable: Out), destEndpoint=(Get Variable: In)", + "Components": { + "Component_[7371956956721983493]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 7371956956721983493, + "sourceEndpoint": { + "nodeId": { + "id": 7997090676448 + }, + "slotId": { + "m_id": "{49682E58-579D-474A-A3E0-52E7DDDA4A7C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8027155447520 + }, + "slotId": { + "m_id": "{C8560B11-DD0D-4A18-98A1-228FB7911DD1}" + } + } + } + } + }, + { + "Id": { + "id": 8057220218592 + }, + "Name": "srcEndpoint=(Expect Greater Than Equal: Out), destEndpoint=(Mark Complete: In)", + "Components": { + "Component_[14854123337262345427]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 14854123337262345427, + "sourceEndpoint": { + "nodeId": { + "id": 8001385643744 + }, + "slotId": { + "m_id": "{9617463C-E5F5-4292-99C3-C7C92891246F}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8005680611040 + }, + "slotId": { + "m_id": "{1A41311D-2629-4A55-8469-AB6EA8F8E00F}" + } + } + } + } + }, + { + "Id": { + "id": 8061515185888 + }, + "Name": "srcEndpoint=(Get Variable: Out), destEndpoint=(Delay: Start)", + "Components": { + "Component_[18301940095446866928]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 18301940095446866928, + "sourceEndpoint": { + "nodeId": { + "id": 8022860480224 + }, + "slotId": { + "m_id": "{273B6C2E-CBE7-479A-B6C6-4CC6E51636B6}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8018565512928 + }, + "slotId": { + "m_id": "{F8445BAB-538D-411E-B386-51DA322E636F}" + } + } + } + } + }, + { + "Id": { + "id": 8065810153184 + }, + "Name": "srcEndpoint=(Get Variable: Out), destEndpoint=(Delay: Reset)", + "Components": { + "Component_[14359507626343113257]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 14359507626343113257, + "sourceEndpoint": { + "nodeId": { + "id": 8027155447520 + }, + "slotId": { + "m_id": "{AB6805D8-5CAA-446B-8C36-CB8A2C30347D}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8018565512928 + }, + "slotId": { + "m_id": "{C84ED69D-1250-441D-99EC-1FA09EBD4A33}" + } + } + } + } + }, + { + "Id": { + "id": 8070105120480 + }, + "Name": "srcEndpoint=(Get Variable: Number), destEndpoint=(Delay: Start: Time)", + "Components": { + "Component_[6761547457125237874]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 6761547457125237874, + "sourceEndpoint": { + "nodeId": { + "id": 8022860480224 + }, + "slotId": { + "m_id": "{12714A1C-FDCF-4A0C-8127-1B6B17A804CC}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8018565512928 + }, + "slotId": { + "m_id": "{FCE9085E-1FBB-4C65-BF21-A4886EE2B83B}" + } + } + } + } + }, + { + "Id": { + "id": 8074400087776 + }, + "Name": "srcEndpoint=(Get Variable: Number), destEndpoint=(Delay: Reset: Time)", + "Components": { + "Component_[8979388687790412978]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 8979388687790412978, + "sourceEndpoint": { + "nodeId": { + "id": 8027155447520 + }, + "slotId": { + "m_id": "{D9BC724B-4BDF-4F62-AF73-238559A85E94}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8018565512928 + }, + "slotId": { + "m_id": "{24A2AD52-B382-4875-B3F7-45072F3D95DC}" + } + } + } + } + }, + { + "Id": { + "id": 8078695055072 + }, + "Name": "srcEndpoint=(Delay: Done), destEndpoint=(If: In)", + "Components": { + "Component_[14625041809622283132]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 14625041809622283132, + "sourceEndpoint": { + "nodeId": { + "id": 8018565512928 + }, + "slotId": { + "m_id": "{6249B81E-1341-41B1-B843-F4658C1EAE31}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8009975578336 + }, + "slotId": { + "m_id": "{BF03B031-321A-4DD1-A00A-ECFF9E03518F}" + } + } + } + } + }, + { + "Id": { + "id": 8082990022368 + }, + "Name": "srcEndpoint=(Delay: Elapsed), destEndpoint=(Expect Greater Than Equal: Candidate)", + "Components": { + "Component_[12771954348451341510]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 12771954348451341510, + "sourceEndpoint": { + "nodeId": { + "id": 8018565512928 + }, + "slotId": { + "m_id": "{1A0F9D41-14F3-4CF0-8C00-7E2374129768}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8001385643744 + }, + "slotId": { + "m_id": "{38A5CD98-69C7-4DA5-BF7D-C562F7458B07}" + } + } + } + } + }, + { + "Id": { + "id": 8087284989664 + }, + "Name": "srcEndpoint=(Delay: Elapsed), destEndpoint=(Expect Greater Than Equal: Candidate)", + "Components": { + "Component_[1854855865676689941]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 1854855865676689941, + "sourceEndpoint": { + "nodeId": { + "id": 8018565512928 + }, + "slotId": { + "m_id": "{1A0F9D41-14F3-4CF0-8C00-7E2374129768}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 8031450414816 + }, + "slotId": { + "m_id": "{B9873274-15A8-4642-BCB8-423D302618FD}" + } + } + } + } + } + ] + }, + "m_assetType": "{3E2AC8CD-713F-453E-967F-29517F331784}", + "versionData": { + "_grammarVersion": 1, + "_runtimeVersion": 1, + "_fileVersion": 1 + }, + "GraphCanvasData": [ + { + "Key": { + "id": 7992795709152 + }, + "Value": { + "ComponentData": { + "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { + "$type": "SceneComponentSaveData", + "ViewParams": { + "Scale": 0.8886388, + "AnchorX": -310.5873718261719, + "AnchorY": 346.5975036621094 + } + } + } + } + }, + { + "Key": { + "id": 7997090676448 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "SetVariableNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 1280.0, + 380.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".setVariable" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{404AE5EA-7F73-4B52-9B4C-DA5712B7E2E2}" + } + } + } + }, + { + "Key": { + "id": 8001385643744 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MethodNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 840.0, + 880.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".method" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{153AFB90-173C-4090-B709-DA73D04A8F62}" + } + } + } + }, + { + "Key": { + "id": 8005680611040 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MethodNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 1280.0, + 880.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".method" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{9ED03175-1B9D-4E72-A6A5-C089ABF0FF81}" + } + } + } + }, + { + "Key": { + "id": 8009975578336 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 460.0, + 640.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{BCF7E6DA-F30B-4AB8-96A3-B7948455532C}" + } + } + } + }, + { + "Key": { + "id": 8014270545632 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TimeNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -280.0, + 480.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{6F87177E-AF30-42E2-BD5F-1DCF623B7235}" + } + } + } + }, + { + "Key": { + "id": 8018565512928 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TimeNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 100.0, + 500.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{C812E74B-E34B-40D5-B0AE-5A1D21FEB7D4}" + } + } + } + }, + { + "Key": { + "id": 8022860480224 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "GetVariableNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -80.0, + 480.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".getVariable" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{3BCB878A-9CB7-4370-9903-52FC5505138C}" + } + } + } + }, + { + "Key": { + "id": 8027155447520 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "GetVariableNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -100.0, + 640.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".getVariable" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{6FC2D332-3653-4AD6-BB34-098CC4BD9F32}" + } + } + } + }, + { + "Key": { + "id": 8031450414816 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MethodNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 820.0, + 380.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData", + "SubStyle": ".method" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{6898E2CC-0226-4598-A801-BE4527FA0010}" + } + } + } + } + ], + "StatisticsHelper": { + "InstanceCounter": [ + { + "Key": 4199610336680704683, + "Value": 1 + }, + { + "Key": 4693003892664749777, + "Value": 1 + }, + { + "Key": 5235960430898951644, + "Value": 1 + }, + { + "Key": 5789802440471445818, + "Value": 2 + }, + { + "Key": 8348694667250199036, + "Value": 1 + }, + { + "Key": 8452971738487658154, + "Value": 1 + }, + { + "Key": 10204019744198319120, + "Value": 1 + }, + { + "Key": 16802392214997617505, + "Value": 1 + } + ] + } + } + } + } + } +} \ No newline at end of file From aaaa35b6c1fdf3276a97ab4580a69fff4334fc61 Mon Sep 17 00:00:00 2001 From: antonmic <56370189+antonmic@users.noreply.github.com> Date: Fri, 3 Dec 2021 09:56:52 -0800 Subject: [PATCH 08/13] addressed PR feedback Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com> --- Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h index a5980000fd..89766cccb5 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/PassDefines.h @@ -44,7 +44,8 @@ namespace AZ // -> Queued (Rendering will transition to Queued if a pass was queued with the PassSystem during Rendering) // // Any State -> Orphaned (transition to Orphaned state can be outside the jurisdiction of the pass and so can happen from any state) - // Orphaned -> Queued (Orphaned state transitions back to idle. + // Orphaned -> Queued (When coming out of Orphaned state, pass will queue itself for build. In practice this + // (almost?) never happens as orphaned passes are re-created in most if not all cases.) // enum class PassState : u8 { From b3bf2158b42094923da8e93f8fb86b20337edc0c Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Fri, 3 Dec 2021 13:10:35 -0800 Subject: [PATCH 09/13] Right click menu support for project buttons (#6122) Signed-off-by: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> --- .../Source/ProjectButtonWidget.cpp | 93 +++++++++++-------- .../Source/ProjectButtonWidget.h | 5 +- 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp index 3225c14266..39980e1d11 100644 --- a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.cpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace O3DE::ProjectManager { @@ -109,11 +110,11 @@ namespace O3DE::ProjectManager vLayout->addWidget(m_progressBar); } - void LabelButton::mousePressEvent([[maybe_unused]] QMouseEvent* event) + void LabelButton::mousePressEvent(QMouseEvent* event) { if(m_enabled) { - emit triggered(); + emit triggered(event); } } @@ -201,52 +202,64 @@ namespace O3DE::ProjectManager projectNameLabel->setToolTip(m_projectInfo.m_path); hLayout->addWidget(projectNameLabel); - QMenu* menu = new QMenu(this); - menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); }); - menu->addAction(tr("Configure Gems..."), this, [this]() { emit EditProjectGems(m_projectInfo.m_path); }); - menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); }); - menu->addAction(tr("Open CMake GUI..."), this, [this]() { emit OpenCMakeGUI(m_projectInfo); }); - menu->addSeparator(); - menu->addAction(tr("Open Project folder..."), this, [this]() - { - AzQtComponents::ShowFileOnDesktop(m_projectInfo.m_path); - }); - -#if AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT - menu->addAction(tr("Create Editor desktop shortcut..."), this, [this]() - { - AZ::IO::FixedMaxPath editorExecutablePath = ProjectUtils::GetEditorExecutablePath(m_projectInfo.m_path.toUtf8().constData()); - - const QString shortcutName = QString("%1 Editor").arg(m_projectInfo.m_displayName); - const QString arg = QString("--regset=\"/Amazon/AzCore/Bootstrap/project_path=%1\"").arg(m_projectInfo.m_path); - - auto result = ProjectUtils::CreateDesktopShortcut(shortcutName, editorExecutablePath.c_str(), { arg }); - if(result.IsSuccess()) - { - QMessageBox::information(this, tr("Desktop Shortcut Created"), result.GetValue()); - } - else - { - QMessageBox::critical(this, tr("Failed to create shortcut"), result.GetError()); - } - }); -#endif // AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT - - menu->addSeparator(); - menu->addAction(tr("Duplicate"), this, [this]() { emit CopyProject(m_projectInfo); }); - menu->addSeparator(); - menu->addAction(tr("Remove from O3DE"), this, [this]() { emit RemoveProject(m_projectInfo.m_path); }); - menu->addAction(tr("Delete this Project"), this, [this]() { emit DeleteProject(m_projectInfo.m_path); }); - m_projectMenuButton = new QPushButton(this); m_projectMenuButton->setObjectName("projectMenuButton"); - m_projectMenuButton->setMenu(menu); + m_projectMenuButton->setMenu(CreateProjectMenu()); hLayout->addWidget(m_projectMenuButton); } vLayout->addWidget(projectFooter); connect(m_projectImageLabel->GetOpenEditorButton(), &QPushButton::clicked, [this](){ emit OpenProject(m_projectInfo.m_path); }); + connect(m_projectImageLabel, &LabelButton::triggered, [this](QMouseEvent* event) { + if (event->button() == Qt::RightButton) + { + m_projectMenuButton->menu()->move(event->globalPos()); + m_projectMenuButton->menu()->show(); + } + }); + } + + QMenu* ProjectButton::CreateProjectMenu() + { + QMenu* menu = new QMenu(this); + menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); }); + menu->addAction(tr("Configure Gems..."), this, [this]() { emit EditProjectGems(m_projectInfo.m_path); }); + menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); }); + menu->addAction(tr("Open CMake GUI..."), this, [this]() { emit OpenCMakeGUI(m_projectInfo); }); + menu->addSeparator(); + menu->addAction(tr("Open Project folder..."), this, [this]() + { + AzQtComponents::ShowFileOnDesktop(m_projectInfo.m_path); + }); + +#if AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT + menu->addAction(tr("Create Editor desktop shortcut..."), this, [this]() + { + AZ::IO::FixedMaxPath editorExecutablePath = ProjectUtils::GetEditorExecutablePath(m_projectInfo.m_path.toUtf8().constData()); + + const QString shortcutName = QString("%1 Editor").arg(m_projectInfo.m_displayName); + const QString arg = QString("--regset=\"/Amazon/AzCore/Bootstrap/project_path=%1\"").arg(m_projectInfo.m_path); + + auto result = ProjectUtils::CreateDesktopShortcut(shortcutName, editorExecutablePath.c_str(), { arg }); + if(result.IsSuccess()) + { + QMessageBox::information(this, tr("Desktop Shortcut Created"), result.GetValue()); + } + else + { + QMessageBox::critical(this, tr("Failed to create shortcut"), result.GetError()); + } + }); +#endif // AZ_TRAIT_PROJECT_MANAGER_CREATE_DESKTOP_SHORTCUT + + menu->addSeparator(); + menu->addAction(tr("Duplicate"), this, [this]() { emit CopyProject(m_projectInfo); }); + menu->addSeparator(); + menu->addAction(tr("Remove from O3DE"), this, [this]() { emit RemoveProject(m_projectInfo.m_path); }); + menu->addAction(tr("Delete this Project"), this, [this]() { emit DeleteProject(m_projectInfo.m_path); }); + + return menu; } const ProjectInfo& ProjectButton::GetProjectInfo() const diff --git a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h index ccb644c458..358c1f249a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h +++ b/Code/Tools/ProjectManager/Source/ProjectButtonWidget.h @@ -24,6 +24,7 @@ QT_FORWARD_DECLARE_CLASS(QProgressBar) QT_FORWARD_DECLARE_CLASS(QLayout) QT_FORWARD_DECLARE_CLASS(QVBoxLayout) QT_FORWARD_DECLARE_CLASS(QEvent) +QT_FORWARD_DECLARE_CLASS(QMenu) namespace O3DE::ProjectManager { @@ -49,7 +50,7 @@ namespace O3DE::ProjectManager QLayout* GetBuildOverlayLayout(); signals: - void triggered(); + void triggered(QMouseEvent* event); public slots: void mousePressEvent(QMouseEvent* event) override; @@ -108,6 +109,8 @@ namespace O3DE::ProjectManager void ShowWarning(bool show, const QString& warning); void ShowDefaultBuildButton(); + QMenu* CreateProjectMenu(); + ProjectInfo m_projectInfo; LabelButton* m_projectImageLabel = nullptr; From fa385ec8423c87d7d221b86be4aa6f62e07d07f1 Mon Sep 17 00:00:00 2001 From: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> Date: Fri, 3 Dec 2021 13:11:23 -0800 Subject: [PATCH 10/13] Fix number argument in notifications (#6121) Signed-off-by: Alex Peterson <26804013+AMZN-alexpete@users.noreply.github.com> --- .../Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index 1d4f354fb5..5bc0b26ca5 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -294,7 +294,7 @@ namespace O3DE::ProjectManager } else if (numChangedDependencies > 1) { - notification += tr("%1 Gem %2").arg(QString(numChangedDependencies), tr("dependencies")); + notification += tr("%1 Gem %2").arg(numChangedDependencies).arg(tr("dependencies")); } notification += (added ? tr(" activated") : tr(" deactivated")); From 87fb6be96413c533f53b4e3529c840045ba3907e Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Fri, 3 Dec 2021 15:38:29 -0800 Subject: [PATCH 11/13] Fixes to Procedural Prefab instantiation - ensure the container of the procprefab has the correct editor components, and remove limitation to instantiating at the root. (#6147) Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- .../Prefab/PrefabSystemScriptingHandler.cpp | 7 ++++++- .../UI/Prefab/PrefabIntegrationManager.cpp | 8 ++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemScriptingHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemScriptingHandler.cpp index 9d0d0547ae..93dfca3f13 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemScriptingHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemScriptingHandler.cpp @@ -8,10 +8,12 @@ #include #include +#include #include +#include +#include #include #include -#include #include #include @@ -72,6 +74,9 @@ namespace AzToolsFramework::Prefab entities, commonRoot, &topLevelEntities); auto containerEntity = AZStd::make_unique(); + containerEntity->CreateComponent(); + containerEntity->CreateComponent(); + containerEntity->CreateComponent(); containerEntity->CreateComponent(); for (AZ::Entity* entity : topLevelEntities) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp index aa6d82e634..bc6700aca5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabIntegrationManager.cpp @@ -565,9 +565,7 @@ namespace AzToolsFramework EditorRequestBus::BroadcastResult(position, &EditorRequestBus::Events::GetWorldPositionAtViewportCenter); } - // Instantiating from context menu always puts the instance at the root level auto createPrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(prefabFilePath, parentId, position); - if (!createPrefabOutcome.IsSuccess()) { WarnUserOfError("Prefab Instantiation Error",createPrefabOutcome.GetError()); @@ -594,15 +592,13 @@ namespace AzToolsFramework } else { - // otherwise return since it needs to be inside an authored prefab - return; + EditorRequestBus::BroadcastResult(position, &EditorRequestBus::Events::GetWorldPositionAtViewportCenter); } - // Instantiating from context menu always puts the instance at the root level auto createPrefabOutcome = s_prefabPublicInterface->InstantiatePrefab(prefabAssetPath, parentId, position); if (!createPrefabOutcome.IsSuccess()) { - WarnUserOfError("Prefab Instantiation Error", createPrefabOutcome.GetError()); + WarnUserOfError("Procedural Prefab Instantiation Error", createPrefabOutcome.GetError()); } } } From 09c9548ba4049fb182be8c95a32a0b5ad8a89ec4 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Mon, 6 Dec 2021 11:23:52 +0000 Subject: [PATCH 12/13] Automated testing create_backup and restore_backup respects file flags. (#6062) * Automated testing create_backup and restore_backup respects file flags. Example: If the file that is to be backed-up is readonly, when restored that file will be readonly. If the file that is to be backed-up is not readonly, when restored that file will be not readonly. Fixes an issue that would mark physics setreg files to readonly after running AutomatedTesting when restoring from the backup. * update LyTestTools tests that use create/restore backup to expect copy2 instead of copy Signed-off-by: amzn-sean <75276488+amzn-sean@users.noreply.github.com> --- .../Physics/utils/FileManagement.py | 55 ++++++++----------- .../ly_test_tools/environment/file_system.py | 40 +++++++++----- .../tests/unit/test_file_system.py | 14 ++--- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py b/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py index 017bb672a4..03287d0542 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py @@ -98,38 +98,32 @@ class FileManagement: """ file_map = FileManagement._load_file_map() backup_path = FileManagement.backup_folder_path - backup_file_name = "{}.bak".format(file_name) - backup_file = os.path.join(backup_path, backup_file_name) # If backup directory DNE, make one if not os.path.exists(backup_path): os.mkdir(backup_path) - # If "traditional" backup file exists, delete it (myFile.txt.bak) - if os.path.exists(backup_file): - fs.delete([backup_file], True, False) - # Find my next storage name (myFile_1.txt.bak) - backup_storage_file_name = FileManagement._next_available_name(backup_file_name, file_map) - if backup_storage_file_name is None: + + # Find my next storage name (myFile_1.txt) + backup_file_name = FileManagement._next_available_name(file_name, file_map) + if backup_file_name is None: # If _next_available_name returns None, we have backed up MAX_BACKUPS of files name [file_name] raise Exception( "FileManagement class ran out of backups per name. Max: {}".format(FileManagement.MAX_BACKUPS) ) - backup_storage_file = os.path.join(backup_path, backup_storage_file_name) + + # If this backup file already exists, delete it. + backup_storage_file = "{}.bak".format(os.path.normpath(os.path.join(backup_path, backup_file_name))) if os.path.exists(backup_storage_file): - # This file should not exists, but if it does it's about to get clobbered! - fs.unlock_file(backup_storage_file) - # Create "traditional" backup file (myFile.txt.bak) - fs.create_backup(os.path.join(file_path, file_name), backup_path) - # Copy "traditional" backup file into storage backup (myFile_1.txt.bak) - FileManagement._copy_file(backup_file_name, backup_path, backup_storage_file_name, backup_path) - fs.lock_file(backup_storage_file) - # Delete "traditional" back up file - fs.unlock_file(backup_file) - fs.delete([backup_file], True, False) + fs.delete([backup_storage_file], True, False) + + # Create backup file (myFile_1.txt.bak) + original_file = os.path.normpath(os.path.join(file_path, file_name)) + fs.create_backup(original_file, backup_path, backup_file_name) + # Update file map with new file - file_map[os.path.join(file_path, file_name)] = backup_storage_file_name + file_map[original_file] = backup_file_name FileManagement._save_file_map(file_map) # Unlock original file to get it ready to be edited by the test - fs.unlock_file(os.path.join(file_path, file_name)) + fs.unlock_file(original_file) @staticmethod def _restore_file(file_name, file_path): @@ -143,20 +137,15 @@ class FileManagement: """ file_map = FileManagement._load_file_map() backup_path = FileManagement.backup_folder_path - src_file = os.path.join(file_path, file_name) + src_file = os.path.normpath(os.path.join(file_path, file_name)) if src_file in file_map: - backup_file = os.path.join(backup_path, file_map[src_file]) - if os.path.exists(backup_file): - fs.unlock_file(backup_file) - fs.unlock_file(src_file) - # Make temporary copy of backed up file to restore from - temp_file = "{}.bak".format(file_name) - FileManagement._copy_file(file_map[src_file], backup_path, temp_file, backup_path) - fs.restore_backup(src_file, backup_path) - fs.lock_file(src_file) - # Delete backup file - fs.delete([os.path.join(backup_path, temp_file)], True, False) + backup_file_name = file_map[src_file] + backup_file = "{}.bak".format(os.path.join(backup_path, backup_file_name)) + + fs.unlock_file(src_file) + if fs.restore_backup(src_file, backup_path, backup_file_name): fs.delete([backup_file], True, False) + # Remove from file map del file_map[src_file] FileManagement._save_file_map(file_map) diff --git a/Tools/LyTestTools/ly_test_tools/environment/file_system.py b/Tools/LyTestTools/ly_test_tools/environment/file_system.py index c67ecc5b23..e8fb1d13cf 100755 --- a/Tools/LyTestTools/ly_test_tools/environment/file_system.py +++ b/Tools/LyTestTools/ly_test_tools/environment/file_system.py @@ -293,61 +293,75 @@ def delete(file_list, del_files, del_dirs): return True -def create_backup(source, backup_dir): +def create_backup(source, backup_dir, backup_name=None): """ Creates a backup of a single source file by creating a copy of it with the same name + '.bak' in backup_dir e.g.: foo.txt is stored as backup_dir/foo.txt.bak + If backup_name is provided, it will create a copy of the source file named "backup_name + .bak" instead. :param source: Full path to file to backup :param backup_dir: Path to the directory to store backup. + :param backup_name: [Optional] Name of the backed up file to use instead or the source name. """ if not backup_dir or not os.path.isdir(backup_dir): logger.error(f'Cannot create backup due to invalid backup directory {backup_dir}') - return + return False if not os.path.exists(source): logger.warning(f'Source file {source} does not exist, aborting backup creation.') - return + return False - source_filename = os.path.basename(source) - dest = os.path.join(backup_dir, f'{source_filename}.bak') + dest = None + if backup_name is None: + source_filename = os.path.basename(source) + dest = os.path.join(backup_dir, f'{source_filename}.bak') + else: + dest = os.path.join(backup_dir, f'{backup_name}.bak') logger.info(f'Saving backup of {source} in {dest}') if os.path.exists(dest): logger.warning(f'Backup file already exists at {dest}, it will be overwritten.') try: - shutil.copy(source, dest) + shutil.copy2(source, dest) except Exception: # intentionally broad logger.warning('Could not create backup, exception occurred while copying.', exc_info=True) + return False + return True -def restore_backup(original_file, backup_dir): +def restore_backup(original_file, backup_dir, backup_name=None): """ Restores a backup file to its original location. Works with a single file only. :param original_file: Full path to file to overwrite. :param backup_dir: Path to the directory storing the backup. + :param backup_name: [Optional] Provide if the backup file name is different from source. eg backup file = myFile_1.txt.bak original file = myfile.txt """ if not backup_dir or not os.path.isdir(backup_dir): logger.error(f'Cannot restore backup due to invalid or nonexistent directory {backup_dir}.') - return + return False - source_filename = os.path.basename(original_file) - backup = os.path.join(backup_dir, f'{source_filename}.bak') + backup = None + if backup_name is None: + source_filename = os.path.basename(original_file) + backup = os.path.join(backup_dir, f'{source_filename}.bak') + else: + backup = os.path.join(backup_dir, f'{backup_name}.bak') if not os.path.exists(backup): logger.warning(f'Backup file {backup} does not exist, aborting backup restoration.') - return + return False logger.info(f'Restoring backup of {original_file} from {backup}') try: - shutil.copy(backup, original_file) + shutil.copy2(backup, original_file) except Exception: # intentionally broad logger.warning('Could not restore backup, exception occurred while copying.', exc_info=True) - + return False + return True def delete_oldest(path_glob, keep_num, del_files=True, del_dirs=False): """ Delete oldest builds, keeping a specific number """ diff --git a/Tools/LyTestTools/tests/unit/test_file_system.py b/Tools/LyTestTools/tests/unit/test_file_system.py index 2ddd3f8934..2fdcf8131e 100755 --- a/Tools/LyTestTools/tests/unit/test_file_system.py +++ b/Tools/LyTestTools/tests/unit/test_file_system.py @@ -751,7 +751,7 @@ class TestFileBackup(unittest.TestCase): self._dummy_file = 'dummy.txt' self._dummy_backup_file = os.path.join(self._dummy_dir, '{}.bak'.format(self._dummy_file)) - @mock.patch('shutil.copy') + @mock.patch('shutil.copy2') @mock.patch('os.path.exists') @mock.patch('os.path.isdir') def test_BackupSettings_SourceExists_BackupCreated(self, mock_path_isdir, mock_backup_exists, mock_copy): @@ -763,7 +763,7 @@ class TestFileBackup(unittest.TestCase): mock_copy.assert_called_with(self._dummy_file, self._dummy_backup_file) @mock.patch('ly_test_tools.environment.file_system.logger.warning') - @mock.patch('shutil.copy') + @mock.patch('shutil.copy2') @mock.patch('os.path.exists') @mock.patch('os.path.isdir') def test_BackupSettings_BackupExists_WarningLogged(self, mock_path_isdir, mock_backup_exists, mock_copy, mock_logger_warning): @@ -776,7 +776,7 @@ class TestFileBackup(unittest.TestCase): mock_logger_warning.assert_called_once() @mock.patch('ly_test_tools.environment.file_system.logger.warning') - @mock.patch('shutil.copy') + @mock.patch('shutil.copy2') @mock.patch('os.path.exists') @mock.patch('os.path.isdir') def test_BackupSettings_SourceNotExists_WarningLogged(self, mock_path_isdir, mock_backup_exists, mock_copy, mock_logger_warning): @@ -789,7 +789,7 @@ class TestFileBackup(unittest.TestCase): mock_logger_warning.assert_called_once() @mock.patch('ly_test_tools.environment.file_system.logger.warning') - @mock.patch('shutil.copy') + @mock.patch('shutil.copy2') @mock.patch('os.path.exists') @mock.patch('os.path.isdir') def test_BackupSettings_CannotCopy_WarningLogged(self, mock_path_isdir, mock_backup_exists, mock_copy, mock_logger_warning): @@ -821,7 +821,7 @@ class TestFileBackupRestore(unittest.TestCase): self._dummy_file = 'dummy.txt' self._dummy_backup_file = os.path.join(self._dummy_dir, '{}.bak'.format(self._dummy_file)) - @mock.patch('shutil.copy') + @mock.patch('shutil.copy2') @mock.patch('os.path.exists') @mock.patch('os.path.isdir') def test_RestoreSettings_BackupRestore_Success(self, mock_path_isdir, mock_exists, mock_copy): @@ -832,7 +832,7 @@ class TestFileBackupRestore(unittest.TestCase): mock_copy.assert_called_with(self._dummy_backup_file, self._dummy_file) @mock.patch('ly_test_tools.environment.file_system.logger.warning') - @mock.patch('shutil.copy') + @mock.patch('shutil.copy2') @mock.patch('os.path.exists') @mock.patch('os.path.isdir') def test_RestoreSettings_CannotCopy_WarningLogged(self, mock_path_isdir, mock_exists, mock_copy, mock_logger_warning): @@ -846,7 +846,7 @@ class TestFileBackupRestore(unittest.TestCase): mock_logger_warning.assert_called_once() @mock.patch('ly_test_tools.environment.file_system.logger.warning') - @mock.patch('shutil.copy') + @mock.patch('shutil.copy2') @mock.patch('os.path.exists') @mock.patch('os.path.isdir') def test_RestoreSettings_BackupNotExists_WarningLogged(self, mock_path_isdir, mock_exists, mock_copy, mock_logger_warning): From 969dbf407a8aa4fdd30a16fc992f1bd8ff9b31be Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Mon, 6 Dec 2021 14:53:45 +0000 Subject: [PATCH 13/13] Add tests for planar manipulator draw when dealing with scaling (#6164) * add support to add a custom debug display request interface for manipulator test framework Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * wip changes to support tests for manipulator view drawing Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * add test for planar manipulator draw when dealing with scaling Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * additional comments for added context Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * small updates/fixes after PR feedback Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * fix for missing NullDebugDisplayRequests Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> --- .../UnitTest/TestDebugDisplayRequests.h | 7 ++ .../AzManipulatorTestFrameworkTestHelpers.h | 3 +- .../DirectManipulatorViewportInteraction.h | 5 +- .../IndirectManipulatorViewportInteraction.h | 2 +- .../ViewportInteraction.h | 11 ++- .../DirectManipulatorViewportInteraction.cpp | 5 +- ...IndirectManipulatorViewportInteraction.cpp | 5 +- .../Source/ViewportInteraction.cpp | 13 +-- .../Tests/GridSnappingTest.cpp | 3 +- .../Tests/ViewportInteractionTest.cpp | 3 +- .../Tests/WorldSpaceBuilderTest.cpp | 6 +- .../Manipulators/AngularManipulator.cpp | 4 +- .../LineSegmentSelectionManipulator.cpp | 4 +- .../Manipulators/LinearManipulator.cpp | 4 +- .../Manipulators/ManipulatorManager.cpp | 2 +- .../Manipulators/ManipulatorSpace.cpp | 15 ++-- .../Manipulators/ManipulatorSpace.h | 2 + .../Manipulators/ManipulatorView.cpp | 9 ++- .../Manipulators/ManipulatorView.h | 3 +- .../Manipulators/MultiLinearManipulator.cpp | 4 +- .../Manipulators/PlanarManipulator.cpp | 4 +- .../Manipulators/SelectionManipulator.cpp | 4 +- .../SplineSelectionManipulator.cpp | 4 +- .../Manipulators/SurfaceManipulator.cpp | 4 +- .../Manipulators/TranslationManipulators.cpp | 80 ++++++++++++++----- .../Manipulators/TranslationManipulators.h | 42 ++++++++-- .../UnitTest/AzToolsFrameworkTestHelpers.h | 9 +++ .../Tests/ManipulatorViewTests.cpp | 80 +++++++++++++++---- .../JointsSubComponentModeAngleCone.cpp | 5 +- .../Code/Tests/WhiteBoxComponentTest.cpp | 8 +- 30 files changed, 244 insertions(+), 106 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.h b/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.h index 72b15c1a69..b71d10c751 100644 --- a/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.h +++ b/Code/Framework/AzFramework/AzFramework/UnitTest/TestDebugDisplayRequests.h @@ -13,6 +13,13 @@ namespace UnitTest { + //! Null implementation of DebugDisplayRequests for dummy draw calls. + class NullDebugDisplayRequests : public AzFramework::DebugDisplayRequests + { + public: + virtual ~NullDebugDisplayRequests() = default; + }; + //! Minimal implementation of DebugDisplayRequests to support testing shapes. //! Stores a list of points based on received draw calls to delineate the exterior of the object requested to be drawn. class TestDebugDisplayRequests : public AzFramework::DebugDisplayRequests diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkTestHelpers.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkTestHelpers.h index f87f83c1b2..63392eb82f 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkTestHelpers.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkTestHelpers.h @@ -29,7 +29,8 @@ namespace UnitTest void SetUpEditorFixtureImpl() override { ToolsApplicationFixtureT::SetUpEditorFixtureImpl(); - m_viewportManipulatorInteraction = AZStd::make_unique(); + m_viewportManipulatorInteraction = + AZStd::make_unique(ToolsApplicationFixtureT::CreateDebugDisplayRequests()); m_actionDispatcher = AZStd::make_unique(*m_viewportManipulatorInteraction); m_cameraState = AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize); diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h index 7cef7b635d..33afee695b 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h @@ -17,11 +17,10 @@ namespace AzManipulatorTestFramework class ViewportInteraction; //! Implementation of manipulator viewport interaction that manipulates the manager directly. - class DirectCallManipulatorViewportInteraction - : public ManipulatorViewportInteraction + class DirectCallManipulatorViewportInteraction : public ManipulatorViewportInteraction { public: - DirectCallManipulatorViewportInteraction(); + explicit DirectCallManipulatorViewportInteraction(AZStd::shared_ptr debugDisplayRequests); ~DirectCallManipulatorViewportInteraction(); // ManipulatorViewportInteractionInterface ... diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h index a7b1be2c7d..da2804dfd5 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h @@ -21,7 +21,7 @@ namespace AzManipulatorTestFramework class IndirectCallManipulatorViewportInteraction : public ManipulatorViewportInteraction { public: - IndirectCallManipulatorViewportInteraction(); + explicit IndirectCallManipulatorViewportInteraction(AZStd::shared_ptr debugDisplayRequests); ~IndirectCallManipulatorViewportInteraction(); // ManipulatorViewportInteractionInterface ... diff --git a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h index a353140d4c..1568c1a931 100644 --- a/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h +++ b/Code/Framework/AzManipulatorTestFramework/Include/AzManipulatorTestFramework/ViewportInteraction.h @@ -11,10 +11,13 @@ #include #include +namespace AzFramework +{ + class DebugDisplayRequests; +} + namespace AzManipulatorTestFramework { - class NullDebugDisplayRequests; - //! Implementation of the viewport interaction model to handle viewport interaction requests. class ViewportInteraction : public ViewportInteractionInterface @@ -23,7 +26,7 @@ namespace AzManipulatorTestFramework , private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler { public: - ViewportInteraction(); + explicit ViewportInteraction(AZStd::shared_ptr debugDisplayRequests); ~ViewportInteraction(); // ViewportInteractionInterface overrides ... @@ -63,7 +66,7 @@ namespace AzManipulatorTestFramework static constexpr AzFramework::ViewportId m_viewportId = 1234; //!< Arbitrary viewport id for manipulator tests. AzFramework::EntityVisibilityQuery m_entityVisibilityQuery; - AZStd::unique_ptr m_nullDebugDisplayRequests; + AZStd::shared_ptr m_debugDisplayRequests; AzFramework::CameraState m_cameraState; bool m_gridSnapping = false; bool m_angularSnapping = false; diff --git a/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp b/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp index c9234fe488..c96840e4c9 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/DirectManipulatorViewportInteraction.cpp @@ -118,10 +118,11 @@ namespace AzManipulatorTestFramework return m_manipulatorManager->Interacting(); } - DirectCallManipulatorViewportInteraction::DirectCallManipulatorViewportInteraction() + DirectCallManipulatorViewportInteraction::DirectCallManipulatorViewportInteraction( + AZStd::shared_ptr debugDisplayRequests) : m_customManager( AZStd::make_unique(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId")))) - , m_viewportInteraction(AZStd::make_unique()) + , m_viewportInteraction(AZStd::make_unique(AZStd::move(debugDisplayRequests))) , m_manipulatorManager(AZStd::make_unique(m_viewportInteraction.get(), m_customManager)) { } diff --git a/Code/Framework/AzManipulatorTestFramework/Source/IndirectManipulatorViewportInteraction.cpp b/Code/Framework/AzManipulatorTestFramework/Source/IndirectManipulatorViewportInteraction.cpp index 9bcb8986d5..9c5f84196f 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/IndirectManipulatorViewportInteraction.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/IndirectManipulatorViewportInteraction.cpp @@ -76,8 +76,9 @@ namespace AzManipulatorTestFramework return manipulatorInteracting; } - IndirectCallManipulatorViewportInteraction::IndirectCallManipulatorViewportInteraction() - : m_viewportInteraction(AZStd::make_unique()) + IndirectCallManipulatorViewportInteraction::IndirectCallManipulatorViewportInteraction( + AZStd::shared_ptr debugDisplayRequests) + : m_viewportInteraction(AZStd::make_unique(AZStd::move(debugDisplayRequests))) , m_manipulatorManager(AZStd::make_unique(*m_viewportInteraction)) { } diff --git a/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp b/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp index e56f7d6d72..1a28c8cad1 100644 --- a/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Source/ViewportInteraction.cpp @@ -13,15 +13,8 @@ namespace AzManipulatorTestFramework { - // Null debug display for dummy draw calls - class NullDebugDisplayRequests : public AzFramework::DebugDisplayRequests - { - public: - virtual ~NullDebugDisplayRequests() = default; - }; - - ViewportInteraction::ViewportInteraction() - : m_nullDebugDisplayRequests(AZStd::make_unique()) + ViewportInteraction::ViewportInteraction(AZStd::shared_ptr debugDisplayRequests) + : m_debugDisplayRequests(AZStd::move(debugDisplayRequests)) { AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler::BusConnect(m_viewportId); AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler::BusConnect(m_viewportId); @@ -102,7 +95,7 @@ namespace AzManipulatorTestFramework AzFramework::DebugDisplayRequests& ViewportInteraction::GetDebugDisplay() { - return *m_nullDebugDisplayRequests; + return *m_debugDisplayRequests; } void ViewportInteraction::SetGridSnapping(const bool enabled) diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp index 4af66edc0a..8707d08bb3 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/GridSnappingTest.cpp @@ -26,7 +26,8 @@ namespace UnitTest { public: GridSnappingFixture() - : m_viewportManipulatorInteraction(AZStd::make_unique()) + : m_viewportManipulatorInteraction(AZStd::make_unique( + AZStd::make_shared())) , m_actionDispatcher( AZStd::make_unique(*m_viewportManipulatorInteraction)) { diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp index 38c3e33977..481647f960 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/ViewportInteractionTest.cpp @@ -15,7 +15,8 @@ namespace UnitTest { public: AValidViewportInteraction() - : m_viewportInteraction(AZStd::make_unique()) + : m_viewportInteraction( + AZStd::make_unique(AZStd::make_shared())) { } diff --git a/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp b/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp index 376c18072e..95afe0e47d 100644 --- a/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp +++ b/Code/Framework/AzManipulatorTestFramework/Tests/WorldSpaceBuilderTest.cpp @@ -75,9 +75,11 @@ namespace UnitTest void SetUpEditorFixtureImpl() override { m_directState = - AZStd::make_unique(AZStd::make_unique()); + AZStd::make_unique(AZStd::make_unique( + AZStd::make_shared())); m_busState = - AZStd::make_unique(AZStd::make_unique()); + AZStd::make_unique(AZStd::make_unique( + AZStd::make_shared())); m_cameraState = AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp index b8fb4e6a53..29445f6562 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/AngularManipulator.cpp @@ -191,8 +191,8 @@ namespace AzToolsFramework { m_manipulatorView->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState, - mouseInteraction); + ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } void AngularManipulator::SetAxis(const AZ::Vector3& axis) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp index 2131fdf1cf..4ded50e1ab 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LineSegmentSelectionManipulator.cpp @@ -116,8 +116,8 @@ namespace AzToolsFramework { m_manipulatorView->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay, cameraState, - mouseInteraction); + ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), m_localStart, MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp index ee63c5de47..8b55480e5a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/LinearManipulator.cpp @@ -239,8 +239,8 @@ namespace AzToolsFramework view->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, cameraState, - mouseInteraction); + ManipulatorState{ ApplySpace(localTransform), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp index b07ac08d87..859bfcab30 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorManager.cpp @@ -146,7 +146,7 @@ namespace AzToolsFramework for (const auto& pair : m_manipulatorIdToPtrMap) { - pair.second->Draw({ Interacting() }, debugDisplay, cameraState, mouseInteraction); + pair.second->Draw(ManipulatorManagerState{ Interacting() }, debugDisplay, cameraState, mouseInteraction); } RefreshMouseOverState(mouseInteraction.m_mousePick); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.cpp index d42182db92..5e05bea72a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.cpp @@ -10,6 +10,15 @@ namespace AzToolsFramework { + AZ::Transform ApplySpace(const AZ::Transform& localTransform, const AZ::Transform& space, const AZ::Vector3& nonUniformScale) + { + AZ::Transform result; + result.SetRotation(space.GetRotation() * localTransform.GetRotation()); + result.SetTranslation(space.TransformPoint(nonUniformScale * localTransform.GetTranslation())); + result.SetUniformScale(space.GetUniformScale() * localTransform.GetUniformScale()); + return result; + } + const AZ::Transform& ManipulatorSpace::GetSpace() const { return m_space; @@ -32,11 +41,7 @@ namespace AzToolsFramework AZ::Transform ManipulatorSpace::ApplySpace(const AZ::Transform& localTransform) const { - AZ::Transform result; - result.SetRotation(m_space.GetRotation() * localTransform.GetRotation()); - result.SetTranslation(m_space.TransformPoint(m_nonUniformScale * localTransform.GetTranslation())); - result.SetUniformScale(m_space.GetUniformScale() * localTransform.GetUniformScale()); - return result; + return AzToolsFramework::ApplySpace(localTransform, m_space, m_nonUniformScale); } const AZ::Vector3& ManipulatorSpaceWithLocalPosition::GetLocalPosition() const diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h index c372afcf32..5ceb4a36cc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorSpace.h @@ -17,6 +17,8 @@ namespace AZ namespace AzToolsFramework { + AZ::Transform ApplySpace(const AZ::Transform& localTransform, const AZ::Transform& space, const AZ::Vector3& nonUniformScale); + //! Handles location for manipulators which have a global space but no local transformation. class ManipulatorSpace { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp index e36231032f..e4ee75bbf9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.cpp @@ -383,8 +383,8 @@ namespace AzToolsFramework debugDisplay.DrawLine(quadBoundVisual.m_corner1, quadBoundVisual.m_corner2); debugDisplay.SetColor(ViewColor(manipulatorState.m_mouseOver, m_axis2Color, m_mouseOverColor).GetAsVector4()); + debugDisplay.DrawLine(quadBoundVisual.m_corner4, quadBoundVisual.m_corner1); debugDisplay.DrawLine(quadBoundVisual.m_corner2, quadBoundVisual.m_corner3); - debugDisplay.DrawLine(quadBoundVisual.m_corner1, quadBoundVisual.m_corner4); if (manipulatorState.m_mouseOver) { @@ -738,15 +738,16 @@ namespace AzToolsFramework /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AZStd::unique_ptr CreateManipulatorViewQuad( - const PlanarManipulator& planarManipulator, + const AZ::Vector3& axis1, + const AZ::Vector3& axis2, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Vector3& offset, const float size) { AZStd::unique_ptr viewQuad = AZStd::make_unique(); - viewQuad->m_axis1 = planarManipulator.GetAxis1(); - viewQuad->m_axis2 = planarManipulator.GetAxis2(); + viewQuad->m_axis1 = axis1; + viewQuad->m_axis2 = axis2; viewQuad->m_size = size; viewQuad->m_offset = offset; viewQuad->m_axis1Color = axis1Color; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h index 6f94a9d253..8a9514d11a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/ManipulatorView.h @@ -382,7 +382,8 @@ namespace AzToolsFramework // Helpers to create various manipulator views. AZStd::unique_ptr CreateManipulatorViewQuad( - const PlanarManipulator& planarManipulator, + const AZ::Vector3& axis1, + const AZ::Vector3& axis2, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Vector3& offset, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp index 10c3a57749..f4dca63d77 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/MultiLinearManipulator.cpp @@ -145,8 +145,8 @@ namespace AzToolsFramework { view->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, - cameraState, mouseInteraction); + ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, + debugDisplay, cameraState, mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp index 825edf6ba4..9dbb49a1e6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/PlanarManipulator.cpp @@ -202,8 +202,8 @@ namespace AzToolsFramework { view->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, - cameraState, mouseInteraction); + ManipulatorState{ ApplySpace(GetLocalTransform()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, + debugDisplay, cameraState, mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp index 9cf97dc213..64496c44d7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SelectionManipulator.cpp @@ -90,8 +90,8 @@ namespace AzToolsFramework { view->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState, - mouseInteraction); + ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp index 4ee965e43a..1da4240bf7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SplineSelectionManipulator.cpp @@ -94,8 +94,8 @@ namespace AzToolsFramework { m_manipulatorView->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, debugDisplay, - cameraState, mouseInteraction); + ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), AZ::Vector3::CreateZero(), MouseOver() }, + debugDisplay, cameraState, mouseInteraction); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp index 01b8635406..58d579b20c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/SurfaceManipulator.cpp @@ -166,8 +166,8 @@ namespace AzToolsFramework { m_manipulatorView->Draw( GetManipulatorManagerId(), managerState, GetManipulatorId(), - { TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, cameraState, - mouseInteraction); + ManipulatorState{ TransformUniformScale(GetSpace()), GetNonUniformScale(), GetLocalPosition(), MouseOver() }, debugDisplay, + cameraState, mouseInteraction); } void SurfaceManipulator::InvalidateImpl() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp index f6c0028546..5810662e57 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.cpp @@ -19,6 +19,21 @@ namespace AzToolsFramework static const AZ::Color LinearManipulatorZAxisColor = AZ::Color(0.0f, 0.0f, 1.0f, 1.0f); static const AZ::Color SurfaceManipulatorColor = AZ::Color(1.0f, 1.0f, 0.0f, 0.5f); + static TranslationManipulatorsViewCreateInfo DefaultTranslationManipulatorViewCreateInfo() + { + TranslationManipulatorsViewCreateInfo createInfo; + createInfo.axis1Color = LinearManipulatorXAxisColor; + createInfo.axis2Color = LinearManipulatorYAxisColor; + createInfo.axis3Color = LinearManipulatorZAxisColor; + createInfo.surfaceColor = SurfaceManipulatorColor; + createInfo.linearAxisLength = LinearManipulatorAxisLength(); + createInfo.linearConeLength = LinearManipulatorConeLength(); + createInfo.linearConeRadius = LinearManipulatorConeRadius(); + createInfo.planarAxisLength = PlanarManipulatorAxisLength(); + createInfo.surfaceRadius = SurfaceManipulatorRadius(); + return createInfo; + } + TranslationManipulators::TranslationManipulators( const Dimensions dimensions, const AZ::Transform& worldFromLocal, const AZ::Vector3& nonUniformScale) : m_dimensions(dimensions) @@ -231,17 +246,36 @@ namespace AzToolsFramework } } + void TranslationManipulators::ConfigureView2d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo) + { + ConfigureLinearView( + translationManipulatorViewCreateInfo.linearAxisLength, translationManipulatorViewCreateInfo.linearConeLength, + translationManipulatorViewCreateInfo.linearConeRadius, translationManipulatorViewCreateInfo.axis1Color, + translationManipulatorViewCreateInfo.axis2Color, translationManipulatorViewCreateInfo.axis3Color); + ConfigurePlanarView( + translationManipulatorViewCreateInfo.planarAxisLength, translationManipulatorViewCreateInfo.linearAxisLength, + translationManipulatorViewCreateInfo.linearConeLength, translationManipulatorViewCreateInfo.axis1Color, + translationManipulatorViewCreateInfo.axis2Color, translationManipulatorViewCreateInfo.axis3Color); + } + + void TranslationManipulators::ConfigureView3d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo) + { + ConfigureView2d(translationManipulatorViewCreateInfo); + ConfigureSurfaceView(translationManipulatorViewCreateInfo.surfaceRadius, translationManipulatorViewCreateInfo.surfaceColor); + } + void TranslationManipulators::ConfigureLinearView( const float axisLength, + const float coneLength, + const float coneRadius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/) { const AZ::Color axesColor[] = { axis1Color, axis2Color, axis3Color }; - const auto configureLinearView = - [lineBoundWidth = m_lineBoundWidth, coneLength = LinearManipulatorConeLength(), axisLength, - coneRadius = LinearManipulatorConeRadius()](LinearManipulator* linearManipulator, const AZ::Color& color) + const auto configureLinearView = [lineBoundWidth = m_lineBoundWidth, coneLength, axisLength, + coneRadius](LinearManipulator* linearManipulator, const AZ::Color& color) { const auto lineLength = axisLength - coneLength; @@ -259,25 +293,21 @@ namespace AzToolsFramework } void TranslationManipulators::ConfigurePlanarView( - const float planeSize, + const float planarAxisLength, + const float linearAxisLength, + const float linearConeLength, const AZ::Color& plane1Color, const AZ::Color& plane2Color /*= AZ::Color(0.0f, 1.0f, 0.0f, 0.5f)*/, const AZ::Color& plane3Color /*= AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)*/) { const AZ::Color planesColor[] = { plane1Color, plane2Color, plane3Color }; - const float linearAxisLength = LinearManipulatorAxisLength(); - const float linearConeLength = LinearManipulatorConeLength(); for (size_t manipulatorIndex = 0; manipulatorIndex < m_planarManipulators.size(); ++manipulatorIndex) { const auto& planarManipulator = *m_planarManipulators[manipulatorIndex]; - const AZStd::shared_ptr manipulatorView = CreateManipulatorViewQuad( - *m_planarManipulators[manipulatorIndex], planesColor[manipulatorIndex], planesColor[(manipulatorIndex + 1) % 3], - (planarManipulator.GetAxis1() + planarManipulator.GetAxis2()) * - (((linearAxisLength - linearConeLength) * 0.5f) - (planeSize * 0.5f)), - planeSize); - - m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ manipulatorView }); + m_planarManipulators[manipulatorIndex]->SetViews(ManipulatorViews{ CreateManipulatorViewQuadForPlanarTranslationManipulator( + planarManipulator.GetAxis1(), planarManipulator.GetAxis2(), planesColor[manipulatorIndex], + planesColor[(manipulatorIndex + 1) % 3], linearAxisLength, linearConeLength, planarAxisLength) }); } } @@ -325,19 +355,25 @@ namespace AzToolsFramework void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators) { translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ()); - translationManipulators->ConfigurePlanarView( - PlanarManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor); - translationManipulators->ConfigureLinearView( - LinearManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor, LinearManipulatorZAxisColor); - translationManipulators->ConfigureSurfaceView(SurfaceManipulatorRadius(), SurfaceManipulatorColor); + translationManipulators->ConfigureView3d(DefaultTranslationManipulatorViewCreateInfo()); } void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators) { translationManipulators->SetAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY()); - translationManipulators->ConfigurePlanarView( - PlanarManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor); - translationManipulators->ConfigureLinearView( - LinearManipulatorAxisLength(), LinearManipulatorXAxisColor, LinearManipulatorYAxisColor); + translationManipulators->ConfigureView2d(DefaultTranslationManipulatorViewCreateInfo()); + } + + AZStd::shared_ptr CreateManipulatorViewQuadForPlanarTranslationManipulator( + const AZ::Vector3& axis1, + const AZ::Vector3& axis2, + const AZ::Color& axis1Color, + const AZ::Color& axis2Color, + const float linearAxisLength, + const float linearConeLength, + const float planarAxisLength) + { + const AZ::Vector3 offset = (axis1 + axis2) * (((linearAxisLength - linearConeLength) * 0.5f) - (planarAxisLength * 0.5f)); + return CreateManipulatorViewQuad(axis1, axis2, axis1Color, axis2Color, offset, planarAxisLength); } } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h index 341bb2d4ac..ea8dbb7975 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Manipulators/TranslationManipulators.h @@ -15,6 +15,20 @@ namespace AzToolsFramework { + //! Parameters to configure the appearance of the TranslationManipulators view(s). + struct TranslationManipulatorsViewCreateInfo + { + float linearAxisLength; + float linearConeLength; + float linearConeRadius; + float planarAxisLength; + float surfaceRadius; + AZ::Color axis1Color; + AZ::Color axis2Color; + AZ::Color axis3Color; + AZ::Color surfaceColor; + }; + //! TranslationManipulators is an aggregation of 3 linear manipulators, 3 planar manipulators //! and one surface manipulator who share the same transform. class TranslationManipulators : public Manipulators @@ -23,6 +37,9 @@ namespace AzToolsFramework AZ_RTTI(TranslationManipulators, "{D5E49EA2-30E0-42BC-A51D-6A7F87818260}") AZ_CLASS_ALLOCATOR(TranslationManipulators, AZ::SystemAllocator, 0) + TranslationManipulators(TranslationManipulators&&) = delete; + TranslationManipulators& operator=(TranslationManipulators&&) = delete; + //! How many dimensions does this translation manipulator have. enum class Dimensions { @@ -52,26 +69,31 @@ namespace AzToolsFramework void SetAxes(const AZ::Vector3& axis1, const AZ::Vector3& axis2, const AZ::Vector3& axis3 = AZ::Vector3::CreateAxisZ()); + void ConfigureView2d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo); + void ConfigureView3d(const TranslationManipulatorsViewCreateInfo& translationManipulatorViewCreateInfo); + + //! Sets the bound width to use for the line/axis of a linear manipulator. + void SetLineBoundWidth(float lineBoundWidth); + + private: void ConfigurePlanarView( float planeSize, + float linearAxisLength, + float linearConeLength, const AZ::Color& plane1Color, const AZ::Color& plane2Color = AZ::Color(0.0f, 1.0f, 0.0f, 0.5f), const AZ::Color& plane3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)); void ConfigureLinearView( float axisLength, + float coneLength, + float coneRadius, const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f)); void ConfigureSurfaceView(float radius, const AZ::Color& color); - //! Sets the bound width to use for the line/axis of a linear manipulator. - void SetLineBoundWidth(float lineBoundWidth); - - private: - AZ_DISABLE_COPY_MOVE(TranslationManipulators) - // Manipulators void ProcessManipulators(const AZStd::function&) override; @@ -131,4 +153,12 @@ namespace AzToolsFramework void ConfigureTranslationManipulatorAppearance3d(TranslationManipulators* translationManipulators); void ConfigureTranslationManipulatorAppearance2d(TranslationManipulators* translationManipulators); + AZStd::shared_ptr CreateManipulatorViewQuadForPlanarTranslationManipulator( + const AZ::Vector3& axis1, + const AZ::Vector3& axis2, + const AZ::Color& axis1Color, + const AZ::Color& axis2Color, + float linearAxisLength, + float linearConeLength, + float planarAxisLength); } // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h index 1e29f1dbce..77a3639871 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h @@ -15,12 +15,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -235,6 +237,13 @@ namespace UnitTest return toolsApp; } + //! It is possible to override this in classes deriving from ToolsApplicationFixture to provide alternate + //! implementations of the DebugDisplayRequests interface (e.g. TestDebugDisplayRequests). + virtual AZStd::shared_ptr CreateDebugDisplayRequests() + { + return AZStd::make_shared(); + } + protected: TestEditorActions m_editorActions; ToolsApplicationMessageHandler m_messageHandler; // used to suppress trace messages in test output diff --git a/Code/Framework/AzToolsFramework/Tests/ManipulatorViewTests.cpp b/Code/Framework/AzToolsFramework/Tests/ManipulatorViewTests.cpp index 11ec33a995..5f02d9da9c 100644 --- a/Code/Framework/AzToolsFramework/Tests/ManipulatorViewTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ManipulatorViewTests.cpp @@ -7,12 +7,16 @@ */ #include +#include +#include +#include +#include #include #include -#include +#include #include -#include - +#include +#include #include #include #include @@ -21,8 +25,7 @@ namespace UnitTest { using namespace AzToolsFramework; - class ManipulatorViewTest - : public AllocatorsTestFixture + class ManipulatorViewTest : public AllocatorsTestFixture { AZStd::unique_ptr m_serializeContext; @@ -32,7 +35,7 @@ namespace UnitTest m_serializeContext = AZStd::make_unique(); m_app.Start(AzFramework::Application::Descriptor()); // 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 + // 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); } @@ -51,12 +54,9 @@ namespace UnitTest /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Given const AZ::Transform orientation = - AZ::Transform::CreateFromQuaternion( - AZ::Quaternion::CreateFromAxisAngle( - AZ::Vector3::CreateAxisX(), AZ::DegToRad(-90.0f))); + AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f))); - const AZ::Transform translation = - AZ::Transform::CreateTranslation(AZ::Vector3(5.0f, 0.0f, 10.0f)); + const AZ::Transform translation = AZ::Transform::CreateTranslation(AZ::Vector3(5.0f, 0.0f, 10.0f)); const AZ::Transform manipulatorSpace = translation * orientation; // create a rotation manipulator in an arbitrary space @@ -67,8 +67,7 @@ namespace UnitTest // When const AZ::Vector3 worldCameraPosition = AZ::Vector3(5.0f, -10.0f, 10.0f); // transform the view direction to the space of the manipulator (space + local transform) - const AZ::Vector3 viewDirection = - CalculateViewDirection(rotationManipulators, worldCameraPosition); + const AZ::Vector3 viewDirection = CalculateViewDirection(rotationManipulators, worldCameraPosition); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -84,8 +83,7 @@ namespace UnitTest cameraState.m_position = AZ::Vector3::CreateAxisY(20.0f); cameraState.m_forward = -AZ::Vector3::CreateAxisY(); - const float scale = - AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateZero(), cameraState); + const float scale = AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateZero(), cameraState); EXPECT_NEAR(scale, 2.0f, std::numeric_limits::epsilon()); } @@ -96,9 +94,57 @@ namespace UnitTest cameraState.m_position = AZ::Vector3::CreateAxisY(20.0f); cameraState.m_forward = -AZ::Vector3::CreateAxisY(); - const float scale = - AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateAxisX(-10.0f), cameraState); + const float scale = AzToolsFramework::CalculateScreenToWorldMultiplier(AZ::Vector3::CreateAxisX(-10.0f), cameraState); EXPECT_NEAR(scale, 2.0f, std::numeric_limits::epsilon()); } + + TEST_F(ManipulatorViewTest, ManipulatorViewQuadDrawsAtCorrectPositionWhenManipulatorSpaceIsScaledUniformlyAndNonUniformly) + { + // Given + // simulate a custom manipulator space (e.g. entity transform) and a local offset within that space (e.g. spline vertex position) + const AZ::Transform space = + AZ::Transform::CreateTranslation(AZ::Vector3(2.0f, -3.0f, -4.0f)) * AZ::Transform::CreateUniformScale(2.0f); + const AZ::Vector3 localPosition = AZ::Vector3(2.0f, -2.0f, 0.0f); + const AZ::Vector3 nonUniformScale = AZ::Vector3(2.0f, 3.0f, 4.0f); + const AZ::Transform combinedTransform = + AzToolsFramework::ApplySpace(AZ::Transform::CreateTranslation(localPosition), space, nonUniformScale); + + // create a manipulator state based on the space and local position + AzToolsFramework::ManipulatorState manipulatorState{}; + manipulatorState.m_worldFromLocal = combinedTransform; + manipulatorState.m_nonUniformScale = nonUniformScale; + // note: This is zero as the localPosition is already encoded in the combinedTransform + manipulatorState.m_localPosition = AZ::Vector3::CreateZero(); + + // camera (go to position format) - 10.00, -15.00, 6.00, -90.00, 0.00 + const AzFramework::CameraState cameraState = AzFramework::CreateDefaultCamera( + AZ::Transform::CreateFromMatrix3x3AndTranslation( + AZ::Matrix3x3::CreateRotationX(AZ::DegToRad(-90.0f)), AZ::Vector3(10.0f, -15.0f, 6.0f)), + AZ::Vector2(1280, 720)); + + // test debug display instance to record vertices that were output + auto testDebugDisplayRequests = AZStd::make_shared(); + auto planarTranslationViewQuad = CreateManipulatorViewQuadForPlanarTranslationManipulator( + AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Color::CreateZero(), AZ::Color::CreateZero(), 2.2f, 0.2f, 1.0f); + + // When + // draw the quad as it would be for a manipulator + planarTranslationViewQuad->Draw( + AzToolsFramework::ManipulatorManagerId(1), AzToolsFramework::ManipulatorManagerState{ false }, + AzToolsFramework::ManipulatorId(1), manipulatorState, *testDebugDisplayRequests, cameraState, + AzToolsFramework::ViewportInteraction::MouseInteraction{}); + + const AZStd::vector expectedDisplayPositions = { + AZ::Vector3(10.5f, -13.5f, -4.0f), AZ::Vector3(11.5f, -13.5f, -4.0f), AZ::Vector3(10.5f, -14.5f, -4.0f), + AZ::Vector3(11.5f, -14.5f, -4.0f), AZ::Vector3(10.5f, -13.5f, -4.0f), AZ::Vector3(10.5f, -14.5f, -4.0f), + AZ::Vector3(11.5f, -14.5f, -4.0f), AZ::Vector3(11.5f, -13.5f, -4.0f) + }; + + // Then + const auto points = testDebugDisplayRequests->GetPoints(); + // quad vertices appear in the expected position (not offset or scaled incorrectly by space scale) + using ::testing::UnorderedPointwise; + EXPECT_THAT(points, UnorderedPointwise(ContainerIsClose(), expectedDisplayPositions)); + } } // namespace UnitTest diff --git a/Gems/PhysX/Code/Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.cpp b/Gems/PhysX/Code/Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.cpp index e942d6beaa..b229c9d020 100644 --- a/Gems/PhysX/Code/Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.cpp +++ b/Gems/PhysX/Code/Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.cpp @@ -347,8 +347,9 @@ namespace PhysX void JointsSubComponentModeAngleCone::ConfigurePlanarView(const AZ::Color& planeColor, const AZ::Color& plane2Color) { AzToolsFramework::ManipulatorViews views; - views.emplace_back(CreateManipulatorViewQuad( - *m_yzPlanarManipulator, planeColor, plane2Color, AZ::Vector3::CreateZero(), AzToolsFramework::PlanarManipulatorAxisLength())); + views.emplace_back(AzToolsFramework::CreateManipulatorViewQuad( + m_yzPlanarManipulator->GetAxis1(), m_yzPlanarManipulator->GetAxis2(), planeColor, plane2Color, AZ::Vector3::CreateZero(), + AzToolsFramework::PlanarManipulatorAxisLength())); m_yzPlanarManipulator->SetViews(AZStd::move(views)); } diff --git a/Gems/WhiteBox/Code/Tests/WhiteBoxComponentTest.cpp b/Gems/WhiteBox/Code/Tests/WhiteBoxComponentTest.cpp index 0e93f38195..ce592ee2ed 100644 --- a/Gems/WhiteBox/Code/Tests/WhiteBoxComponentTest.cpp +++ b/Gems/WhiteBox/Code/Tests/WhiteBoxComponentTest.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -38,10 +39,6 @@ namespace UnitTest static const AzToolsFramework::ManipulatorManagerId TestManipulatorManagerId = AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId")); - class NullDebugDisplayRequests : public AzFramework::DebugDisplayRequests - { - }; - class WhiteBoxManipulatorFixture : public WhiteBoxTestFixture { public: @@ -67,7 +64,8 @@ namespace UnitTest // create the direct call manipulator viewport interaction and an immediate mode dispatcher AZStd::unique_ptr viewportManipulatorInteraction = - AZStd::make_unique(); + AZStd::make_unique( + AZStd::make_shared()); AZStd::unique_ptr actionDispatcher = AZStd::make_unique( *viewportManipulatorInteraction);