diff --git a/AutomatedTesting/Animations/Motions/Jack_Death_Fall_Back_ZUp.fbx.assetinfo b/AutomatedTesting/Animations/Motions/Jack_Death_Fall_Back_ZUp.fbx.assetinfo deleted file mode 100644 index e7fd23585b..0000000000 --- a/AutomatedTesting/Animations/Motions/Jack_Death_Fall_Back_ZUp.fbx.assetinfo +++ /dev/null @@ -1,300 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Animations/Motions/Jack_Idle_Aim_ZUp.fbx.assetinfo b/AutomatedTesting/Animations/Motions/Jack_Idle_Aim_ZUp.fbx.assetinfo deleted file mode 100644 index b7b8ef2dba..0000000000 --- a/AutomatedTesting/Animations/Motions/Jack_Idle_Aim_ZUp.fbx.assetinfo +++ /dev/null @@ -1,300 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Animations/Motions/rin_Idle.fbx.assetinfo b/AutomatedTesting/Animations/Motions/rin_Idle.fbx.assetinfo deleted file mode 100644 index 8c8374e8de..0000000000 --- a/AutomatedTesting/Animations/Motions/rin_Idle.fbx.assetinfo +++ /dev/null @@ -1,638 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Animations/Motions/rin_Jump.fbx.assetinfo b/AutomatedTesting/Animations/Motions/rin_Jump.fbx.assetinfo index b3d20a25f5..c190a949b1 100644 --- a/AutomatedTesting/Animations/Motions/rin_Jump.fbx.assetinfo +++ b/AutomatedTesting/Animations/Motions/rin_Jump.fbx.assetinfo @@ -1,652 +1,142 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "values": [ + { + "$type": "MotionGroup", + "name": "rin_jump", + "selectedRootBone": "RootNode.root", + "id": "{A816A306-96C4-523C-87D9-0784EE509817}", + "rules": { + "rules": [ + { + "$type": "CoordinateSystemRule", + "targetCoordinateSystem": 1 + }, + { + "$type": "EMotionFX::Pipeline::Rule::MotionMetaDataRule", + "data": { + "motionEventTable": { + "tracks": [ + { + "name": "Sync", + "deletable": false + }, + { + "name": "sound", + "events": [ + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "Mvt_Walk" + } + ] + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "Ftsp_Walk" + } + ], + "startTime": 0.30516499280929568, + "endTime": 0.30516499280929568 + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "Mvt_Run" + } + ], + "startTime": 0.3315509855747223, + "endTime": 0.3315509855747223 + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "Ftsp_Run" + } + ], + "startTime": 0.3579379916191101, + "endTime": 0.3579379916191101 + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "Ftsp_Walk" + } + ], + "startTime": 0.9625319838523865, + "endTime": 0.9625319838523865 + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "Ftsp_Run" + } + ], + "startTime": 1.0061269998550416, + "endTime": 1.0061269998550416 + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "Mvt_Walk" + } + ], + "startTime": 1.1346169710159302, + "endTime": 1.1346169710159302 + } + ] + }, + { + "name": "Event Track 3", + "events": [ + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "RightFoot" + } + ], + "startTime": 0.0005639999872073531, + "endTime": 0.0005639999872073531 + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "JumpStart" + } + ], + "startTime": 0.36318498849868777, + "endTime": 0.36318498849868777 + }, + { + "eventDatas": [ + { + "$type": "TwoStringEventData", + "subject": "DoneJump" + } + ], + "startTime": 1.059928059577942, + "endTime": 1.059928059577942 + } + ] + } + ] + } + } + }, + { + "$type": "MotionSamplingRule" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py index 2583109573..382a6f27f7 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py @@ -6,13 +6,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT import logging import os -import tempfile +import psutil import ly_test_tools.log.log_monitor import ly_test_tools.environment.process_utils as process_utils import ly_test_tools.environment.waiter as waiter -from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole from ly_remote_console.remote_console_commands import send_command_and_expect_response as send_command_and_expect_response + logger = logging.getLogger(__name__) @@ -95,7 +95,7 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc return port_listening if null_renderer: - launcher.args.extend(["-NullRenderer"]) + launcher.args.extend(["-rhi=Null"]) # Start the Launcher with launcher.start(): @@ -110,8 +110,8 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc # Load the specified level in the launcher send_command_and_expect_response(remote_console_instance, - f"map {level}", - "LEVEL_LOAD_COMPLETE", timeout=30) + f"LoadLevel {level}", + "LEVEL_LOAD_END", timeout=30) # Monitor the console for expected lines for line in expected_lines: diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py index bbdb925585..2fac361ced 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py @@ -36,8 +36,8 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper): :return: None """ - PREPROCESS_INSTANCE_COUNT = 24 - POSTPROCESS_INSTANCE_COUNT = 18 + PREPROCESS_INSTANCE_COUNT = 44 + POSTPROCESS_INSTANCE_COUNT = 34 # Create empty level self.test_success = self.create_level( @@ -62,25 +62,7 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper): dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0) # Add entity with Mesh to replicate creation of hills - hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 40.0, 40.0, 40.0) - - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") - - # Increase Box Shape size to encompass the hills - vegetation.get_set_test(1, "Box Shape|Box Configuration|Dimensions", math.Vector3(100.0, 100.0, 100.0)) + hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 10.0) # Set a Min Altitude of 38 and Max of 40 in Vegetation Altitude Filter vegetation.get_set_test(3, "Configuration|Altitude Min", 38.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py index 4b0951acaf..6a99979a1f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py @@ -9,9 +9,10 @@ import sys sys.path.append(os.path.dirname(os.path.abspath(__file__))) import azlmbr.asset as asset +import azlmbr.components as components import azlmbr.legacy.general as general import azlmbr.bus as bus -import azlmbr.entity as EntityId +import azlmbr.entity as entity import azlmbr.editor as editor import azlmbr.math as math import azlmbr.paths @@ -83,18 +84,12 @@ class TestDynamicSliceInstanceSpawnerEmbeddedEditor(EditorTestHelper): self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances") self.test_success = self.test_success and num_found == num_expected_instances - # 5) Create a new entity with a Camera component for testing in the launcher + # 5) Move the default Camera entity for testing in the launcher cam_position = math.Vector3(512.0, 500.0, 35.0) - camera_component = ["Camera"] - new_entity_id2 = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", cam_position, EntityId.EntityId() - ) - if new_entity_id2.IsValid(): - self.log("Camera entity created") - camera_entity = hydra.Entity("Camera Entity", new_entity_id2) - camera_entity.components = [] - for component in camera_component: - camera_entity.components.append(hydra.add_component(component, new_entity_id2)) + search_filter = entity.SearchFilter() + search_filter.names = ["Camera"] + search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) + components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) # 6) Save and export to engine general.save_level() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py index 892549d414..70030ff359 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py @@ -11,7 +11,8 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__))) import azlmbr.legacy.general as general import azlmbr.asset as asset import azlmbr.bus as bus -import azlmbr.entity as EntityId +import azlmbr.components as components +import azlmbr.entity as entity import azlmbr.editor as editor import azlmbr.math as math import azlmbr.paths @@ -68,7 +69,7 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper): veg_area_required_components = ["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List", "Script Canvas"] new_entity_id = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId() + bus.Broadcast, "CreateNewEntityAtPosition", entity_position, entity.EntityId() ) if new_entity_id.IsValid(): self.log("Spawner entity created") @@ -106,18 +107,12 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper): self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances") self.test_success = self.test_success and num_found == num_expected_instances - # 5) Create a new entity with a Camera component for testing in the launcher - entity_position = math.Vector3(512.0, 500.0, 35.0) - camera_component = ["Camera"] - new_entity_id2 = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId() - ) - if new_entity_id2.IsValid(): - self.log("Camera entity created") - camera_entity = hydra.Entity("Camera Entity", new_entity_id2) - camera_entity.components = [] - for component in camera_component: - camera_entity.components.append(hydra.add_component(component, new_entity_id2)) + # 5) Move the default Camera entity for testing in the launcher + cam_position = math.Vector3(512.0, 500.0, 35.0) + search_filter = entity.SearchFilter() + search_filter.names = ["Camera"] + search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) + components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) # 6) Save and export to engine general.save_level() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py index c4dfbbf4fe..3543b4c23c 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py @@ -18,9 +18,9 @@ import azlmbr.areasystem as areasystem import azlmbr.legacy.general as general import azlmbr import azlmbr.bus as bus -import azlmbr.editor as editor +import azlmbr.components as components import azlmbr.math as math -import azlmbr.entity as EntityId +import azlmbr.entity as entity import azlmbr.paths sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) @@ -134,20 +134,14 @@ class TestVegLayerBlenderCreated(EditorTestHelper): purple_count += 1 self.test_success = pink_count == purple_count and (pink_count + purple_count == num_expected) and self.test_success - # 5) Create a new entity with a Camera component for testing in the launcher - entity_position = math.Vector3(500.0, 500.0, 47.0) - rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0)) - camera_component = ["Camera"] - camera_id = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId() - ) - if camera_id.IsValid(): - self.log("Camera entity created") - camera_entity = hydra.Entity("Camera Entity", camera_id) - camera_entity.components = [] - for component in camera_component: - camera_entity.components.append(hydra.add_component(component, camera_id)) - azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", camera_id, rot_degrees_vector) + # 5) Move the default Camera entity for testing in the launcher + cam_position = math.Vector3(500.0, 500.0, 47.0) + cam_rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0)) + search_filter = entity.SearchFilter() + search_filter.names = ["Camera"] + search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) + components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) + azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", search_entity_ids[0], cam_rot_degrees_vector) # 6) Save and export level general.save_level() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py index 0224f6bc0a..fb1ac5a5ce 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py @@ -34,8 +34,8 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper): :return: None """ - PREPROCESS_INSTANCE_COUNT = 425 - POSTPROCESS_INSTANCE_COUNT = 430 + PREPROCESS_INSTANCE_COUNT = 21 + POSTPROCESS_INSTANCE_COUNT = 19 # Create empty level self.test_success = self.create_level( @@ -56,7 +56,6 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper): vegetation_entity.add_component("Vegetation Altitude Filter") vegetation_entity.add_component("Vegetation Position Modifier") - # Create a child entity under vegetation area child_entity = hydra.Entity("child_entity") components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"] @@ -66,29 +65,13 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper): vegetation_entity.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", child_entity.id) vegetation_entity.get_set_test(4, "Configuration|Position Y|Gradient|Gradient Entity Id", child_entity.id) - # Set the min and max values for Altitude Filter - vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 32.0) - vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 35.0) + vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 34.0) + vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 38.0) # Add entity with Mesh to replicate creation of hills and a flat surface to plant on dynveg.create_surface_entity("Flat Surface", position, 32.0, 32.0, 1.0) - hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0, 4.0, 4.0) - - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") + hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0) # Set the filter stage to preprocess and postprocess respectively and verify instance count vegetation_entity.get_set_test(0, "Configuration|Filter Stage", 1) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py index c99d180253..4752aeddbc 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py @@ -13,7 +13,7 @@ import azlmbr.legacy.general as general import azlmbr.math as math sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from automatedtesting_shared.editor_test_helper import EditorTestHelper +from editor_python_test_tools.editor_test_helper import EditorTestHelper from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py index d23f811f58..89367ca475 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py @@ -82,22 +82,7 @@ class test_MeshBlocker_InstancesBlockedByMesh(EditorTestHelper): bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(), False) blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", cubeId) - components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(2.0, 2.0, 2.0)) - - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") + components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 2.0) # Verify spawned instance counts are accurate after addition of Blocker Entity num_expected = 160 # Number of "PurpleFlower"s that plant on a 10 x 10 surface minus 2m blocker cube diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py index ad57f80776..4a3edcd0e9 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py @@ -88,24 +88,9 @@ class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorTestHelper): bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(), False) blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_id) - components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(5.0, 5.0, 5.0)) + components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 5.0) components.TransformBus(bus.Event, "SetLocalRotation", blocker_entity.id, math.Vector3(0.0, y_rotation, 0.0)) - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") - # 5) Adjust the height Max percentage values of blocker blocker_entity.get_set_test(0, "Configuration|Mesh Height Percent Max", 0.8) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py index 053c4ccbfd..eb74a5a144 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py @@ -90,7 +90,6 @@ class TestDynamicSliceInstanceSpawner(object): @pytest.mark.SUITE_periodic @pytest.mark.dynveg_area @pytest.mark.parametrize("launcher_platform", ['windows']) - @pytest.mark.skip # ATOM-14703 def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level, remote_console_instance, project, launcher_platform): @@ -126,7 +125,6 @@ class TestDynamicSliceInstanceSpawner(object): @pytest.mark.SUITE_periodic @pytest.mark.dynveg_area @pytest.mark.parametrize("launcher_platform", ['windows']) - @pytest.mark.skip # ATOM-14703 def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level, remote_console_instance, project, launcher_platform): diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py index 3c16420a30..2620a7d50a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py @@ -68,7 +68,6 @@ class TestLayerBlender(object): "Entity has a Box Shape component", "Blender Configuration|Vegetation Areas: SUCCESS", "Blender Box Shape|Box Configuration|Dimensions: SUCCESS", - "Camera entity created", "LayerBlender_E2E_Editor: result=SUCCESS" ] @@ -85,12 +84,11 @@ class TestLayerBlender(object): @pytest.mark.BAT @pytest.mark.SUITE_periodic @pytest.mark.dynveg_area - @pytest.mark.xfail @pytest.mark.parametrize("launcher_platform", ['windows']) def test_LayerBlender_E2E_Launcher(self, workspace, project, launcher, level, remote_console_instance, launcher_platform): - launcher.args.extend(["-NullRenderer"]) + launcher.args.extend(["-rhi=Null"]) launcher.start() assert launcher.is_alive(), "Launcher failed to start" diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py index 410bdbafed..2af848ffb1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py @@ -121,7 +121,7 @@ class TestLayerSpawner(object): @pytest.mark.test_case_id("C30000751") @pytest.mark.SUITE_sandbox @pytest.mark.dynveg_misc - @pytest.mark.skip # ATOM-14828 + @pytest.mark.skip # https://github.com/o3de/o3de/issues/2038 def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, editor, level, launcher_platform): expected_lines = [ @@ -136,5 +136,6 @@ class TestLayerSpawner(object): editor, "LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py", expected_lines, - cfg_args=[level] + cfg_args=[level], + null_renderer=False ) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py index 515009cb3a..09d4746fa6 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py @@ -34,7 +34,7 @@ def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z return surface_entity -def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y, scale_z): +def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale): # Creates an entity with the assigned mesh_asset as the specified scale and sets up as a planting surface mesh_asset_path = os.path.join("models", "sphere.azmodel") mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(), @@ -47,7 +47,7 @@ def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y, if surface_entity.id.IsValid(): print(f"'{surface_entity.name}' created") hydra.get_set_test(surface_entity, 0, "Controller|Configuration|Mesh Asset", mesh_asset) - components.TransformBus(bus.Event, "SetLocalScale", surface_entity.id, math.Vector3(scale_x, scale_y, scale_z)) + components.TransformBus(bus.Event, "SetLocalUniformScale", surface_entity.id, uniform_scale) return surface_entity diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt index 73af69b93a..17202acc29 100644 --- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -5,6 +5,13 @@ # if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + + include(${LY_ROOT_FOLDER}/Code/Tools/SerializeContextTools/Platform/${PAL_PLATFORM_NAME}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) + if (PAL_TRAIT_BUILD_SERIALIZECONTEXTTOOLS) + list(APPEND additional_dependencies AZ::SerializeContextTools) # test_CLITool_SerializeContextTools depends on it + endif() + list(APPEND additional_dependencies AZ::AssetBundlerBatch) # test_CLITool_AssetBundlerBatch_Works depends on it + ly_add_pytest( NAME AutomatedTesting::SmokeTest TEST_SUITE smoke @@ -18,6 +25,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) Legacy::Editor AutomatedTesting.GameLauncher AutomatedTesting.Assets + ${aditional_dependencies} COMPONENT Smoke ) diff --git a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas b/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas index f4ca23b882..10c40fbb9f 100644 --- a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas +++ b/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas @@ -742,14 +742,14 @@ - + - + diff --git a/AutomatedTesting/Objects/Characters/Jack/Jack.fbx.assetinfo b/AutomatedTesting/Objects/Characters/Jack/Jack.fbx.assetinfo deleted file mode 100644 index 14b860fcd4..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/Jack.fbx.assetinfo +++ /dev/null @@ -1,691 +0,0 @@ -{ - "values": [ - { - "$type": "ActorGroup", - "name": "jack", - "selectedRootBone": "RootNode.LOD_Group_1.LOD_0", - "id": "{B7194F91-D8A1-5D5D-AC6D-DDEBC087D80D}", - "rules": { - "rules": [ - { - "$type": "{3CB103B3-CEAF-49D7-A9DC-5A31E2DF15E4} LodRule", - "nodeSelectionList": [ - { - "selectedNodes": [ - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_upLegRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_upLegRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__RHand2Aim_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:l_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__L_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeTargetLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeWeightLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:r_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__R_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeTargetRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeWeightRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:Bip01__CustomStart", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.Jack:Bip01__RHand2Aim_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__RHand2Aim_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:l_ball.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__L_Heel.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeTargetLeft.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeWeightLeft.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:r_ball.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__R_Heel.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeTargetRight.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeWeightRight.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.Jack:head", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:Bip01__CustomStart.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.Jack:Bip01__RHand2Aim_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.Jack:head.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_upArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_upArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_loArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_loArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.Jack:l_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.Jack:l_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.Jack:l_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.Jack:r_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.Jack:r_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.Jack:r_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.Jack:l_thumb3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.Jack:l_index3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.Jack:l_mid3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.Jack:l_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.Jack:l_pinky3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.Jack:r_thumb3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.Jack:r_index3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.Jack:r_mid3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.Jack:r_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.Jack:r_pinky3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.Jack:l_ring3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.Jack:l_pinky3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.Jack:r_ring3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.Jack:r_pinky3.transform", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh" - ], - "unselectedNodes": [ - "RootNode", - "RootNode.LOD_Group_1", - "RootNode.LOD_Group_1.LOD_0", - "RootNode.LOD_Group_1.LOD_1", - "RootNode.LOD_Group_1.LOD_2", - "RootNode.LOD_Group_1.LOD_3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.Jack:jack" - ], - "lodLevel": 1 - }, - { - "selectedNodes": [ - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_upLegRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_upLegRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__RHand2Aim_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:l_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__L_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeTargetLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeWeightLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:r_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__R_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeTargetRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeWeightRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:Bip01__CustomStart", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.Jack:Bip01__RHand2Aim_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__RHand2Aim_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:l_ball.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__L_Heel.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeTargetLeft.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeWeightLeft.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:r_ball.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__R_Heel.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeTargetRight.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeWeightRight.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.Jack:head", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:Bip01__CustomStart.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.Jack:Bip01__RHand2Aim_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.Jack:head.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_upArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_upArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_loArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_loArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.Jack:l_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.Jack:l_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.Jack:l_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.Jack:r_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.Jack:r_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.Jack:r_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.Jack:l_thumb3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.Jack:l_index3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.Jack:l_mid3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.Jack:l_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.Jack:l_pinky3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.Jack:r_thumb3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.Jack:r_index3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.Jack:r_mid3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.Jack:r_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.Jack:r_pinky3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.Jack:l_ring3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.Jack:l_pinky3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.Jack:r_ring3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.Jack:r_pinky3.transform", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh" - ], - "unselectedNodes": [ - "RootNode", - "RootNode.LOD_Group_1", - "RootNode.LOD_Group_1.LOD_0", - "RootNode.LOD_Group_1.LOD_1", - "RootNode.LOD_Group_1.LOD_2", - "RootNode.LOD_Group_1.LOD_3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.Jack:jack" - ], - "lodLevel": 2 - }, - { - "selectedNodes": [ - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_upLegRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_upLegRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__RHand2Aim_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:l_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__L_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeTargetLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeWeightLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:r_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__R_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeTargetRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeWeightRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:Bip01__CustomStart", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.Jack:Bip01__RHand2Aim_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__RHand2Aim_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:l_ball.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__L_Heel.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeTargetLeft.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeWeightLeft.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:r_ball.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__R_Heel.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeTargetRight.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeWeightRight.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.Jack:head", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:Bip01__CustomStart.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.Jack:Bip01__RHand2Aim_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.Jack:head.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_upArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_upArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_loArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_loArmRoll.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.Jack:l_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.Jack:l_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.Jack:l_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.Jack:r_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.Jack:r_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.Jack:r_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKBlend.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKTarget.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.Jack:l_thumb3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.Jack:l_index3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.Jack:l_mid3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.Jack:l_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.Jack:l_pinky3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.Jack:r_thumb3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.Jack:r_index3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.Jack:r_mid3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.Jack:r_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.Jack:r_pinky3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.Jack:l_ring3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.Jack:l_pinky3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.Jack:r_ring3.transform", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.Jack:r_pinky3.transform", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh" - ], - "unselectedNodes": [ - "RootNode", - "RootNode.LOD_Group_1", - "RootNode.LOD_Group_1.LOD_0", - "RootNode.LOD_Group_1.LOD_1", - "RootNode.LOD_Group_1.LOD_2", - "RootNode.LOD_Group_1.LOD_3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh.Jack:jack", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.SkinWeight_0", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.map1", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh.Jack:jack" - ], - "lodLevel": 3 - } - ] - }, - { - "$type": "TangentsRule" - }, - { - "$type": "SkinRule" - }, - { - "$type": "MaterialRule" - }, - { - "$type": "MetaDataRule", - "metaData": "AdjustActor -actorID $(ACTORID) -name \"Jack\"\r\nActorSetCollisionMeshes -actorID $(ACTORID) -lod 0 -nodeList \"\"\r\nAdjustActor -actorID $(ACTORID) -nodesExcludedFromBounds \"\" -nodeAction \"select\"\r\nAdjustActor -actorID $(ACTORID) -nodeAction \"replace\" -attachmentNodes \"\"\r\nAdjustActor -actorID $(ACTORID) -motionExtractionNodeName \"Jack:jack_root\"\r\n" - }, - { - "$type": "CoordinateSystemRule" - } - ] - } - }, - { - "$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup", - "name": "Jack", - "nodeSelectionList": { - "selectedNodes": [ - {}, - "RootNode", - "RootNode.LOD_Group_1", - "RootNode.LOD_Group_1.LOD_0", - "RootNode.LOD_Group_1.LOD_1", - "RootNode.LOD_Group_1.LOD_2", - "RootNode.LOD_Group_1.LOD_3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root", - "RootNode.LOD_Group_1.LOD_1.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_2.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_3.Jack:jack_mesh", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_upLegRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__RHand2Aim_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:l_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__L_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeTargetLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:l_upLeg.Jack:l_loLeg.Jack:l_ankle.Jack:Bip01__planeWeightLeft", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:r_ball", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__R_Heel", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeTargetRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:r_upLeg.Jack:r_loLeg.Jack:r_ankle.Jack:Bip01__planeWeightRight", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:Bip01__CustomStart", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:Bip01__CustomAim.Jack:Bip01__RHand2Aim_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:neck.Jack:head", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_upArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_loArmRoll", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_handProp.Jack:Bip01__RHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKBlend", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_handProp.Jack:Bip01__LHand2Weapon_IKTarget", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_thumb1.Jack:l_thumb2.Jack:l_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_index1.Jack:l_index2.Jack:l_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_mid1.Jack:l_mid2.Jack:l_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_thumb1.Jack:r_thumb2.Jack:r_thumb3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_index1.Jack:r_index2.Jack:r_index3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_mid1.Jack:r_mid2.Jack:r_mid3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_ring1.Jack:l_ring2.Jack:l_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:l_shldr.Jack:l_upArm.Jack:l_loArm.Jack:l_hand.Jack:l_metacarpal.Jack:l_pinky1.Jack:l_pinky2.Jack:l_pinky3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_ring1.Jack:r_ring2.Jack:r_ring3", - "RootNode.LOD_Group_1.LOD_0.Jack:jack_root.Jack:Bip01__pelvis.Jack:spine1.Jack:spine2.Jack:spine3.Jack:r_shldr.Jack:r_upArm.Jack:r_loArm.Jack:r_hand.Jack:r_metacarpal.Jack:r_pinky1.Jack:r_pinky2.Jack:r_pinky3" - ] - }, - "rules": { - "rules": [ - { - "$type": "SkinRule" - }, - { - "$type": "MaterialRule" - } - ] - }, - "id": "{8D605093-F5E6-476C-ABD6-42304F53F1F0}" - } - ] -} \ No newline at end of file diff --git a/AutomatedTesting/Objects/Characters/Jack/enemy.cdf b/AutomatedTesting/Objects/Characters/Jack/enemy.cdf deleted file mode 100644 index c3225e07b3..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/enemy.cdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:da2f0e0a3100ff1b46534d4ca314e4ceabc14a8cc894070dd18a51feb7eba390 -size 290 diff --git a/AutomatedTesting/Objects/Characters/Jack/enemy_runner.cdf b/AutomatedTesting/Objects/Characters/Jack/enemy_runner.cdf deleted file mode 100644 index 00c03ea1b8..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/enemy_runner.cdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a3eac079f5ee483917a2cab9f8726a0e66ee6ed8cb9f966d872fe3dc0bf287c6 -size 304 diff --git a/AutomatedTesting/Objects/Characters/Jack/enemy_tank.cdf b/AutomatedTesting/Objects/Characters/Jack/enemy_tank.cdf deleted file mode 100644 index 1055e64b28..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/enemy_tank.cdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1b610ceb7b8b42d4890d2f9ca6e0dec79d8361bfa8e1d02517ac3c336259e065 -size 300 diff --git a/AutomatedTesting/Objects/Characters/Jack/jack.cdf b/AutomatedTesting/Objects/Characters/Jack/jack.cdf deleted file mode 100644 index ba2d13ef84..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/jack.cdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58b71612088d2eca7465680c8914d9e42ecf343fc37c835ebc61cd9a23de7b4e -size 288 diff --git a/AutomatedTesting/Objects/Characters/Jack/jack.skin b/AutomatedTesting/Objects/Characters/Jack/jack.skin deleted file mode 100644 index 68d1d95361..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/jack.skin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5d144788bbd3229481b4e874a88de31030377ac8396bb2c00bd05180083498bd -size 3558736 diff --git a/AutomatedTesting/Objects/Characters/Jack/jack_LOD1.skin b/AutomatedTesting/Objects/Characters/Jack/jack_LOD1.skin deleted file mode 100644 index 79650c60dc..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/jack_LOD1.skin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6a198f9b888af5e4cc240319bfe5ee99b35919081e6ef37e14fc43dcad74c9d5 -size 2416608 diff --git a/AutomatedTesting/Objects/Characters/Jack/jack_LOD2.skin b/AutomatedTesting/Objects/Characters/Jack/jack_LOD2.skin deleted file mode 100644 index da1f74af86..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/jack_LOD2.skin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:870b14ba99d6006d936cc84503549450709db541f2a365aa55e3e05709d0822a -size 1355768 diff --git a/AutomatedTesting/Objects/Characters/Jack/jack_LOD3.skin b/AutomatedTesting/Objects/Characters/Jack/jack_LOD3.skin deleted file mode 100644 index a82716f115..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/jack_LOD3.skin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4aa1cf59f3b59afa75caa487630ef9769c5f3bd8ec466b031fa0ce3d7fbc0d31 -size 856508 diff --git a/AutomatedTesting/Objects/Characters/Jack/jack_root.chr b/AutomatedTesting/Objects/Characters/Jack/jack_root.chr deleted file mode 100644 index f2e346a11a..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/jack_root.chr +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43a74e2e7c0d90593f0c3e568b1a9fbfb781fb283c0619921ca1ad67cc2cde2a -size 59540 diff --git a/AutomatedTesting/Objects/Characters/Jack/jack_root.chrparams b/AutomatedTesting/Objects/Characters/Jack/jack_root.chrparams deleted file mode 100644 index 30c8c5f179..0000000000 --- a/AutomatedTesting/Objects/Characters/Jack/jack_root.chrparams +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ca664e801edb91b7fe60b0c93a41f4553e5a85cab2729b00cdbf3adeade71a5 -size 5831 diff --git a/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas b/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas index b9f438a4f3..ffdac5dd8c 100644 --- a/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas +++ b/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas @@ -1045,14 +1045,14 @@ - + - + diff --git a/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas b/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas index 7db4f3a35c..4954eb4684 100644 --- a/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas +++ b/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas @@ -1085,14 +1085,14 @@ - + - + diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 3f86260f8d..c2f16a84b1 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -1896,7 +1896,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly) if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame) { - CUndo undo("Move Camera"); + AzToolsFramework::ScopedUndoBatch undo("Move Camera"); if (bMoveOnly) { // specify eObjectUpdateFlags_UserInput so that an undo command gets logged @@ -1932,7 +1932,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly) if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame) { - CUndo undo("Move Camera"); + AzToolsFramework::ScopedUndoBatch undo("Move Camera"); if (bMoveOnly) { AZ::TransformBus::Event( @@ -1945,6 +1945,8 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly) m_viewEntityId, &AZ::TransformInterface::SetWorldTM, LYTransformToAZTransform(camMatrix)); } + + AzToolsFramework::ToolsApplicationRequestBus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::AddDirtyEntity, m_viewEntityId); } else { diff --git a/Code/Editor/Platform/Mac/gui_info.plist b/Code/Editor/Platform/Mac/gui_info.plist index 0ec7b59e98..5b5f94e977 100644 --- a/Code/Editor/Platform/Mac/gui_info.plist +++ b/Code/Editor/Platform/Mac/gui_info.plist @@ -5,7 +5,7 @@ CFBundleExecutable Editor CFBundleIdentifier - com.Amazon.Lumberyard.Editor + org.O3DE.Editor CFBundlePackageType APPL CFBundleSignature diff --git a/Code/Editor/Plugins/EditorCommon/CMakeLists.txt b/Code/Editor/Plugins/EditorCommon/CMakeLists.txt index 96d9cce5b7..048f77cd0c 100644 --- a/Code/Editor/Plugins/EditorCommon/CMakeLists.txt +++ b/Code/Editor/Plugins/EditorCommon/CMakeLists.txt @@ -46,4 +46,8 @@ ly_add_target( AZ::AzCore AZ::AzToolsFramework AZ::AzQtComponents + RUNTIME_DEPENDENCIES + AZ::AzCore + AZ::AzToolsFramework + AZ::AzQtComponents ) diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp index f4e4fed973..63ce446e97 100644 --- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp +++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp @@ -20,12 +20,12 @@ #include "ValidationHandler.h" #include +#include -#include "AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h" +#include #include #include #include -#include #include #include @@ -52,7 +52,7 @@ namespace ProjectSettingsTool PlatformEnabled(PlatformId::Ios) ? ProjectSettingsContainer::PlistInitVector({ ProjectSettingsContainer::PlatformAndPath - { PlatformId::Ios, m_projectRoot + PlatformResourcesFolder(PlatformId::Ios) } + { PlatformId::Ios, GetPlatformResource(PlatformId::Ios) } }) : ProjectSettingsContainer::PlistInitVector()) @@ -647,33 +647,38 @@ namespace ProjectSettingsTool // iOS can be disabled if the plist file is missing if (platformId == PlatformId::Ios) { - const AZStd::string filename = m_projectRoot + PlatformResourcesFolder(platformId); - return CFileUtil::FileExists(filename.c_str()); + AZStd::string plistPath = GetPlatformResource(platformId); + return !plistPath.empty(); } return true; } - const char* ProjectSettingsToolWindow::PlatformResourcesFolder(PlatformId platformId) + AZStd::string ProjectSettingsToolWindow::GetPlatformResource(PlatformId platformId) { if (platformId == PlatformId::Ios) { - const AZStd::string firstfilename = m_projectRoot + "/Gem/Resources/Platform/iOS/Info.plist"; - if (CFileUtil::FileExists(firstfilename.c_str())) - { - return "/Gem/Resources/Platform/iOS/Info.plist"; - } - else + const char* searchPaths[] = { + "Resources/Platform/iOS/Info.plist", + + // legacy paths + "Gem/Resources/Platform/iOS/Info.plist", + "Gem/Resources/IOSLauncher/Info.plist", + }; + + for (auto relPath : searchPaths) { - const AZStd::string filename = m_projectRoot + "/Gem/Resources/IOSLauncher/Info.plist"; - if (CFileUtil::FileExists(filename.c_str())) + AZ::IO::FixedMaxPath projectPlist{ m_projectRoot }; + projectPlist /= relPath; + + if (AZ::IO::SystemFile::Exists(projectPlist.c_str())) { - return "/Gem/Resources/IOSLauncher/Info.plist"; + return projectPlist.LexicallyNormal().String(); } } } - return nullptr; + return AZStd::string(); } #include diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h index 8979672f99..64a6646e7f 100644 --- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h +++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h @@ -137,8 +137,8 @@ namespace ProjectSettingsTool // returns true if the platform is enabled bool PlatformEnabled(PlatformId platformId); - // returns the resource folder - const char* PlatformResourcesFolder(PlatformId platformId); + // returns the main platform specific resource file e.g. for iOS it would be the Info.plist + AZStd::string GetPlatformResource(PlatformId platformId); // The ui for the window QScopedPointer m_ui; diff --git a/Code/Editor/ViewportTitleDlg.cpp b/Code/Editor/ViewportTitleDlg.cpp index 3090cf8e63..cb544ce5c0 100644 --- a/Code/Editor/ViewportTitleDlg.cpp +++ b/Code/Editor/ViewportTitleDlg.cpp @@ -868,7 +868,16 @@ void CViewportTitleDlg::OnBnClickedMuteAudio() void CViewportTitleDlg::UpdateMuteActionText() { - m_audioMuteAction->setText(gSettings.bMuteAudio ? tr("Un-mute Audio") : tr("Mute Audio")); + if (!Audio::AudioSystemRequestBus::HasHandlers()) + { + m_audioMuteAction->setEnabled(false); + m_audioMuteAction->setText(tr("Mute Audio: Enable Audio Gem")); + } + else + { + m_audioMuteAction->setEnabled(true); + m_audioMuteAction->setText(gSettings.bMuteAudio ? tr("Un-mute Audio") : tr("Mute Audio")); + } } void CViewportTitleDlg::OnHMDInitialized() diff --git a/Code/Framework/AzCore/AzCore/Debug/Trace.h b/Code/Framework/AzCore/AzCore/Debug/Trace.h index 594322f1f3..ecf951ae6c 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Trace.h +++ b/Code/Framework/AzCore/AzCore/Debug/Trace.h @@ -127,7 +127,7 @@ namespace AZ #define AZ_TraceFmtCompileTimeCheck(expression, isVaArgs, baseMsg, msg, msgVargs) \ { \ using namespace AZ::TraceInternal; \ - const auto& rTraceFmtCompileTimeCheckExpressionHelper = (expression); /* This is needed for edge cases for expressions containing lambdas, that were unsupported before C++20 */ \ + [[maybe_unused]] const auto& rTraceFmtCompileTimeCheckExpressionHelper = (expression); /* This is needed for edge cases for expressions containing lambdas, that were unsupported before C++20 */ \ constexpr ExpressionValidResult isValidTraceFmtResult = ExpressionIsValid::value; \ /* Assert different message depending whether it's const char array or if we have extra arguments */ \ static_assert(!(isVaArgs) ? isValidTraceFmtResult != ExpressionValidResult::Invalid_ConstCharArray : true, baseMsg " " msg); \ diff --git a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp index 46717440d5..82e230d54a 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp @@ -116,7 +116,7 @@ namespace AZ { const char* uuidString = nullptr; unsigned int uuidStringLength = 0; - if (dc.ReadArg(0, uuidString) && dc.ReadValue(1, uuidStringLength)) + if (dc.ReadArg(0, uuidString) && dc.ReadArg(1, uuidStringLength)) { dc.PushResult(Uuid(uuidString, uuidStringLength)); } diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp index b68b19ddda..0444c4ce2a 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp @@ -157,8 +157,11 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe lua_pop(l, 2); // pop the Class name and behaviorClass lua_pushnil(l); + + // iterate over the key/value pairs while (lua_next(l, -2) != 0) { + // if key: string value: function if (lua_isstring(l, -2) && lua_isfunction(l, -1)) { const char* name = lua_tostring(l, -2); @@ -167,6 +170,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe bool isRead = true; bool isWrite = true; + // check if there is a getter provided lua_getupvalue(l, -1, 1); if (lua_isnil(l, -1)) { @@ -174,6 +178,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe } lua_pop(l, 1); + // check if there is a setter provided lua_getupvalue(l, -1, 2); if (lua_isnil(l, -1)) { @@ -181,6 +186,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe } lua_pop(l, 1); + // enumerate the remaining property if (!enumProperty(&behaviorClass->m_typeId, name, isRead, isWrite, userData)) { lua_pop(l, 5); @@ -189,21 +195,30 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe } else { + // for any non-built in methods if (strncmp(name, "__", 2) != 0) { const char* dbgParamInfo = NULL; - lua_getupvalue(l, -1, 2); + + // attempt to get the name + bool popDebugName = lua_getupvalue(l, -1, 2) != nullptr; if (lua_isstring(l, -1)) { dbgParamInfo = lua_tostring(l, -1); } + // enumerate the method's parameters if (!enumMethod(&behaviorClass->m_typeId, name, dbgParamInfo, userData)) { lua_pop(l, 6); return; } - lua_pop(l, 1); // pop the DBG name + + // if we were able to get the name, pop it from the stack + if (popDebugName) + { + lua_pop(l, 1); + } } } } diff --git a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp index a654302da6..d61323f33e 100644 --- a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp +++ b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp @@ -7,9 +7,9 @@ */ #include -#include "AzCore/Component/Entity.h" -#include "AzCore/Asset/AssetManager.h" -#include "AzCore/Slice/SliceComponent.h" +#include +#include +#include namespace UnitTest { diff --git a/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp b/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp index 69bf6bb394..96810c20ec 100644 --- a/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp +++ b/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp @@ -279,14 +279,11 @@ namespace AZ return SystemFile::Exists(resolvedPath); } - void LocalFileIO::CheckInvalidWrite(const char* path) + void LocalFileIO::CheckInvalidWrite([[maybe_unused]] const char* path) { - (void)path; - #if defined(AZ_ENABLE_TRACING) const char* assetsAlias = GetAlias("@assets@"); - - if (((path) && (assetsAlias) && (azstrnicmp(path, assetsAlias, strlen(assetsAlias)) == 0))) + if (path && assetsAlias && AZ::IO::PathView(path).IsRelativeTo(assetsAlias)) { AZ_Error("FileIO", false, "You may not alter data inside the asset cache. Please check the call stack and consider writing into the source asset folder instead.\n" "Attempted write location: %s", path); diff --git a/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h b/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h index a1ec4a05f0..a122fe3133 100644 --- a/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h @@ -205,6 +205,25 @@ namespace AzFramework class InputDeviceImplementationRequest : public AZ::EBusTraits { public: + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests can be addressed to a specific InputDeviceId so that they are only + //! handled by one input device that has connected to the bus using that unique id, or they + //! can be broadcast to all input devices that have connected to the bus, regardless of id. + //! Connected input devices are ordered by their local player index from lowest to highest. + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ByIdAndOrdered; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests should be handled by only one input device connected to each id + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests can be addressed to a specific InputDeviceId + using BusIdType = InputDeviceId; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests are handled by connected devices in the order of local player index + using BusIdOrderCompare = AZStd::less; + //////////////////////////////////////////////////////////////////////////////////////////// //! Alias for the EBus implementation of this interface using Bus = AZ::EBus>; @@ -214,11 +233,12 @@ namespace AzFramework using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&); //////////////////////////////////////////////////////////////////////////////////////////// - //! Create a custom implementation for all the existing instances of this input device type. + //! Set a custom implementation for this input device type, either for a specific instance + //! by addressing the call to an InputDeviceId, or for all existing instances by broadcast. //! Passing InputDeviceType::Implementation::Create as the argument will create the default //! device implementation, while passing nullptr will delete any existing implementation. //! \param[in] createFunction Pointer to the function that will create the implementation. - virtual void CreateCustomImplementation(CreateFunctionType createFunction) = 0; + virtual void SetCustomImplementation(CreateFunctionType createFunction) = 0; }; //////////////////////////////////////////////////////////////////////////////////////////////// @@ -238,7 +258,7 @@ namespace AzFramework AZ_INLINE InputDeviceImplementationRequestHandler(InputDeviceType& inputDevice) : m_inputDevice(inputDevice) { - InputDeviceImplementationRequest::Bus::Handler::BusConnect(); + InputDeviceImplementationRequest::Bus::Handler::BusConnect(m_inputDevice.GetInputDeviceId()); } //////////////////////////////////////////////////////////////////////////////////////////// @@ -251,8 +271,8 @@ namespace AzFramework using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&); //////////////////////////////////////////////////////////////////////////////////////////// - //! \ref InputDeviceImplementationRequest::CreateCustomImplementation - AZ_INLINE void CreateCustomImplementation(CreateFunctionType createFunction) override + //! \ref InputDeviceImplementationRequest::SetCustomImplementation + AZ_INLINE void SetCustomImplementation(CreateFunctionType createFunction) override { AZStd::unique_ptr newImplementation; if (createFunction) diff --git a/Code/Framework/AzFramework/CMakeLists.txt b/Code/Framework/AzFramework/CMakeLists.txt index 1f53472ff8..2cfc5e4b89 100644 --- a/Code/Framework/AzFramework/CMakeLists.txt +++ b/Code/Framework/AzFramework/CMakeLists.txt @@ -52,3 +52,63 @@ ly_add_source_properties( PROPERTY COMPILE_DEFINITIONS VALUES TOUCHBENDING_LAYER_BIT=${LY_TOUCHBENDING_LAYER_BIT} ) + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) + + ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME}) + + ly_add_target( + NAME AzFrameworkTestShared STATIC + NAMESPACE AZ + FILES_CMAKE + Tests/framework_shared_tests_files.cmake + INCLUDE_DIRECTORIES + PUBLIC + Tests + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AzFramework + ) + + if(PAL_TRAIT_BUILD_HOST_TOOLS) + + ly_add_target( + NAME ProcessLaunchTest EXECUTABLE + NAMESPACE AZ + FILES_CMAKE + Tests/process_launch_test_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Tests + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AzFramework + ) + + ly_add_target( + NAME AzFramework.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE AZ + FILES_CMAKE + Tests/frameworktests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Tests + ${pal_dir} + BUILD_DEPENDENCIES + PRIVATE + AZ::AzFramework + AZ::AzTest + AZ::AzTestShared + AZ::AzFrameworkTestShared + RUNTIME_DEPENDENCIES + AZ::ProcessLaunchTest + ) + ly_add_googletest( + NAME AZ::AzFramework.Tests + ) + + endif() + +endif() \ No newline at end of file diff --git a/Code/Framework/Tests/Application.cpp b/Code/Framework/AzFramework/Tests/Application.cpp similarity index 100% rename from Code/Framework/Tests/Application.cpp rename to Code/Framework/AzFramework/Tests/Application.cpp diff --git a/Code/Framework/Tests/ArchiveCompressionTests.cpp b/Code/Framework/AzFramework/Tests/ArchiveCompressionTests.cpp similarity index 100% rename from Code/Framework/Tests/ArchiveCompressionTests.cpp rename to Code/Framework/AzFramework/Tests/ArchiveCompressionTests.cpp diff --git a/Code/Framework/Tests/ArchiveTests.cpp b/Code/Framework/AzFramework/Tests/ArchiveTests.cpp similarity index 100% rename from Code/Framework/Tests/ArchiveTests.cpp rename to Code/Framework/AzFramework/Tests/ArchiveTests.cpp diff --git a/Code/Framework/Tests/AssetCatalog.cpp b/Code/Framework/AzFramework/Tests/AssetCatalog.cpp similarity index 100% rename from Code/Framework/Tests/AssetCatalog.cpp rename to Code/Framework/AzFramework/Tests/AssetCatalog.cpp diff --git a/Code/Framework/Tests/AssetProcessorConnection.cpp b/Code/Framework/AzFramework/Tests/AssetProcessorConnection.cpp similarity index 100% rename from Code/Framework/Tests/AssetProcessorConnection.cpp rename to Code/Framework/AzFramework/Tests/AssetProcessorConnection.cpp diff --git a/Code/Framework/Tests/BehaviorEntityTests.cpp b/Code/Framework/AzFramework/Tests/BehaviorEntityTests.cpp similarity index 100% rename from Code/Framework/Tests/BehaviorEntityTests.cpp rename to Code/Framework/AzFramework/Tests/BehaviorEntityTests.cpp diff --git a/Code/Framework/Tests/BinToTextEncode.cpp b/Code/Framework/AzFramework/Tests/BinToTextEncode.cpp similarity index 100% rename from Code/Framework/Tests/BinToTextEncode.cpp rename to Code/Framework/AzFramework/Tests/BinToTextEncode.cpp diff --git a/Code/Framework/Tests/CameraInputTests.cpp b/Code/Framework/AzFramework/Tests/CameraInputTests.cpp similarity index 100% rename from Code/Framework/Tests/CameraInputTests.cpp rename to Code/Framework/AzFramework/Tests/CameraInputTests.cpp diff --git a/Code/Framework/Tests/CameraState.cpp b/Code/Framework/AzFramework/Tests/CameraState.cpp similarity index 100% rename from Code/Framework/Tests/CameraState.cpp rename to Code/Framework/AzFramework/Tests/CameraState.cpp diff --git a/Code/Framework/Tests/ClickDetectorTests.cpp b/Code/Framework/AzFramework/Tests/ClickDetectorTests.cpp similarity index 100% rename from Code/Framework/Tests/ClickDetectorTests.cpp rename to Code/Framework/AzFramework/Tests/ClickDetectorTests.cpp diff --git a/Code/Framework/Tests/CursorStateTests.cpp b/Code/Framework/AzFramework/Tests/CursorStateTests.cpp similarity index 100% rename from Code/Framework/Tests/CursorStateTests.cpp rename to Code/Framework/AzFramework/Tests/CursorStateTests.cpp diff --git a/Code/Framework/Tests/EntityContext.cpp b/Code/Framework/AzFramework/Tests/EntityContext.cpp similarity index 100% rename from Code/Framework/Tests/EntityContext.cpp rename to Code/Framework/AzFramework/Tests/EntityContext.cpp diff --git a/Code/Framework/Tests/FileIO.cpp b/Code/Framework/AzFramework/Tests/FileIO.cpp similarity index 100% rename from Code/Framework/Tests/FileIO.cpp rename to Code/Framework/AzFramework/Tests/FileIO.cpp diff --git a/Code/Framework/Tests/FileTagTests.cpp b/Code/Framework/AzFramework/Tests/FileTagTests.cpp similarity index 100% rename from Code/Framework/Tests/FileTagTests.cpp rename to Code/Framework/AzFramework/Tests/FileTagTests.cpp diff --git a/Code/Framework/Tests/FrameworkApplicationFixture.h b/Code/Framework/AzFramework/Tests/FrameworkApplicationFixture.h similarity index 100% rename from Code/Framework/Tests/FrameworkApplicationFixture.h rename to Code/Framework/AzFramework/Tests/FrameworkApplicationFixture.h diff --git a/Code/Framework/Tests/GenAppDescriptors.cpp b/Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp similarity index 94% rename from Code/Framework/Tests/GenAppDescriptors.cpp rename to Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp index dde3800895..069d3b35f2 100644 --- a/Code/Framework/Tests/GenAppDescriptors.cpp +++ b/Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp @@ -15,16 +15,16 @@ namespace UnitTest { using namespace AZ; - class SetRestoreFileIOBaseRAII + class FileIOBaseRAII { public: - SetRestoreFileIOBaseRAII(AZ::IO::FileIOBase& fileIO) + FileIOBaseRAII(AZ::IO::FileIOBase& fileIO) : m_prevFileIO(AZ::IO::FileIOBase::GetInstance()) { AZ::IO::FileIOBase::SetInstance(&fileIO); } - ~SetRestoreFileIOBaseRAII() + ~FileIOBaseRAII() { AZ::IO::FileIOBase::SetInstance(m_prevFileIO); } @@ -102,7 +102,7 @@ namespace UnitTest TEST_F(GenAppDescriptors, Test) { AZ::IO::LocalFileIO fileIO; - SetRestoreFileIOBaseRAII restoreFileIOScope(fileIO); + FileIOBaseRAII restoreFileIOScope(fileIO); run(); } } diff --git a/Code/Framework/Tests/InputTests.cpp b/Code/Framework/AzFramework/Tests/InputTests.cpp similarity index 100% rename from Code/Framework/Tests/InputTests.cpp rename to Code/Framework/AzFramework/Tests/InputTests.cpp diff --git a/Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h b/Code/Framework/AzFramework/Tests/Mocks/MockSpawnableEntitiesInterface.h similarity index 100% rename from Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h rename to Code/Framework/AzFramework/Tests/Mocks/MockSpawnableEntitiesInterface.h diff --git a/Code/Framework/Tests/NativeWindow.cpp b/Code/Framework/AzFramework/Tests/NativeWindow.cpp similarity index 100% rename from Code/Framework/Tests/NativeWindow.cpp rename to Code/Framework/AzFramework/Tests/NativeWindow.cpp diff --git a/Code/Framework/Tests/OctreePerformanceTests.cpp b/Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp similarity index 100% rename from Code/Framework/Tests/OctreePerformanceTests.cpp rename to Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp diff --git a/Code/Framework/Tests/OctreeTests.cpp b/Code/Framework/AzFramework/Tests/OctreeTests.cpp similarity index 100% rename from Code/Framework/Tests/OctreeTests.cpp rename to Code/Framework/AzFramework/Tests/OctreeTests.cpp diff --git a/Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h b/Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h similarity index 100% rename from Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h rename to Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h diff --git a/Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Android/platform_android_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Android/platform_android_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Android/platform_android_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Android/platform_android_files.cmake diff --git a/Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h b/Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h similarity index 100% rename from Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h rename to Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h diff --git a/Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Linux/platform_linux_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Linux/platform_linux_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Linux/platform_linux_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Linux/platform_linux_files.cmake diff --git a/Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h b/Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h similarity index 100% rename from Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h rename to Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h diff --git a/Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Mac/platform_mac_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Mac/platform_mac_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Mac/platform_mac_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Mac/platform_mac_files.cmake diff --git a/Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h b/Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h similarity index 100% rename from Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h rename to Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h diff --git a/Code/Framework/Tests/Platform/Windows/platform_windows_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Windows/platform_windows_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Windows/platform_windows_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Windows/platform_windows_files.cmake diff --git a/Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h b/Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h similarity index 100% rename from Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h rename to Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h diff --git a/Code/Framework/Tests/Platform/iOS/platform_ios_files.cmake b/Code/Framework/AzFramework/Tests/Platform/iOS/platform_ios_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/iOS/platform_ios_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/iOS/platform_ios_files.cmake diff --git a/Code/Framework/Tests/PlatformHelper.cpp b/Code/Framework/AzFramework/Tests/PlatformHelper.cpp similarity index 100% rename from Code/Framework/Tests/PlatformHelper.cpp rename to Code/Framework/AzFramework/Tests/PlatformHelper.cpp diff --git a/Code/Framework/Tests/ProcessLaunchMain.cpp b/Code/Framework/AzFramework/Tests/ProcessLaunchMain.cpp similarity index 100% rename from Code/Framework/Tests/ProcessLaunchMain.cpp rename to Code/Framework/AzFramework/Tests/ProcessLaunchMain.cpp diff --git a/Code/Framework/Tests/ProcessLaunchParseTests.cpp b/Code/Framework/AzFramework/Tests/ProcessLaunchParseTests.cpp similarity index 100% rename from Code/Framework/Tests/ProcessLaunchParseTests.cpp rename to Code/Framework/AzFramework/Tests/ProcessLaunchParseTests.cpp diff --git a/Code/Framework/Tests/Scene.cpp b/Code/Framework/AzFramework/Tests/Scene.cpp similarity index 99% rename from Code/Framework/Tests/Scene.cpp rename to Code/Framework/AzFramework/Tests/Scene.cpp index 32a0958692..57293c9d77 100644 --- a/Code/Framework/Tests/Scene.cpp +++ b/Code/Framework/AzFramework/Tests/Scene.cpp @@ -9,7 +9,6 @@ AZ_PUSH_DISABLE_WARNING(, "-Wdelete-non-virtual-dtor") -#include #include #include #include diff --git a/Code/Framework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp similarity index 100% rename from Code/Framework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp rename to Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp diff --git a/Code/Framework/Tests/Utils/Utils.cpp b/Code/Framework/AzFramework/Tests/Utils/Utils.cpp similarity index 100% rename from Code/Framework/Tests/Utils/Utils.cpp rename to Code/Framework/AzFramework/Tests/Utils/Utils.cpp diff --git a/Code/Framework/Tests/Utils/Utils.h b/Code/Framework/AzFramework/Tests/Utils/Utils.h similarity index 100% rename from Code/Framework/Tests/Utils/Utils.h rename to Code/Framework/AzFramework/Tests/Utils/Utils.h diff --git a/Code/Framework/Tests/framework_shared_tests_files.cmake b/Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake similarity index 90% rename from Code/Framework/Tests/framework_shared_tests_files.cmake rename to Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake index 72ffdf0043..5ee7ff644b 100644 --- a/Code/Framework/Tests/framework_shared_tests_files.cmake +++ b/Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake @@ -9,4 +9,5 @@ set(FILES Mocks/MockSpawnableEntitiesInterface.h Utils/Utils.h Utils/Utils.cpp + FrameworkApplicationFixture.h ) diff --git a/Code/Framework/Tests/frameworktests_files.cmake b/Code/Framework/AzFramework/Tests/frameworktests_files.cmake similarity index 56% rename from Code/Framework/Tests/frameworktests_files.cmake rename to Code/Framework/AzFramework/Tests/frameworktests_files.cmake index 398bb8f45b..25c56f5a71 100644 --- a/Code/Framework/Tests/frameworktests_files.cmake +++ b/Code/Framework/AzFramework/Tests/frameworktests_files.cmake @@ -6,44 +6,28 @@ # set(FILES - ../AzCore/Tests/Main.cpp + ../../AzCore/Tests/Main.cpp Spawnable/SpawnableEntitiesManagerTests.cpp ArchiveCompressionTests.cpp ArchiveTests.cpp BehaviorEntityTests.cpp BinToTextEncode.cpp - ComponentAddRemove.cpp - ComponentAdapterTests.cpp CameraInputTests.cpp ClickDetectorTests.cpp CursorStateTests.cpp EntityContext.cpp - EntityTestbed.h - FileFunc.cpp FileIO.cpp FileTagTests.cpp - FrameworkApplicationFixture.h GenAppDescriptors.cpp - GenericComponentWrapperTest.cpp - InstanceDataHierarchy.cpp OctreePerformanceTests.cpp OctreeTests.cpp - Slices.cpp - Script/ScriptComponentTests.cpp - Script/ScriptEntityTests.cpp AssetCatalog.cpp AssetProcessorConnection.cpp NativeWindow.cpp - TransformComponent.cpp - SQLiteConnectionTests.cpp ProcessLaunchParseTests.cpp Application.cpp PlatformHelper.cpp Scene.cpp - EntityOwnershipService/EntityOwnershipServiceTestFixture.h - EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp - EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp - EntityOwnershipService/SliceEntityOwnershipTests.cpp CameraState.cpp InputTests.cpp ) diff --git a/Code/Framework/Tests/process_launch_test_files.cmake b/Code/Framework/AzFramework/Tests/process_launch_test_files.cmake similarity index 100% rename from Code/Framework/Tests/process_launch_test_files.cmake rename to Code/Framework/AzFramework/Tests/process_launch_test_files.cmake diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h index 51aecbd8e7..6dd6b0b448 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h @@ -63,6 +63,9 @@ namespace AzToolsFramework //! Signal the Python handler to stop virtual bool StopPython(bool silenceWarnings = false) = 0; + //! Query to determine if the Python VM has been initialized indicating an active state + virtual bool IsPythonActive() = 0; + //! Determines if the caller needs to wait for the Python VM to initialize (non-main thread only) virtual void WaitForInitialization() {} diff --git a/Code/Framework/AzToolsFramework/CMakeLists.txt b/Code/Framework/AzToolsFramework/CMakeLists.txt index b2a9690948..9a54ee5226 100644 --- a/Code/Framework/AzToolsFramework/CMakeLists.txt +++ b/Code/Framework/AzToolsFramework/CMakeLists.txt @@ -76,6 +76,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE AZ::AzTestShared 3rdParty::Qt::Test + AZ::AzFrameworkTestShared AZ::AzToolsFramework AZ::AzToolsFrameworkTestCommon AZ::AzManipulatorTestFramework.Static diff --git a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp index 4335e42d62..71b86f6ef4 100644 --- a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include namespace UnitTest { @@ -72,7 +74,7 @@ namespace UnitTest void CreateArchiveFolder( QString archiveFolderName, QStringList fileList ) { - QDir tempPath = QDir(m_tempDir.path()).filePath(archiveFolderName); + QDir tempPath = QDir(m_tempDir.GetDirectory()).filePath(archiveFolderName); for (const auto& thisFile : fileList) { @@ -88,12 +90,12 @@ namespace UnitTest QString GetArchivePath() { - return QDir(m_tempDir.path()).filePath("TestArchive.pak"); + return QDir(m_tempDir.GetDirectory()).filePath("TestArchive.pak"); } QString GetArchiveFolder() { - return QDir(m_tempDir.path()).filePath(GetArchiveFolderName()); + return QDir(m_tempDir.GetDirectory()).filePath(GetArchiveFolderName()); } bool CreateArchive() @@ -111,6 +113,11 @@ namespace UnitTest // 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); + + if (auto fileIoBase = AZ::IO::FileIOBase::GetInstance(); fileIoBase != nullptr) + { + fileIoBase->SetAlias("@assets@", m_tempDir.GetDirectory()); + } } void TearDown() override @@ -120,7 +127,7 @@ namespace UnitTest } AZStd::unique_ptr m_app; - QTemporaryDir m_tempDir {QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).filePath("ArchiveTests-")}; + UnitTest::ScopedTemporaryDirectory m_tempDir; }; #if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS @@ -129,7 +136,7 @@ namespace UnitTest TEST_F(ArchiveTest, CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated) #endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { - EXPECT_TRUE(m_tempDir.isValid()); + EXPECT_TRUE(m_tempDir.IsValid()); CreateArchiveFolder(); bool createResult = CreateArchive(); @@ -143,7 +150,7 @@ namespace UnitTest TEST_F(ArchiveTest, ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound) #endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { - EXPECT_TRUE(m_tempDir.isValid()); + EXPECT_TRUE(m_tempDir.IsValid()); CreateArchiveFolder(); EXPECT_EQ(CreateArchive(), true); @@ -203,7 +210,9 @@ namespace UnitTest } bool catalogCreated{ false }; + AZ_TEST_START_TRACE_SUPPRESSION; AzToolsFramework::AssetBundleCommandsBus::BroadcastResult(catalogCreated, &AzToolsFramework::AssetBundleCommandsBus::Events::CreateDeltaCatalog, GetArchivePath().toStdString().c_str(), true); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // produces different counts in different platforms EXPECT_EQ(catalogCreated, true); } } diff --git a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp index f950f43abc..fea9fa6cc1 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace // anonymous { @@ -54,9 +55,11 @@ namespace UnitTest m_localFileIO = aznew AZ::IO::LocalFileIO(); m_priorFileIO = AZ::IO::FileIOBase::GetInstance(); + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(m_localFileIO); - AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", GetTestFolderPath().c_str()); + AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", m_tempDir.GetDirectory()); + AZStd::string assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(AzFramework::PlatformId::PC); for (int idx = 0; idx < TotalAssets; idx++) @@ -68,9 +71,11 @@ namespace UnitTest assetRegistry.RegisterAsset(m_assets[idx], info); AzFramework::StringFunc::Path::Join(assetRoot.c_str(), info.m_relativePath.c_str(), m_assetsPath[idx]); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[idx].Open(m_assetsPath[idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { m_fileStreams[idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -114,10 +119,12 @@ namespace UnitTest // Modify contents of asset2 int fileIndex = 2; + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -126,10 +133,12 @@ namespace UnitTest // Modify contents of asset 4 fileIndex = 4; + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -151,7 +160,9 @@ namespace UnitTest { if (fileIO->Exists(TempFiles[idx])) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TempFiles[idx]); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } } @@ -162,19 +173,24 @@ namespace UnitTest m_fileStreams[idx].Close(); if (fileIO->Exists(m_assetsPath[idx].c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(m_assetsPath[idx].c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } } auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC); if (fileIO->Exists(pcCatalogFile.c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(pcCatalogFile.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } delete m_pcCatalog; delete m_localFileIO; m_localFileIO = nullptr; + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(m_priorFileIO); m_application->Stop(); delete m_application; @@ -726,6 +742,7 @@ namespace UnitTest } ToolsTestApplication* m_application; + UnitTest::ScopedTemporaryDirectory m_tempDir; AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog; AZ::IO::FileIOBase* m_priorFileIO = nullptr; AZ::IO::FileIOBase* m_localFileIO = nullptr; diff --git a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp index 71e4184eb6..dafd2faa4a 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp @@ -87,10 +87,12 @@ namespace UnitTest for (int idx = 0; idx < s_totalAssets; idx++) { AzFramework::StringFunc::Path::Join(assetRoot.c_str(), m_assetsPath[idx].c_str(), m_assetsPathFull[platformCount][idx]); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[platformCount][idx].Open(m_assetsPathFull[platformCount][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { m_fileStreams[platformCount][idx].Write(m_assetsPath[idx].size(), m_assetsPath[idx].data()); m_fileStreams[platformCount][idx].Close(); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, only invalid for PC, not invalid in Jenkins } else { @@ -112,7 +114,9 @@ namespace UnitTest m_testDynamicSliceAssetId = testDynamicSliceAsset; m_assetRegistry->RegisterAsset(testDynamicSliceAsset, dynamicSliceAssetInfo); + AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream dynamicSliceFileIOStream(TestDynamicSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins AZ::Data::AssetInfo sliceAssetInfo; sliceAssetInfo.m_relativePath = TestSliceAssetPath; @@ -124,7 +128,9 @@ namespace UnitTest secondSliceAssetInfo.m_assetId = secondTestSliceAsset; m_assetRegistry->RegisterAsset(secondTestSliceAsset, secondSliceAssetInfo); + AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream sliceFileIOStream(TestSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // asset0 -> asset1 -> asset2 -> asset4 // --> asset3 @@ -186,7 +192,6 @@ namespace UnitTest AZ::IO::Path assetRoot(AZ::Utils::GetProjectPath()); assetRoot /= "Cache"; AZ::IO::FileIOBase::GetInstance()->SetAlias("@root@", assetRoot.c_str()); - } void TearDown() override @@ -195,7 +200,9 @@ namespace UnitTest if (fileIO->Exists(s_catalogFile)) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(s_catalogFile); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } for (size_t platformCount = 0; platformCount < s_totalTestPlatforms; ++platformCount) @@ -206,26 +213,34 @@ namespace UnitTest // we need to close the handle before we try to remove the file if (fileIO->Exists(m_assetsPathFull[platformCount][idx].c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(m_assetsPathFull[platformCount][idx].c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } } } if (fileIO->Exists(TestSliceAssetPath)) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TestSliceAssetPath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } if (fileIO->Exists(TestDynamicSliceAssetPath)) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TestDynamicSliceAssetPath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC); auto androidCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::ANDROID_ID); if (fileIO->Exists(pcCatalogFile.c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(pcCatalogFile.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } if (fileIO->Exists(androidCatalogFile.c_str())) @@ -266,7 +281,9 @@ namespace UnitTest AZ::IO::SystemFile::SetWritable(filePath.c_str(), false); // Attempt to save to the same file. Should not be allowed. + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->Save(filePath)); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -290,7 +307,9 @@ namespace UnitTest AZ::IO::SystemFile::SetWritable(filePath.c_str(), false); // Attempt to save to the same file. Should not be allowed. + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->SaveAssetFileInfo(filePath, AzFramework::PlatformFlags::Platform_PC, {})); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -357,7 +376,9 @@ namespace UnitTest m_assetSeedManager->AddSeedAsset(assets[2], AzFramework::PlatformFlags::Platform_PC); // Step we are testing + AZ_TEST_START_TRACE_SUPPRESSION; m_assetSeedManager->AddPlatformToAllSeeds(AzFramework::PlatformId::ANDROID_ID); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // Verification AzFramework::PlatformFlags expectedPlatformFlags = AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_ANDROID; @@ -623,11 +644,13 @@ namespace UnitTest EXPECT_EQ(assetList1.m_fileInfoList.size(), 1); EXPECT_TRUE(Search(assetList1, assets[fileIndex])); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex); m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); m_fileStreams[0][fileIndex].Close(); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); @@ -654,11 +677,13 @@ namespace UnitTest EXPECT_EQ(assetList1.m_fileInfoList.size(), 1); EXPECT_TRUE(Search(assetList1, assets[fileIndex])); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); m_fileStreams[0][fileIndex].Close(); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); diff --git a/Code/Framework/Tests/ComponentAdapterTests.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentAdapterTests.cpp similarity index 100% rename from Code/Framework/Tests/ComponentAdapterTests.cpp rename to Code/Framework/AzToolsFramework/Tests/ComponentAdapterTests.cpp diff --git a/Code/Framework/Tests/ComponentAddRemove.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentAddRemove.cpp similarity index 100% rename from Code/Framework/Tests/ComponentAddRemove.cpp rename to Code/Framework/AzToolsFramework/Tests/ComponentAddRemove.cpp diff --git a/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp index 775c771a8a..9ee75408e6 100644 --- a/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp @@ -493,7 +493,10 @@ namespace UnitTest // Add placeholder component which implements component mode. entity->CreateComponent(); + AZ_TEST_START_TRACE_SUPPRESSION; entity->Activate(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp b/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp index 3bc4c092dc..c15034ee33 100644 --- a/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp @@ -348,7 +348,6 @@ namespace UnitTest EXPECT_FALSE(AzToolsFramework::ComponentPaletteUtil::ContainsEditableComponents(context, &Filter_IsTestComponent2, AZ::ComponentDescriptor::DependencyArrayType())); // Reflect Test Component 2 for subsequent tests - Inspector_TestComponent2::Reflect(context); m_application->RegisterComponentDescriptor(Inspector_TestComponent2Descriptor); // Verify that there is now a component that satisfies the AppearsInGameComponentMenu filter without service dependency conditions diff --git a/Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp diff --git a/Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h diff --git a/Code/Framework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp diff --git a/Code/Framework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp diff --git a/Code/Framework/Tests/EntityTestbed.h b/Code/Framework/AzToolsFramework/Tests/EntityTestbed.h similarity index 100% rename from Code/Framework/Tests/EntityTestbed.h rename to Code/Framework/AzToolsFramework/Tests/EntityTestbed.h diff --git a/Code/Framework/Tests/FileFunc.cpp b/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp similarity index 99% rename from Code/Framework/Tests/FileFunc.cpp rename to Code/Framework/AzToolsFramework/Tests/FileFunc.cpp index 4edb91164c..124e9af0f2 100644 --- a/Code/Framework/Tests/FileFunc.cpp +++ b/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp @@ -5,8 +5,8 @@ * */ -#include "FrameworkApplicationFixture.h" -#include "Utils/Utils.h" +#include +#include #include #include #include @@ -47,11 +47,13 @@ namespace UnitTest void SetUp() { m_prevFileIO = AZ::IO::FileIOBase::GetInstance(); + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(&m_fileIO); } void TearDown() override { + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(m_prevFileIO); } diff --git a/Code/Framework/Tests/GenericComponentWrapperTest.cpp b/Code/Framework/AzToolsFramework/Tests/GenericComponentWrapperTest.cpp similarity index 100% rename from Code/Framework/Tests/GenericComponentWrapperTest.cpp rename to Code/Framework/AzToolsFramework/Tests/GenericComponentWrapperTest.cpp diff --git a/Code/Framework/Tests/InstanceDataHierarchy.cpp b/Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp similarity index 100% rename from Code/Framework/Tests/InstanceDataHierarchy.cpp rename to Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp diff --git a/Code/Framework/AzToolsFramework/Tests/Main.cpp b/Code/Framework/AzToolsFramework/Tests/Main.cpp index ff94f9af5c..21aac978b3 100644 --- a/Code/Framework/AzToolsFramework/Tests/Main.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Main.cpp @@ -46,7 +46,7 @@ AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv) } styleManager->initialize(&app, engineRootPath); AZ::Test::printUnusedParametersWarning(argc, argv); - AZ::Test::addTestEnvironments({ new ToolsFrameworkHook }); + AZ::Test::addTestEnvironments({ DEFAULT_UNIT_TEST_ENV, new ToolsFrameworkHook }); int result = RUN_ALL_TESTS(); styleManager.release(); return result; diff --git a/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp b/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp index db7430085b..46f9a9fa3a 100644 --- a/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp @@ -23,8 +23,7 @@ namespace UnitTest }; struct PerforceComponentFixture - : ::testing::Test - , TraceBusRedirector + : ScopedAllocatorSetupFixture , SourceControlTest { @@ -40,7 +39,6 @@ namespace UnitTest m_jobContext = aznew AZ::JobContext(*m_jobManager); AZ::JobContext::SetGlobalContext(m_jobContext); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); AZ::TickBus::AllowFunctionQueuing(true); m_perforceComponent = AZStd::make_unique(); @@ -52,8 +50,6 @@ namespace UnitTest void TearDown() override { - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - AZ::TickBus::AllowFunctionQueuing(false); AZ::TickBus::ClearQueuedEvents(); diff --git a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp index e581f4fac7..3446f854b6 100644 --- a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp @@ -83,9 +83,11 @@ namespace UnitTest info.m_assetId = m_assets[platformNum][idx]; assetRegistry->RegisterAsset(m_assets[platformNum][idx], info); m_assetsPath[platformNum][idx] = info.m_relativePath; + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[platformNum][idx].Open(m_assetsPath[platformNum][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { m_fileStreams[platformNum][idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -131,7 +133,9 @@ namespace UnitTest m_fileStreams[platformNum][idx].Close(); if (fileIO->Exists(m_assetsPath[platformNum][idx].c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(m_assetsPath[platformNum][idx].c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // removing from asset cache folder } } } @@ -246,7 +250,9 @@ namespace UnitTest AzFramework::AssetSystem::NetworkAssetUpdateInterface* notificationInterface = AZ::Interface::Get(); EXPECT_NE(notificationInterface, nullptr); + AZ_TEST_START_TRACE_SUPPRESSION; auto* mockCatalog = new ::testing::NiceMock(AzFramework::PlatformId::ANDROID_ID); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); AZStd::unique_ptr< ::testing::NiceMock> catalogHolder; catalogHolder.reset(mockCatalog); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp index a08de99d3e..b0fd167cc0 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp @@ -13,7 +13,9 @@ namespace UnitTest TEST_F(PrefabInstantiateTest, PrefabInstantiate_InstantiateInvalidTemplate_InstantiateFails) { + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_prefabSystemComponent->InstantiatePrefab(AzToolsFramework::Prefab::InvalidTemplateId)); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); } TEST_F(PrefabInstantiateTest, PrefabInstantiate_NoNestingTemplate_InstantiateSucceeds) diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp index 9cf1194834..a3d6cafd2a 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp @@ -68,8 +68,10 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom); - + + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION(3); templateData.m_isLoadedWithErrors = true; PrefabTestDataUtils::ValidateTemplateLoad(templateData); @@ -115,7 +117,9 @@ namespace UnitTest targetTemplateData.m_filePath, targetTemplatePrefabDom); // Load target and source Templates and get their Ids. + AZ_TEST_START_TRACE_SUPPRESSION; targetTemplateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(targetTemplateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION(4); sourceTemplateData.m_id = m_prefabSystemComponent->GetTemplateIdFromFilePath(sourceTemplateData.m_filePath); // Because of cyclical dependency, the two Templates should be loaded with errors. @@ -144,7 +148,9 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION(2); PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -161,7 +167,9 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION(2); PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -183,7 +191,9 @@ namespace UnitTest templateInstanceData.m_source, PrefabTestDomUtils::CreatePrefabDom(), AZ::IO::ResultCode::Success, AZ::IO::ResultCode::Error); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION(3); PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -279,8 +289,10 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(pathToCorruptedPrefab, corruptedPrefabContent); - + + AZ_TEST_START_TRACE_SUPPRESSION; TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromFile(pathToCorruptedPrefab); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId); } @@ -289,8 +301,10 @@ namespace UnitTest { PrefabDom emptyPrefabDom = PrefabTestDomUtils::CreatePrefabDom(); AZStd::string emptyPrefabDomStr = PrefabTestDomUtils::DomToString(emptyPrefabDom); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "|?<>"), AzToolsFramework::Prefab::InvalidTemplateId); EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "notAFile/"), AzToolsFramework::Prefab::InvalidTemplateId); + AZ_TEST_STOP_TRACE_SUPPRESSION(2); } TEST_F(PrefabLoadTemplateTest, LoadTemplate_LoadFromString_LoadsEmptyPrefab) @@ -318,9 +332,11 @@ namespace UnitTest ); AZStd::string selfDependentPrefabStr = PrefabTestDomUtils::DomToString(selfDependentPrefab); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromString( selfDependentPrefabStr, templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // produces different counts in Jenkins vs local templateData.m_isLoadedWithErrors = true; @@ -330,7 +346,9 @@ namespace UnitTest TEST_F(PrefabLoadTemplateTest, LoadTemplate_LoadFromString_CorruptedReturnsInvalidTemplateId) { AZStd::string corruptPrefab = "{ Corrupted PrefabDom"; + AZ_TEST_START_TRACE_SUPPRESSION; TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromString(corruptPrefab); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId); } } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp index 34cff98a73..6e836e4d44 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp @@ -166,13 +166,25 @@ namespace UnitTest if (expectedNestedInstanceDomInstances.has_value()) { ASSERT_TRUE(actualNestedInstanceDomInstances.has_value()); - for (auto instanceIterator = expectedNestedInstanceDomInstances->get().MemberBegin(); - instanceIterator != expectedNestedInstanceDomInstances->get().MemberEnd(); ++instanceIterator) + if (expectedNestedInstanceDomInstances->get().IsArray()) { - ComparePrefabDoms( - instanceIterator->value, - PrefabDomUtils::FindPrefabDomValue(actualNestedInstanceDomInstances->get(), instanceIterator->name.GetString()), - shouldCompareLinkIds, shouldCompareContainerEntities); + ASSERT_TRUE(actualNestedInstanceDomInstances->get().IsArray()); + const size_t expectedArraySize = expectedNestedInstanceDomInstances->get().GetArray().Size(); + EXPECT_EQ(0, expectedArraySize); + const size_t actualArraySize = actualNestedInstanceDomInstances->get().GetArray().Size(); + EXPECT_EQ(0, actualArraySize); + } + if (expectedNestedInstanceDomInstances->get().IsObject()) + { + ASSERT_TRUE(actualNestedInstanceDomInstances->get().IsObject()); + for (auto instanceIterator = expectedNestedInstanceDomInstances->get().MemberBegin(); + instanceIterator != expectedNestedInstanceDomInstances->get().MemberEnd(); ++instanceIterator) + { + ComparePrefabDoms( + instanceIterator->value, + PrefabDomUtils::FindPrefabDomValue(actualNestedInstanceDomInstances->get(), instanceIterator->name.GetString()), + shouldCompareLinkIds, shouldCompareContainerEntities); + } } } } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h index 763d3bec1f..b438f9f28d 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h @@ -37,8 +37,7 @@ namespace UnitTest }; class PrefabTestFixture - : public ToolsApplicationFixture, - public UnitTest::TraceBusRedirector + : public ToolsApplicationFixture { protected: diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp b/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp index 99cf334dc9..006dd5a656 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp @@ -426,7 +426,9 @@ namespace UnitTest AZStd::any keyString = AZStd::make_any("0"); EXPECT_FALSE(propertyTree.GetContainerItem("My New Int", key).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(propertyTree.GetContainerItem("My New List", keyString).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); PropertyTreeEditor::PropertyAccessOutcome outcome = propertyTree.GetContainerItem("My New List", key); EXPECT_TRUE(outcome.IsSuccess()); @@ -446,7 +448,9 @@ namespace UnitTest AZStd::any value = AZStd::make_any(testUpdate); EXPECT_FALSE(propertyTree.UpdateContainerItem("My New Int", key, value).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(propertyTree.UpdateContainerItem("My New List", keyString, value).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_TRUE(propertyTree.UpdateContainerItem("My New List", key, value).IsSuccess()); PropertyTreeEditor::PropertyAccessOutcome outcome = propertyTree.GetContainerItem("My New List", key); @@ -464,7 +468,9 @@ namespace UnitTest AZStd::any keyString = AZStd::make_any("0"); EXPECT_FALSE(propertyTree.RemoveContainerItem("My New Int", key).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(propertyTree.RemoveContainerItem("My New List", keyString).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); PropertyTreeEditor::PropertyAccessOutcome outcomeAdd1 = propertyTree.RemoveContainerItem("My New List", key); EXPECT_TRUE(outcomeAdd1.IsSuccess()); @@ -755,7 +761,9 @@ namespace UnitTest EXPECT_TRUE(propertyTree.SetProperty("My Int", anEmpty).IsSuccess()); EXPECT_TRUE(propertyTree.SetProperty("My Negative Short", anEmpty).IsSuccess()); EXPECT_TRUE(propertyTree.SetProperty("My New List", anEmpty).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_TRUE(propertyTree.SetProperty("My Asset Data", anEmpty).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_TRUE(propertyTree.SetProperty("My Test Simple Asset", anEmpty).IsSuccess()); } diff --git a/Code/Framework/Tests/SQLiteConnectionTests.cpp b/Code/Framework/AzToolsFramework/Tests/SQLiteConnectionTests.cpp similarity index 100% rename from Code/Framework/Tests/SQLiteConnectionTests.cpp rename to Code/Framework/AzToolsFramework/Tests/SQLiteConnectionTests.cpp diff --git a/Code/Framework/Tests/Script/ScriptComponentTests.cpp b/Code/Framework/AzToolsFramework/Tests/Script/ScriptComponentTests.cpp similarity index 100% rename from Code/Framework/Tests/Script/ScriptComponentTests.cpp rename to Code/Framework/AzToolsFramework/Tests/Script/ScriptComponentTests.cpp diff --git a/Code/Framework/Tests/Script/ScriptEntityTests.cpp b/Code/Framework/AzToolsFramework/Tests/Script/ScriptEntityTests.cpp similarity index 100% rename from Code/Framework/Tests/Script/ScriptEntityTests.cpp rename to Code/Framework/AzToolsFramework/Tests/Script/ScriptEntityTests.cpp diff --git a/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp b/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp index 98b004feba..f8acf7d224 100644 --- a/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp @@ -275,6 +275,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, IntermmediateDataTypeChange) { TestDataA::Reflect(m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentA_V0::Reflect(m_serializeContext.get()); AZ::Entity* entityA = aznew AZ::Entity(); TestComponentA_V0* component = entityA->CreateComponent(); @@ -320,6 +321,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, TypeChangeInUnorderedMap) { TestDataB_V0::Reflect(m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentB_V0::Reflect(m_serializeContext.get()); AZ::Entity* entityA = aznew AZ::Entity(); TestComponentB_V0* componentB = entityA->CreateComponent(); @@ -395,6 +397,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, TypeChangeInVector) { TestDataB_V0::Reflect(m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentC_V0::Reflect(m_serializeContext.get()); AZ::Entity* entityA = aznew AZ::Entity(); TestComponentC_V0* componentC = entityA->CreateComponent(); @@ -452,6 +455,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, UpgradeSkipVersion_TypeChange_FloatToDouble) { // 1. Create an entity with a TestComponentE_V4 with the default value for m_data + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentE_V4::Reflect(m_serializeContext.get()); AZ::Entity* testEntity = aznew AZ::Entity(); TestComponentE_V4* componentEV4 = testEntity->CreateComponent(); @@ -563,6 +567,7 @@ namespace UnitTest SliceUpgradeTestAsset::Reflect(m_serializeContext.get()); AzFramework::SimpleAssetReference::Register(*m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentD_V1::Reflect(m_serializeContext.get()); AZ::Entity* entity = aznew AZ::Entity(); entity->CreateComponent(); diff --git a/Code/Framework/Tests/Slices.cpp b/Code/Framework/AzToolsFramework/Tests/Slices.cpp similarity index 96% rename from Code/Framework/Tests/Slices.cpp rename to Code/Framework/AzToolsFramework/Tests/Slices.cpp index ba413eb727..a8c98d2a85 100644 --- a/Code/Framework/Tests/Slices.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Slices.cpp @@ -972,11 +972,11 @@ namespace UnitTest }; - class TestExportEditorComponent + class SliceTestExportEditorComponent : public AzToolsFramework::Components::EditorComponentBase { public: - AZ_COMPONENT(TestExportEditorComponent, "{8FA877A2-38E6-49AD-B31E-71B86DC8BB03}", AzToolsFramework::Components::EditorComponentBase); + AZ_COMPONENT(SliceTestExportEditorComponent, "{8FA877A2-38E6-49AD-B31E-71B86DC8BB03}", AzToolsFramework::Components::EditorComponentBase); enum ExportComponentType { @@ -986,9 +986,9 @@ namespace UnitTest EXPORT_NULL_COMPONENT }; - TestExportEditorComponent() {} + SliceTestExportEditorComponent() {} - TestExportEditorComponent(ExportComponentType exportType, bool exportHandled) : + SliceTestExportEditorComponent(ExportComponentType exportType, bool exportHandled) : m_exportType(exportType), m_exportHandled(exportHandled) {} @@ -1000,15 +1000,15 @@ namespace UnitTest { if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { - serializeContext->Class() + serializeContext->Class() ; if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { - editContext->Class( + editContext->Class( "Test Export Editor Component", "Validate different options for exporting editor components") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::RuntimeExportCallback, &TestExportEditorComponent::ExportComponent) + ->Attribute(AZ::Edit::Attributes::RuntimeExportCallback, &SliceTestExportEditorComponent::ExportComponent) ; } } @@ -1070,7 +1070,7 @@ namespace UnitTest m_app.RegisterComponentDescriptor(TestExportRuntimeComponent::CreateDescriptor()); m_app.RegisterComponentDescriptor(TestExportOtherRuntimeComponent::CreateDescriptor()); - m_app.RegisterComponentDescriptor(TestExportEditorComponent::CreateDescriptor()); + m_app.RegisterComponentDescriptor(SliceTestExportEditorComponent::CreateDescriptor()); m_editorSliceAsset = Data::AssetManager::Instance().CreateAsset(Data::AssetId(Uuid::CreateRandom())); @@ -1125,11 +1125,11 @@ namespace UnitTest } // create entity containing the EditorOnly component in the editor slice - void CreateTestExportEditorEntity(const char* name, TestExportEditorComponent::ExportComponentType exportType, bool exportHandled) + void CreateTestExportEditorEntity(const char* name, SliceTestExportEditorComponent::ExportComponentType exportType, bool exportHandled) { AZ::Entity* entity = aznew AZ::Entity(name); entity->CreateComponent(); - entity->CreateComponent(exportType, exportHandled); + entity->CreateComponent(exportType, exportHandled); m_editorSliceComponent->AddEntity(entity); } @@ -1314,7 +1314,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportedSuccessfully) { // Create an editor component that has a RuntimeExportCallback and successfully exports itself - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_OTHER_RUNTIME_COMPONENT, true); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_OTHER_RUNTIME_COMPONENT, true); if (!CompileSlice()) { @@ -1325,7 +1325,7 @@ namespace UnitTest // (A result of Runtime component means BuildGameEntity() ran instead) AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); EXPECT_TRUE(entity->FindComponent()); } @@ -1333,7 +1333,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportSuppressed) { // Create an editor component that has a RuntimeExportCallback and successfully suppresses itself from exporting - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, true); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, true); if (!CompileSlice()) { @@ -1343,7 +1343,7 @@ namespace UnitTest // Expected result: exported slice does NOT contain either component. AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); } @@ -1351,7 +1351,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportUnhandledFallbackToBuildGameEntity) { // Create an editor component that has a RuntimeExportCallback, returns a pointer to itself, but says it wasn't handled. - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, false); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, false); if (!CompileSlice()) { @@ -1362,7 +1362,7 @@ namespace UnitTest // produced a runtime component. AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_TRUE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); } @@ -1370,7 +1370,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportSuppressedAndUnhandledFallbackToBuildGameEntity) { // Create an editor component that has a RuntimeExportCallback and suppresses itself from exporting, but says it wasn't handled - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, false); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, false); if (!CompileSlice()) { @@ -1381,7 +1381,7 @@ namespace UnitTest // produced a runtime component. AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_TRUE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); } @@ -1389,7 +1389,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentFailsToExportItself) { // Create an editor component that has a RuntimeExportCallback and suppresses itself from exporting, but says it wasn't handled - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, true); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, true); // We expect the slice compilation to fail, since an editor component is being exported as a game component CompileSlice(false); diff --git a/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp b/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp index 05ffc6055f..8c8ebc47e9 100644 --- a/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp @@ -20,7 +20,6 @@ namespace UnitTest class ThumbnailerTests : public ::testing::Test - , public TraceBusRedirector { protected: void SetUp() override @@ -31,8 +30,6 @@ namespace UnitTest // was running, because the environment wasn't setup for it to save these settings. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - TraceBusRedirector::BusConnect(); - AZStd::string entityName("test"); AZ::EntityId testEntityId; AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult( @@ -61,8 +58,6 @@ namespace UnitTest void TearDown() override { - TraceBusRedirector::BusDisconnect(); - AzToolsFramework::EditorEntityContextRequestBus::Broadcast( &AzToolsFramework::EditorEntityContextRequestBus::Events::DestroyEditorEntity, m_testEntity->GetId()); diff --git a/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp b/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp index 3007f12192..0c50ca2e00 100644 --- a/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp @@ -248,8 +248,6 @@ namespace AzToolsFramework m_app.Stop(); AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - } // A few tests save a layer and want to check the state after saving. diff --git a/Code/Framework/Tests/TransformComponent.cpp b/Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp similarity index 99% rename from Code/Framework/Tests/TransformComponent.cpp rename to Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp index 57edbf7f74..21631571f5 100644 --- a/Code/Framework/Tests/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp @@ -975,7 +975,7 @@ namespace UnitTest // AzToolsFramework::Components::TransformComponent // Fixture base class for AzToolsFramework::Components::TransformComponent tests - class EditorTransformComponentTest + class OldEditorTransformComponentTest : public ::testing::Test { protected: @@ -1000,7 +1000,7 @@ namespace UnitTest // Old TransformComponents used to store "Slice Root" entity Id, which could be its own Id. // The version-converter could end up making an entity into its own transform parent. // The EditorEntityFixupComponent should fix this up during slice instantiation. - TEST_F(EditorTransformComponentTest, OldSliceRoots_ShouldHaveNoParent) + TEST_F(OldEditorTransformComponentTest, OldSliceRoots_ShouldHaveNoParent) { const char kSliceData[] = R"DELIMITER( diff --git a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp index cf9f95ef31..384edf76ad 100644 --- a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp @@ -127,7 +127,6 @@ namespace UnitTest void SetUpEditorFixtureImpl() override { m_editor = new EntityPropertyEditor(); - m_editorActions.Connect(); m_entity1 = CreateDefaultEditorEntity("Entity1"); m_entity2 = CreateDefaultEditorEntity("Entity2"); @@ -137,13 +136,11 @@ namespace UnitTest void TearDownEditorFixtureImpl() override { - m_editorActions.Disconnect(); delete m_editor; } public: EntityPropertyEditor* m_editor; - TestEditorActions m_editorActions; EntityIdList m_entityIds; AZ::EntityId m_entity1; AZ::EntityId m_entity2; @@ -234,8 +231,6 @@ namespace UnitTest entities.insert(m_levelEntity); m_levelEditor->SetOverrideEntityIds(entities); - m_editorActions.Connect(); - // Connect to the EditorRequestBus so that we can intercept calls checking whether or not a level is currently open. AzToolsFramework::EditorRequestBus::Handler::BusConnect(); } @@ -244,7 +239,6 @@ namespace UnitTest { AzToolsFramework::EditorRequestBus::Handler::BusDisconnect(); - m_editorActions.Disconnect(); delete m_levelEditor; } @@ -258,7 +252,6 @@ namespace UnitTest public: EntityPropertyEditor* m_levelEditor; - TestEditorActions m_editorActions; AZ::EntityId m_levelEntity; bool m_levelOpen = false; }; diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp index f1d282e869..7480c937f4 100644 --- a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp @@ -85,19 +85,8 @@ namespace UnitTest } class ViewportUiWidgetAssertFixture - : public ::testing::Test - , UnitTest::TraceBusRedirector - { - public: - void SetUp() override - { - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - } - void TearDown() override - { - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - }; + : public ScopedAllocatorSetupFixture + {}; TEST_F(ViewportUiWidgetAssertFixture, RegisterUpdateCallbackDoesNotRegisterFunctionForNotAddedObject) { diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 2e2be6f921..9d1ec3e346 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -11,35 +11,37 @@ set(FILES AssetFileInfoListComparison.cpp AssetSeedManager.cpp AssetSystemMocks.h - ComponentModeTests.cpp - ComponentModeTestDoubles.h + ComponentAdapterTests.cpp + ComponentAddRemove.cpp ComponentModeTestDoubles.cpp - ComponentModeTestFixture.h + ComponentModeTestDoubles.h ComponentModeTestFixture.cpp + ComponentModeTestFixture.h + ComponentModeTests.cpp EditorTransformComponentSelectionTests.cpp EditorVertexSelectionTests.cpp + Entity/EditorEntityContextComponentTests.cpp + Entity/EditorEntityHelpersTests.cpp + Entity/EditorEntitySearchComponentTests.cpp + Entity/EditorEntitySelectionTests.cpp EntityIdQLabelTests.cpp EntityInspectorTests.cpp + EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp + EntityOwnershipService/EntityOwnershipServiceTestFixture.h + EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp + EntityOwnershipService/SliceEntityOwnershipTests.cpp + EntityTestbed.h + FileFunc.cpp FingerprintingTests.cpp + GenericComponentWrapperTest.cpp + InstanceDataHierarchy.cpp + IntegerPrimtitiveTestConfig.h LogLines.cpp ManipulatorBoundsTests.cpp ManipulatorCoreTests.cpp ManipulatorViewTests.cpp - PlatformAddressedAssetCatalogTests.cpp - PropertyIntCtrlCommonTests.h - IntegerPrimtitiveTestConfig.h - QtWidgetLimitsTests.cpp - PropertyIntSliderCtrlTests.cpp - PropertyIntSpinCtrlTests.cpp - PropertyTreeEditorTests.cpp - PythonBindingTests.cpp - Slice.cpp - SliceUpgradeTestsData.h - SliceUpgradeTests.cpp - SpinBoxTests.cpp - ThumbnailerTests.cpp - UndoStack.cpp PerforceComponentTests.cpp + PlatformAddressedAssetCatalogTests.cpp Prefab/Benchmark/PrefabBenchmarkFixture.cpp Prefab/Benchmark/PrefabBenchmarkFixture.h Prefab/Benchmark/PrefabCreateBenchmarks.cpp @@ -47,13 +49,13 @@ set(FILES Prefab/Benchmark/PrefabLoadBenchmarks.cpp Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp Prefab/Benchmark/SpawnableCreateBenchmarks.cpp - Prefab/Spawnable/SpawnableMetaDataTests.cpp Prefab/MockPrefabFileIOActionValidator.cpp Prefab/MockPrefabFileIOActionValidator.h Prefab/PrefabDuplicateTests.cpp Prefab/PrefabEntityAliasTests.cpp Prefab/PrefabInstanceToTemplatePropagatorTests.cpp Prefab/PrefabInstantiateTests.cpp + Prefab/PrefabInstantiateTests.cpp Prefab/PrefabLoadTemplateTests.cpp Prefab/PrefabTestComponent.cpp Prefab/PrefabTestComponent.h @@ -67,37 +69,50 @@ set(FILES Prefab/PrefabTestFixture.h Prefab/PrefabTestUndoFixture.cpp Prefab/PrefabTestUndoFixture.h + Prefab/PrefabTestUtils.h Prefab/PrefabUndoLinkTests.cpp Prefab/PrefabUndoTests.cpp - Prefab/PrefabTestUtils.h Prefab/PrefabUpdateInstancesTests.cpp Prefab/PrefabUpdateTemplateTests.cpp Prefab/PrefabUpdateWithPatchesTests.cpp - Prefab/PrefabInstantiateTests.cpp + Prefab/Spawnable/SpawnableMetaDataTests.cpp Prefab/SpawnableCreateTests.cpp - Prefab/SpawnableRemoveEditorInfoTests.cpp Prefab/SpawnableRemoveEditorInfoTestFixture.cpp Prefab/SpawnableRemoveEditorInfoTestFixture.h - Prefab/SpawnableSortEntitiesTests.cpp + Prefab/SpawnableRemoveEditorInfoTests.cpp Prefab/SpawnableSortEntitiesTestFixture.cpp Prefab/SpawnableSortEntitiesTestFixture.h - Entity/EditorEntityContextComponentTests.cpp - Entity/EditorEntityHelpersTests.cpp - Entity/EditorEntitySearchComponentTests.cpp - Entity/EditorEntitySelectionTests.cpp - SliceStabilityTests/SliceStabilityTestFramework.h - SliceStabilityTests/SliceStabilityTestFramework.cpp + Prefab/SpawnableSortEntitiesTests.cpp + PropertyIntCtrlCommonTests.h + PropertyIntSliderCtrlTests.cpp + PropertyIntSpinCtrlTests.cpp + PropertyTreeEditorTests.cpp + PythonBindingTests.cpp + QtWidgetLimitsTests.cpp + Script/ScriptComponentTests.cpp + Script/ScriptEntityTests.cpp + Slice.cpp + Slices.cpp SliceStabilityTests/SliceStabilityCreateTests.cpp SliceStabilityTests/SliceStabilityPushTests.cpp SliceStabilityTests/SliceStabilityReParentTests.cpp + SliceStabilityTests/SliceStabilityTestFramework.cpp + SliceStabilityTests/SliceStabilityTestFramework.h + SliceUpgradeTests.cpp + SliceUpgradeTestsData.h + SpinBoxTests.cpp + SQLiteConnectionTests.cpp + ThumbnailerTests.cpp ToolsComponents/EditorLayerComponentTests.cpp ToolsComponents/EditorTransformComponentTests.cpp + TransformComponent.cpp UI/EntityPropertyEditorTests.cpp + UndoStack.cpp + Viewport/ClusterTests.cpp Viewport/ViewportScreenTests.cpp Viewport/ViewportUiClusterTests.cpp Viewport/ViewportUiDisplayTests.cpp Viewport/ViewportUiManagerTests.cpp - Viewport/ClusterTests.cpp Viewport/ViewportUiWidgetManagerTests.cpp Visibility/EditorVisibilityTests.cpp ) diff --git a/Code/Framework/CMakeLists.txt b/Code/Framework/CMakeLists.txt index e12a8f4cab..880751632c 100644 --- a/Code/Framework/CMakeLists.txt +++ b/Code/Framework/CMakeLists.txt @@ -18,4 +18,3 @@ add_subdirectory(AzNetworking) add_subdirectory(Crcfix) add_subdirectory(GFxFramework) add_subdirectory(GridMate) -add_subdirectory(Tests) diff --git a/Code/Framework/Tests/CMakeLists.txt b/Code/Framework/Tests/CMakeLists.txt deleted file mode 100644 index 6781466413..0000000000 --- a/Code/Framework/Tests/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - - ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - - ly_add_target( - NAME AzFrameworkTestShared STATIC - NAMESPACE AZ - FILES_CMAKE - framework_shared_tests_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzCore - AZ::AzFramework - ) - - if(PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_target( - NAME ProcessLaunchTest EXECUTABLE - NAMESPACE AZ - FILES_CMAKE - process_launch_test_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzCore - AZ::AzFramework - ) - - ly_add_target( - NAME Framework.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE AZ - FILES_CMAKE - frameworktests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - ${pal_dir} - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - AZ::AzToolsFramework - AZ::AzTestShared - AZ::AzFrameworkTestShared - RUNTIME_DEPENDENCIES - AZ::ProcessLaunchTest - ) - ly_add_googletest( - NAME AZ::Framework.Tests - ) - endif() - -endif() diff --git a/Code/Tools/GridHub/GridHub/main.cpp b/Code/Tools/GridHub/GridHub/main.cpp index 5b35abff6c..0b1cfced93 100644 --- a/Code/Tools/GridHub/GridHub/main.cpp +++ b/Code/Tools/GridHub/GridHub/main.cpp @@ -187,7 +187,6 @@ protected: { ComponentApplication::SetSettingsRegistrySpecializations(specializations); specializations.Append("tools"); - specializations.Append("editor"); specializations.Append("gridhub"); } diff --git a/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp b/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp index 62daba1197..911f469b2f 100644 --- a/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include namespace AZ { @@ -31,6 +33,12 @@ namespace AZ { serializeContext->Class()->Version(2); } + + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) + { + Events::ExportProductList::Reflect(behaviorContext); + } } } // namespace SceneCore } // namespace SceneAPI diff --git a/Code/Tools/SceneAPI/SceneCore/DllMain.cpp b/Code/Tools/SceneAPI/SceneCore/DllMain.cpp index 7874ada7be..ac3c307b6c 100644 --- a/Code/Tools/SceneAPI/SceneCore/DllMain.cpp +++ b/Code/Tools/SceneAPI/SceneCore/DllMain.cpp @@ -211,6 +211,7 @@ namespace AZ AZ::SceneAPI::Containers::SceneGraph::Reflect(context); AZ::SceneAPI::Containers::SceneManifest::Reflect(context); AZ::SceneAPI::Containers::RuleContainer::Reflect(context); + AZ::SceneAPI::SceneCore::ExportingComponent::Reflect(context); } void Activate() diff --git a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp index c3a9abcbd2..798978024e 100644 --- a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp @@ -6,6 +6,8 @@ */ #include +#include +#include namespace AZ { @@ -49,6 +51,45 @@ namespace AZ return *this; } + void ExportProductList::Reflect(ReflectContext* context) + { + if (auto* serializeContext = azrtti_cast(context)) + { + serializeContext->Class()->Version(1); + serializeContext->Class()->Version(1); + } + + if (auto* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("ExportProduct") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Property("filename", BehaviorValueProperty(&ExportProduct::m_filename)) + ->Property("sourceId", BehaviorValueProperty(&ExportProduct::m_id)) + ->Property("assetType", BehaviorValueProperty(&ExportProduct::m_assetType)) + ->Property("productDependencies", BehaviorValueProperty(&ExportProduct::m_productDependencies)) + ->Property("subId", + [](ExportProduct* self) { return self->m_subId.has_value() ? self->m_subId.value() : 0; }, + [](ExportProduct* self, u32 subId) { self->m_subId = AZStd::optional(subId); }); + + behaviorContext->Class("ExportProductList") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Method("AddProduct", [](ExportProductList& self, ExportProduct& product) + { + self.AddProduct( + product.m_filename, + product.m_id, + product.m_assetType, + product.m_lod, + product.m_subId, + product.m_dependencyFlags); + }) + ->Method("GetProducts", &ExportProductList::GetProducts) + ->Method("AddDependencyToProduct", &ExportProductList::AddDependencyToProduct); + } + } + ExportProduct& ExportProductList::AddProduct(const AZStd::string& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags) { diff --git a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h index 38deea3f9f..a99303e08b 100644 --- a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h +++ b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h @@ -14,6 +14,8 @@ namespace AZ { + class ReflectContext; + namespace SceneAPI { namespace Events @@ -24,6 +26,7 @@ namespace AZ Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad)); SCENE_CORE_API ExportProduct(AZStd::string&& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad)); + ExportProduct() = default; ExportProduct(const ExportProduct& rhs) = default; SCENE_CORE_API ExportProduct(ExportProduct&& rhs); @@ -54,6 +57,8 @@ namespace AZ class ExportProductList { public: + static void Reflect(ReflectContext* context); + SCENE_CORE_API ExportProduct& AddProduct(const AZStd::string& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad)); SCENE_CORE_API ExportProduct& AddProduct(AZStd::string&& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, @@ -69,3 +74,9 @@ namespace AZ } // namespace Events } // namespace SceneAPI } // namespace AZ + +namespace AZ +{ + AZ_TYPE_INFO_SPECIALIZE(SceneAPI::Events::ExportProduct, "{6054EDCB-4C04-4D96-BF26-704999FFB725}"); + AZ_TYPE_INFO_SPECIALIZE(SceneAPI::Events::ExportProductList, "{1C76A51F-431B-4987-B653-CFCC940D0D0F}"); +} diff --git a/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp b/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp index a4b002db7d..073f357ee6 100644 --- a/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -75,15 +76,16 @@ namespace AZ filename += s_extension; filename += s_generated; - AZStd::string altManifestPath = path; + AZStd::string altManifestFolder = path; AzFramework::ApplicationRequests::Bus::Broadcast( - &AzFramework::ApplicationRequests::Bus::Events::MakePathRootRelative, - altManifestPath); + &AzFramework::ApplicationRequests::Bus::Events::MakePathRelative, + altManifestFolder, + AZ::Utils::GetProjectPath().c_str()); - AZ::StringFunc::Path::GetFolderPath(altManifestPath.c_str(), altManifestPath); + AZ::StringFunc::Path::GetFolderPath(altManifestFolder.c_str(), altManifestFolder); AZStd::string generatedAssetInfoPath; - AZ::StringFunc::Path::Join(assetCacheRoot.c_str(), altManifestPath.c_str(), generatedAssetInfoPath); + AZ::StringFunc::Path::Join(assetCacheRoot.c_str(), altManifestFolder.c_str(), generatedAssetInfoPath); AZ::StringFunc::Path::ConstructFull(generatedAssetInfoPath.c_str(), filename.c_str(), generatedAssetInfoPath); if (!AZ::IO::FileIOBase::GetInstance()->Exists(generatedAssetInfoPath.c_str())) diff --git a/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp b/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp index e1c72bc8b4..4e08181b83 100644 --- a/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp @@ -28,710 +28,731 @@ extern "C" AZ_DLL_EXPORT void ReflectBehavior(AZ::BehaviorContext* context); // the DLL entry point for SceneCore to reflect its serialize context extern "C" AZ_DLL_EXPORT void ReflectTypes(AZ::SerializeContext* context); -namespace AZ +namespace AZ::SceneAPI::Containers { - namespace SceneAPI + class MockManifestRule : public DataTypes::IManifestObject { - namespace Containers + public: + AZ_RTTI(MockManifestRule, "{D6F96B48-4E6F-4EE8-A5A3-959B76F90DA8}", IManifestObject); + AZ_CLASS_ALLOCATOR(MockManifestRule, AZ::SystemAllocator, 0); + + MockManifestRule() = default; + + MockManifestRule(double value) + : m_value(value) + { + } + + double GetValue() const + { + return m_value; + } + + void SetValue(double value) { - class MockManifestRule : public DataTypes::IManifestObject + m_value = value; + } + + static void Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) { - public: - AZ_RTTI(MockManifestRule, "{D6F96B48-4E6F-4EE8-A5A3-959B76F90DA8}", IManifestObject); - AZ_CLASS_ALLOCATOR(MockManifestRule, AZ::SystemAllocator, 0); + serializeContext->Class() + ->Version(1) + ->Field("value", &MockManifestRule::m_value); + } + } - MockManifestRule() = default; + private: + double m_value = 0.0; + }; - MockManifestRule(double value) - : m_value(value) - { - } + struct MockBuilder final + { + AZ_TYPE_INFO(MockBuilder, "{ECF0FB2C-E5C0-4B89-993C-8511A7EF6894}"); - double GetValue() const - { - return m_value; - } + AZStd::unique_ptr m_scene; - void SetValue(double value) - { - m_value = value; - } + MockBuilder() + { + m_scene = AZStd::make_unique("unit_scene"); + } - static void Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("value", &MockManifestRule::m_value); - } - } + ~MockBuilder() + { + m_scene.reset(); + } - private: - double m_value = 0.0; - }; + void BuildSceneGraph() + { + m_scene->SetManifestFilename("manifest_filename"); + m_scene->SetSource("unit_source_filename", azrtti_typeid()); + + auto& graph = m_scene->GetGraph(); + + /*----------------------------\ + | Root | + | / \ | + | | | | + | A B | + | | /|\ | + | C I J K | + | / | \ \ | + | D E F L | + | / \ | + | G H | + \----------------------------*/ + + //Build up the graph + const auto indexA = graph.AddChild(graph.GetRoot(), "A", AZStd::make_shared(1)); + const auto indexC = graph.AddChild(indexA, "C", AZStd::make_shared(3)); + const auto indexE = graph.AddChild(indexC, "E", AZStd::make_shared(4)); + graph.AddChild(indexC, "D", AZStd::make_shared(5)); + graph.AddChild(indexC, "F", AZStd::make_shared(6)); + graph.AddChild(indexE, "G", AZStd::make_shared(7)); + graph.AddChild(indexE, "H", AZStd::make_shared(8)); + const auto indexB = graph.AddChild(graph.GetRoot(), "B", AZStd::make_shared(2)); + const auto indexK = graph.AddChild(indexB, "K", AZStd::make_shared(2)); + graph.AddChild(indexB, "I", AZStd::make_shared(9)); + graph.AddChild(indexB, "J", AZStd::make_shared(10)); + graph.AddChild(indexK, "L", AZStd::make_shared(12)); + + m_scene->GetManifest().AddEntry(AZStd::make_shared(0.1)); + m_scene->GetManifest().AddEntry(AZStd::make_shared(2.3)); + m_scene->GetManifest().AddEntry(AZStd::make_shared(4.5)); + } - struct MockBuilder final + static void Reflect(ReflectContext* context) + { + BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) { - AZ_TYPE_INFO(MockBuilder, "{ECF0FB2C-E5C0-4B89-993C-8511A7EF6894}"); + behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Method("BuildSceneGraph", [](MockBuilder& self) + { + return self.BuildSceneGraph(); + }) + ->Method("GetScene", [](MockBuilder& self) + { + return self.m_scene.get(); + }); + } + } + }; - AZStd::unique_ptr m_scene; + class SceneGraphBehaviorTest + : public ::testing::Test + { + public: + void SetUp() override + { + m_behaviorContext = AZStd::make_unique(); + ReflectBehavior(m_behaviorContext.get()); + } - MockBuilder() - { - m_scene = AZStd::make_unique("unit_scene"); - } + void TearDown() override + { + m_behaviorContext.reset(); + } - ~MockBuilder() - { - m_scene.reset(); - } + AZ::BehaviorClass* GetBehaviorClass(const AZ::TypeId& behaviorClassType) + { + auto entry = m_behaviorContext->m_typeToClassMap.find(behaviorClassType); + return (entry != m_behaviorContext->m_typeToClassMap.end()) ? entry->second : nullptr; + } - void BuildSceneGraph() - { - m_scene->SetManifestFilename("manifest_filename"); - m_scene->SetSource("unit_source_filename", azrtti_typeid()); - - auto& graph = m_scene->GetGraph(); - - /*----------------------------\ - | Root | - | / \ | - | | | | - | A B | - | | /|\ | - | C I J K | - | / | \ \ | - | D E F L | - | / \ | - | G H | - \----------------------------*/ - - //Build up the graph - const auto indexA = graph.AddChild(graph.GetRoot(), "A", AZStd::make_shared(1)); - const auto indexC = graph.AddChild(indexA, "C", AZStd::make_shared(3)); - const auto indexE = graph.AddChild(indexC, "E", AZStd::make_shared(4)); - graph.AddChild(indexC, "D", AZStd::make_shared(5)); - graph.AddChild(indexC, "F", AZStd::make_shared(6)); - graph.AddChild(indexE, "G", AZStd::make_shared(7)); - graph.AddChild(indexE, "H", AZStd::make_shared(8)); - const auto indexB = graph.AddChild(graph.GetRoot(), "B", AZStd::make_shared(2)); - const auto indexK = graph.AddChild(indexB, "K", AZStd::make_shared(2)); - graph.AddChild(indexB, "I", AZStd::make_shared(9)); - graph.AddChild(indexB, "J", AZStd::make_shared(10)); - graph.AddChild(indexK, "L", AZStd::make_shared(12)); - - m_scene->GetManifest().AddEntry(AZStd::make_shared(0.1)); - m_scene->GetManifest().AddEntry(AZStd::make_shared(2.3)); - m_scene->GetManifest().AddEntry(AZStd::make_shared(4.5)); - } + AZ::BehaviorProperty* GetBehaviorProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName) + { + auto entry = behaviorClass.m_properties.find(propertyName); + return (entry != behaviorClass.m_properties.end()) ? entry->second : nullptr; + } - static void Reflect(ReflectContext* context) - { - BehaviorContext* behaviorContext = azrtti_cast(context); - if (behaviorContext) - { - behaviorContext->Class() - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) - ->Attribute(AZ::Script::Attributes::Module, "scene") - ->Method("BuildSceneGraph", [](MockBuilder& self) - { - return self.BuildSceneGraph(); - }) - ->Method("GetScene", [](MockBuilder& self) - { - return self.m_scene.get(); - }); - } - } - }; + bool HasBehaviorClass(const AZ::TypeId& behaviorClassType) + { + return GetBehaviorClass(behaviorClassType) != nullptr; + } - class SceneGraphBehaviorTest - : public ::testing::Test + bool HasProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName, const AZ::TypeId& propertyClassType) + { + AZ::BehaviorProperty* behaviorProperty = GetBehaviorProperty(behaviorClass, propertyName); + if (behaviorProperty) { - public: - void SetUp() override - { - m_behaviorContext = AZStd::make_unique(); - ReflectBehavior(m_behaviorContext.get()); - } + return behaviorProperty->m_getter->GetResult()->m_typeId == propertyClassType; + } + return false; + } - void TearDown() override - { - m_behaviorContext.reset(); - } + using ArgList = AZStd::vector; - AZ::BehaviorClass* GetBehaviorClass(const AZ::TypeId& behaviorClassType) - { - auto entry = m_behaviorContext->m_typeToClassMap.find(behaviorClassType); - return (entry != m_behaviorContext->m_typeToClassMap.end()) ? entry->second : nullptr; - } + bool HasMethodWithInput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const ArgList& input) + { + auto entry = behaviorClass.m_methods.find(methodName); + if (entry == behaviorClass.m_methods.end()) + { + return false; + } + AZ::BehaviorMethod* method = entry->second; - AZ::BehaviorProperty* GetBehaviorProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName) - { - auto entry = behaviorClass.m_properties.find(propertyName); - return (entry != behaviorClass.m_properties.end()) ? entry->second : nullptr; - } + const size_t methodArgsCount = method->IsMember() ? method->GetNumArguments() - 1 : method->GetNumArguments(); + if (input.size() != methodArgsCount) + { + return false; + } - bool HasBehaviorClass(const AZ::TypeId& behaviorClassType) + for (size_t argIndex = 0; argIndex < input.size(); ++argIndex) + { + const size_t thisPointerOffset = method->IsMember() ? 1 : 0; + const auto argType = method->GetArgument(argIndex + thisPointerOffset)->m_typeId; + const auto inputType = input[argIndex]; + if (inputType != argType) { - return GetBehaviorClass(behaviorClassType) != nullptr; + return false; } + } + return true; + } - bool HasProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName, const AZ::TypeId& propertyClassType) + bool HasMethodWithOutput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const AZ::TypeId& output, const ArgList& input) + { + auto entry = behaviorClass.m_methods.find(methodName); + if (entry == behaviorClass.m_methods.end()) + { + return false; + } + AZ::BehaviorMethod* method = entry->second; + if (method->HasResult()) + { + if (method->GetResult()->m_typeId != output) { - AZ::BehaviorProperty* behaviorProperty = GetBehaviorProperty(behaviorClass, propertyName); - if (behaviorProperty) - { - return behaviorProperty->m_getter->GetResult()->m_typeId == propertyClassType; - } return false; } + } + else + { + return false; + } + return HasMethodWithInput(behaviorClass, methodName, input); + } - using ArgList = AZStd::vector; + AZStd::unique_ptr m_behaviorContext; + }; - bool HasMethodWithInput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const ArgList& input) - { - auto entry = behaviorClass.m_methods.find(methodName); - if (entry == behaviorClass.m_methods.end()) - { - return false; - } - AZ::BehaviorMethod* method = entry->second; + TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_Exists) + { + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + } - const size_t methodArgsCount = method->IsMember() ? method->GetNumArguments() - 1 : method->GetNumArguments(); - if (input.size() != methodArgsCount) - { - return false; - } + TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_HasExpectedProperties) + { + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasProperty(*behaviorClass, "name", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "manifestFilename", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "sourceFilename", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "sourceGuid", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "graph", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "manifest", azrtti_typeid())); + } - for (size_t argIndex = 0; argIndex < input.size(); ++argIndex) - { - const size_t thisPointerOffset = method->IsMember() ? 1 : 0; - const auto argType = method->GetArgument(argIndex + thisPointerOffset)->m_typeId; - const auto inputType = input[argIndex]; - if (inputType != argType) - { - return false; - } - } - return true; - } + TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_Exists) + { + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + } - bool HasMethodWithOutput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const AZ::TypeId& output, const ArgList& input) - { - auto entry = behaviorClass.m_methods.find(methodName); - if (entry == behaviorClass.m_methods.end()) - { - return false; - } - AZ::BehaviorMethod* method = entry->second; - if (method->HasResult()) - { - if (method->GetResult()->m_typeId != output) - { - return false; - } - } - else - { - return false; - } - return HasMethodWithInput(behaviorClass, methodName, input); - } + TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_HasExpectedProperties) + { + using namespace AZ::SceneAPI::Containers; + + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeName", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetRoot", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeContent", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeSibling", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeChild", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeParent", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsNodeEndPoint", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeCount", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "GetNodeParent", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "GetNodeSibling", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "GetNodeChild", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "FindWithPath", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "FindWithRootAndPath", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid(), azrtti_typeid() } + )); + } - AZStd::unique_ptr m_behaviorContext; - }; + TEST_F(SceneGraphBehaviorTest, SceneGraphNodeIndexClass_BehaviorContext_HasExpectedProperties) + { + using namespace AZ::SceneAPI::Containers; + + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "AsNumber", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Distance", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsValid", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Equal", azrtti_typeid(), { azrtti_typeid() })); + } - TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_Exists) - { - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - } + TEST_F(SceneGraphBehaviorTest, SceneGraphNameClass_BehaviorContext_HasExpectedProperties) + { + using namespace AZ::SceneAPI::Containers; - TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_HasExpectedProperties) - { - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasProperty(*behaviorClass, "name", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "manifestFilename", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "sourceFilename", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "sourceGuid", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "graph", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "manifest", azrtti_typeid())); - } + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetPath", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetName", azrtti_typeid(), {})); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_Exists) - { - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - } + class MockSceneComponentApplication + : public AZ::ComponentApplicationBus::Handler + { + public: + MockSceneComponentApplication() + { + AZ::ComponentApplicationBus::Handler::BusConnect(); + AZ::Interface::Register(this); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_HasExpectedProperties) - { - using namespace AZ::SceneAPI::Containers; - - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeName", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetRoot", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeContent", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeSibling", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeChild", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeParent", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsNodeEndPoint", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeCount", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "GetNodeParent", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "GetNodeSibling", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "GetNodeChild", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "FindWithPath", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "FindWithRootAndPath", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid(), azrtti_typeid() } - )); - } + ~MockSceneComponentApplication() + { + AZ::Interface::Unregister(this); + AZ::ComponentApplicationBus::Handler::BusDisconnect(); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphNodeIndexClass_BehaviorContext_HasExpectedProperties) - { - using namespace AZ::SceneAPI::Containers; - - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "AsNumber", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Distance", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsValid", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Equal", azrtti_typeid(), { azrtti_typeid() })); - } + MOCK_METHOD1(FindEntity, AZ::Entity* (const AZ::EntityId&)); + MOCK_METHOD1(AddEntity, bool(AZ::Entity*)); + MOCK_METHOD0(Destroy, void()); + MOCK_METHOD1(RegisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); + MOCK_METHOD1(UnregisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); + MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityActivatedEventHandler, void(AZ::EntityActivatedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityDeactivatedEventHandler, void(AZ::EntityDeactivatedEvent::Handler&)); + MOCK_METHOD1(SignalEntityActivated, void(AZ::Entity*)); + MOCK_METHOD1(SignalEntityDeactivated, void(AZ::Entity*)); + MOCK_METHOD1(RemoveEntity, bool(AZ::Entity*)); + MOCK_METHOD1(DeleteEntity, bool(const AZ::EntityId&)); + MOCK_METHOD1(GetEntityName, AZStd::string(const AZ::EntityId&)); + MOCK_METHOD1(EnumerateEntities, void(const ComponentApplicationRequests::EntityCallback&)); + MOCK_METHOD0(GetApplication, AZ::ComponentApplication* ()); + MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ()); + MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ()); + MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ()); + MOCK_CONST_METHOD0(GetAppRoot, const char*()); + MOCK_CONST_METHOD0(GetEngineRoot, const char*()); + MOCK_CONST_METHOD0(GetExecutableFolder, const char* ()); + MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ()); + MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&)); + }; + + class MockEditorPythonConsoleInterface final + : public AzToolsFramework::EditorPythonConsoleInterface + { + public: + MockEditorPythonConsoleInterface() + { + AZ::Interface::Register(this); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphNameClass_BehaviorContext_HasExpectedProperties) - { - using namespace AZ::SceneAPI::Containers; + ~MockEditorPythonConsoleInterface() + { + AZ::Interface::Unregister(this); + } - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetPath", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetName", azrtti_typeid(), {})); - } + MOCK_CONST_METHOD1(GetModuleList, void(AZStd::vector&)); + MOCK_CONST_METHOD1(GetGlobalFunctionList, void(GlobalFunctionCollection&)); + MOCK_METHOD1(FetchPythonTypeName, AZStd::string(const AZ::BehaviorParameter&)); + }; - class MockSceneComponentApplication - : public AZ::ComponentApplicationBus::Handler - { - public: - MockSceneComponentApplication() - { - AZ::ComponentApplicationBus::Handler::BusConnect(); - AZ::Interface::Register(this); - } + // + // SceneGraphBehaviorScriptTest + // + class SceneGraphBehaviorScriptTest + : public UnitTest::AllocatorsFixture + { + public: + AZStd::unique_ptr m_componentApplication; + AZStd::unique_ptr m_editorPythonConsoleInterface; + AZStd::unique_ptr m_scriptContext; + AZStd::unique_ptr m_behaviorContext; + AZStd::unique_ptr m_serializeContext; + + static void TestExpectTrue(bool value) + { + EXPECT_TRUE(value); + } - ~MockSceneComponentApplication() - { - AZ::Interface::Unregister(this); - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - } + static void TestExpectEquals(AZ::s64 lhs, AZ::s64 rhs) + { + EXPECT_EQ(lhs, rhs); + } - MOCK_METHOD1(FindEntity, AZ::Entity* (const AZ::EntityId&)); - MOCK_METHOD1(AddEntity, bool(AZ::Entity*)); - MOCK_METHOD0(Destroy, void()); - MOCK_METHOD1(RegisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); - MOCK_METHOD1(UnregisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); - MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityActivatedEventHandler, void(AZ::EntityActivatedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityDeactivatedEventHandler, void(AZ::EntityDeactivatedEvent::Handler&)); - MOCK_METHOD1(SignalEntityActivated, void(AZ::Entity*)); - MOCK_METHOD1(SignalEntityDeactivated, void(AZ::Entity*)); - MOCK_METHOD1(RemoveEntity, bool(AZ::Entity*)); - MOCK_METHOD1(DeleteEntity, bool(const AZ::EntityId&)); - MOCK_METHOD1(GetEntityName, AZStd::string(const AZ::EntityId&)); - MOCK_METHOD1(EnumerateEntities, void(const ComponentApplicationRequests::EntityCallback&)); - MOCK_METHOD0(GetApplication, AZ::ComponentApplication* ()); - MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ()); - MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ()); - MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ()); - MOCK_CONST_METHOD0(GetAppRoot, const char*()); - MOCK_CONST_METHOD0(GetEngineRoot, const char*()); - MOCK_CONST_METHOD0(GetExecutableFolder, const char* ()); - MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ()); - MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&)); - }; - - class MockEditorPythonConsoleInterface final - : public AzToolsFramework::EditorPythonConsoleInterface + static void ReflectTestTypes(AZ::ReflectContext* context) + { + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) { - public: - MockEditorPythonConsoleInterface() - { - AZ::Interface::Register(this); - } + behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene.graph.test") + ->Method("GetId", [](const DataTypes::MockIGraphObject& self) + { + return self.m_id; + }) + ->Method("SetId", [](DataTypes::MockIGraphObject& self, int value) + { + self.m_id = value; + }) + ->Method("AddAndSet", [](DataTypes::MockIGraphObject& self, int lhs, int rhs) + { + self.m_id = lhs + rhs; + }); + } + } - ~MockEditorPythonConsoleInterface() - { - AZ::Interface::Unregister(this); - } + void SetUp() override + { + UnitTest::AllocatorsFixture::SetUp(); - MOCK_CONST_METHOD1(GetModuleList, void(AZStd::vector&)); - MOCK_CONST_METHOD1(GetGlobalFunctionList, void(GlobalFunctionCollection&)); - MOCK_METHOD1(FetchPythonTypeName, AZStd::string(const AZ::BehaviorParameter&)); - }; + m_serializeContext = AZStd::make_unique(); - // - // SceneGraphBehaviorScriptTest - // - class SceneGraphBehaviorScriptTest - : public UnitTest::AllocatorsFixture - { - public: - AZStd::unique_ptr m_componentApplication; - AZStd::unique_ptr m_editorPythonConsoleInterface; - AZStd::unique_ptr m_scriptContext; - AZStd::unique_ptr m_behaviorContext; - AZStd::unique_ptr m_serializeContext; - - static void TestExpectTrue(bool value) - { - EXPECT_TRUE(value); - } + m_behaviorContext = AZStd::make_unique(); + m_behaviorContext->Method("TestExpectTrue", &TestExpectTrue); + m_behaviorContext->Method("TestExpectEquals", &TestExpectEquals); - static void TestExpectEquals(AZ::s64 lhs, AZ::s64 rhs) - { - EXPECT_EQ(lhs, rhs); - } + AZ::MathReflect(m_behaviorContext.get()); + ReflectBehavior(m_behaviorContext.get()); + ReflectTestTypes(m_behaviorContext.get()); + MockBuilder::Reflect(m_behaviorContext.get()); - static void ReflectTestTypes(AZ::ReflectContext* context) - { - AZ::BehaviorContext* behaviorContext = azrtti_cast(context); - if (behaviorContext) + m_scriptContext = AZStd::make_unique(); + m_scriptContext->BindTo(m_behaviorContext.get()); + + m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); + + ON_CALL(*m_componentApplication, GetBehaviorContext()) + .WillByDefault(::testing::Invoke([this]() { - behaviorContext->Class() - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) - ->Attribute(AZ::Script::Attributes::Module, "scene.graph.test") - ->Method("GetId", [](const DataTypes::MockIGraphObject& self) - { - return self.m_id; - }) - ->Method("SetId", [](DataTypes::MockIGraphObject& self, int value) - { - self.m_id = value; - }) - ->Method("AddAndSet", [](DataTypes::MockIGraphObject& self, int lhs, int rhs) - { - self.m_id = lhs + rhs; - }); - } - } + return this->m_behaviorContext.get(); + })); - void SetUp() override - { - UnitTest::AllocatorsFixture::SetUp(); + ON_CALL(*m_componentApplication, GetSerializeContext()) + .WillByDefault(::testing::Invoke([this]() + { + return this->m_serializeContext.get(); + })); - m_serializeContext = AZStd::make_unique(); + m_editorPythonConsoleInterface = AZStd::make_unique(); + } - m_behaviorContext = AZStd::make_unique(); - m_behaviorContext->Method("TestExpectTrue", &TestExpectTrue); - m_behaviorContext->Method("TestExpectEquals", &TestExpectEquals); + void SetupEditorPythonConsoleInterface() + { + EXPECT_CALL(*m_editorPythonConsoleInterface, FetchPythonTypeName(::testing::_)) + .Times(4) + .WillRepeatedly(::testing::Invoke([](const AZ::BehaviorParameter&) {return "int"; })); + } - AZ::MathReflect(m_behaviorContext.get()); - ReflectBehavior(m_behaviorContext.get()); - ReflectTestTypes(m_behaviorContext.get()); - MockBuilder::Reflect(m_behaviorContext.get()); + void TearDown() override + { + m_scriptContext.reset(); + m_serializeContext.reset(); + m_behaviorContext.reset(); - m_scriptContext = AZStd::make_unique(); - m_scriptContext->BindTo(m_behaviorContext.get()); + UnitTest::AllocatorsFixture::TearDown(); + } - m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); + void ExpectExecute(AZStd::string_view script) + { + EXPECT_TRUE(m_scriptContext->Execute(script.data())); + } + }; - ON_CALL(*m_componentApplication, GetBehaviorContext()) - .WillByDefault(::testing::Invoke([this]() - { - return this->m_behaviorContext.get(); - })); + TEST_F(SceneGraphBehaviorScriptTest, Scene_ScriptContext_Access) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("TestExpectTrue(scene ~= nil)"); + ExpectExecute("TestExpectTrue(scene.name == 'unit_scene')"); + ExpectExecute("TestExpectTrue(scene.manifestFilename == 'manifest_filename')"); + ExpectExecute("TestExpectTrue(scene.sourceFilename == 'unit_source_filename')"); + ExpectExecute("TestExpectTrue(tostring(scene.sourceGuid) == '{1F2E6142-B0D8-42C6-A6E5-CD726DAA9EF0}')"); + ExpectExecute("TestExpectTrue(scene:GetOriginalSceneOrientation() == Scene.SceneOrientation_YUp)"); + } - ON_CALL(*m_componentApplication, GetSerializeContext()) - .WillByDefault(::testing::Invoke([this]() - { - return this->m_serializeContext.get(); - })); + TEST_F(SceneGraphBehaviorScriptTest, SceneGraph_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + + // instance methods + ExpectExecute("TestExpectTrue(scene.graph ~= nil)"); + ExpectExecute("TestExpectTrue(scene.graph:GetRoot():IsValid())"); + ExpectExecute("TestExpectEquals(scene.graph:GetNodeCount(), 13)"); + ExpectExecute("nodeRoot = scene.graph:GetRoot()"); + ExpectExecute("nodeA = scene.graph:GetNodeChild(nodeRoot); TestExpectTrue(nodeA:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeContent(nodeA))"); + ExpectExecute("nodeC = scene.graph:GetNodeChild(nodeA); TestExpectTrue(nodeC:IsValid())"); + ExpectExecute("nodeNameC = scene.graph:GetNodeName(nodeC); TestExpectTrue(nodeNameC ~= nil)"); + ExpectExecute("nodeE = scene.graph:GetNodeChild(nodeC); TestExpectTrue(nodeE:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeSibling(nodeE))"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeChild(nodeE))"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeParent(nodeE))"); + ExpectExecute("nodeG = scene.graph:GetNodeChild(nodeE); TestExpectTrue(nodeG:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:GetNodeParent(nodeG) == nodeE)"); + ExpectExecute("nodeH = scene.graph:GetNodeSibling(nodeG); TestExpectTrue(nodeH:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:GetNodeName(nodeH):GetPath() == 'A.C.E.H')"); + ExpectExecute("nodeB = scene.graph:GetNodeSibling(nodeA); TestExpectTrue(nodeB:IsValid())"); + ExpectExecute("nodeK = scene.graph:GetNodeChild(nodeB); TestExpectTrue(nodeK:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:FindWithPath('B.K') == nodeK)"); + ExpectExecute("nodeL = scene.graph:GetNodeChild(nodeK); TestExpectTrue(nodeL:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:FindWithRootAndPath(nodeK, 'L') == nodeL)"); + + // static methods + ExpectExecute("TestExpectTrue(scene.graph.IsValidName('A'))"); + ExpectExecute("TestExpectTrue(scene.graph.GetNodeSeperationCharacter() == string.byte('.'))"); + } - m_editorPythonConsoleInterface = AZStd::make_unique(); - } + TEST_F(SceneGraphBehaviorScriptTest, SceneGraphNodeIndex_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeA = scene.graph:GetNodeChild(scene.graph:GetRoot())"); + ExpectExecute("TestExpectTrue(nodeA:IsValid())"); + ExpectExecute("TestExpectEquals(nodeA:AsNumber(), 1)"); + ExpectExecute("TestExpectEquals(scene.graph:GetRoot():Distance(nodeA), 1)"); + ExpectExecute("TestExpectEquals(nodeA:Distance(scene.graph:GetRoot()), -1)"); + ExpectExecute("TestExpectTrue(nodeA == scene.graph:FindWithPath('A'))"); + } - void SetupEditorPythonConsoleInterface() - { - EXPECT_CALL(*m_editorPythonConsoleInterface, FetchPythonTypeName(::testing::_)) - .Times(4) - .WillRepeatedly(::testing::Invoke([](const AZ::BehaviorParameter&) {return "int"; })); - } + TEST_F(SceneGraphBehaviorScriptTest, SceneGraphName_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("nodeNameG = scene.graph:GetNodeName(nodeG)"); + ExpectExecute("TestExpectTrue(nodeNameG:GetPath() == 'A.C.E.G')"); + ExpectExecute("TestExpectTrue(nodeNameG:GetName() == 'G')"); + } - void TearDown() override - { - m_scriptContext.reset(); - m_serializeContext.reset(); - m_behaviorContext.reset(); + TEST_F(SceneGraphBehaviorScriptTest, SceneGraphIGraphNode_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); + ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); + ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); + ExpectExecute("TestExpectEquals(value, 7)"); + ExpectExecute("setIdArgs = vector_any(); setIdArgs:push_back(8);"); + ExpectExecute("proxy:Invoke('SetId', setIdArgs)"); + ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); + ExpectExecute("TestExpectEquals(value, 8)"); + ExpectExecute("addArgs = vector_any(); addArgs:push_back(8); addArgs:push_back(9)"); + ExpectExecute("proxy:Invoke('AddAndSet', addArgs)"); + ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); + ExpectExecute("TestExpectEquals(value, 17)"); + } - UnitTest::AllocatorsFixture::TearDown(); - } + TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_Loads) + { + SetupEditorPythonConsoleInterface(); + + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); + ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); + ExpectExecute("info = proxy:GetClassInfo()"); + ExpectExecute("TestExpectTrue(info ~= nil)"); + } - void ExpectExecute(AZStd::string_view script) - { - EXPECT_TRUE(m_scriptContext->Execute(script.data())); - } - }; + TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_CorrectFormats) + { + SetupEditorPythonConsoleInterface(); + + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); + ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); + ExpectExecute("info = proxy:GetClassInfo()"); + ExpectExecute("TestExpectTrue(info.className == 'MockIGraphObject')"); + ExpectExecute("TestExpectTrue(info.classUuid == '{66A082CC-851D-4E1F-ABBD-45B58A216CFA}')"); + ExpectExecute("TestExpectTrue(info.methodList[1] == 'def GetId(self) -> int')"); + ExpectExecute("TestExpectTrue(info.methodList[2] == 'def SetId(self, arg1: int) -> None')"); + ExpectExecute("TestExpectTrue(info.methodList[3] == 'def AddAndSet(self, arg1: int, arg2: int) -> None')"); + } - TEST_F(SceneGraphBehaviorScriptTest, Scene_ScriptContext_Access) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("TestExpectTrue(scene ~= nil)"); - ExpectExecute("TestExpectTrue(scene.name == 'unit_scene')"); - ExpectExecute("TestExpectTrue(scene.manifestFilename == 'manifest_filename')"); - ExpectExecute("TestExpectTrue(scene.sourceFilename == 'unit_source_filename')"); - ExpectExecute("TestExpectTrue(tostring(scene.sourceGuid) == '{1F2E6142-B0D8-42C6-A6E5-CD726DAA9EF0}')"); - ExpectExecute("TestExpectTrue(scene:GetOriginalSceneOrientation() == Scene.SceneOrientation_YUp)"); - } + TEST_F(SceneGraphBehaviorScriptTest, ExportProduct_ExpectedClassesAndFields_Work) + { + ExpectExecute("mockAssetType = Uuid.CreateString('{B7AD6A54-963F-4F0F-A70E-1CFC0364BE6B}')"); + ExpectExecute("exportProduct = ExportProduct()"); + ExpectExecute("exportProduct.filename = 'some/file.name'"); + ExpectExecute("exportProduct.sourceId = Uuid.CreateString('{A19F5FDB-C5FB-478F-A0B0-B697D2C10DB5}', 0)"); + ExpectExecute("exportProduct.assetType = mockAssetType"); + ExpectExecute("exportProduct.subId = 10101"); + ExpectExecute("TestExpectEquals(exportProduct.subId, 10101)"); + ExpectExecute("TestExpectEquals(exportProduct.productDependencies:GetSize(), 0)"); + + ExpectExecute("exportProductDep = ExportProduct()"); + ExpectExecute("exportProductDep.filename = 'some/file.dep'"); + ExpectExecute("exportProductDep.sourceId = Uuid.CreateString('{A19F5FDB-C5FB-478F-A0B0-B697D2C10DB5}', 0)"); + ExpectExecute("exportProductDep.assetType = mockAssetType"); + ExpectExecute("exportProductDep.subId = 2"); + + ExpectExecute("exportProductList = ExportProductList()"); + ExpectExecute("exportProductList:AddProduct(exportProduct)"); + ExpectExecute("exportProductList:AddProduct(exportProductDep)"); + ExpectExecute("productList = exportProductList:GetProducts()"); + ExpectExecute("TestExpectEquals(productList:GetSize(), 2)"); + ExpectExecute("exportProductList:AddDependencyToProduct(exportProduct.filename, exportProductDep)"); + ExpectExecute("TestExpectEquals(productList:Front().productDependencies:GetSize(), 1)"); + } - TEST_F(SceneGraphBehaviorScriptTest, SceneGraph_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - - // instance methods - ExpectExecute("TestExpectTrue(scene.graph ~= nil)"); - ExpectExecute("TestExpectTrue(scene.graph:GetRoot():IsValid())"); - ExpectExecute("TestExpectEquals(scene.graph:GetNodeCount(), 13)"); - ExpectExecute("nodeRoot = scene.graph:GetRoot()"); - ExpectExecute("nodeA = scene.graph:GetNodeChild(nodeRoot); TestExpectTrue(nodeA:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeContent(nodeA))"); - ExpectExecute("nodeC = scene.graph:GetNodeChild(nodeA); TestExpectTrue(nodeC:IsValid())"); - ExpectExecute("nodeNameC = scene.graph:GetNodeName(nodeC); TestExpectTrue(nodeNameC ~= nil)"); - ExpectExecute("nodeE = scene.graph:GetNodeChild(nodeC); TestExpectTrue(nodeE:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeSibling(nodeE))"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeChild(nodeE))"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeParent(nodeE))"); - ExpectExecute("nodeG = scene.graph:GetNodeChild(nodeE); TestExpectTrue(nodeG:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:GetNodeParent(nodeG) == nodeE)"); - ExpectExecute("nodeH = scene.graph:GetNodeSibling(nodeG); TestExpectTrue(nodeH:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:GetNodeName(nodeH):GetPath() == 'A.C.E.H')"); - ExpectExecute("nodeB = scene.graph:GetNodeSibling(nodeA); TestExpectTrue(nodeB:IsValid())"); - ExpectExecute("nodeK = scene.graph:GetNodeChild(nodeB); TestExpectTrue(nodeK:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:FindWithPath('B.K') == nodeK)"); - ExpectExecute("nodeL = scene.graph:GetNodeChild(nodeK); TestExpectTrue(nodeL:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:FindWithRootAndPath(nodeK, 'L') == nodeL)"); - - // static methods - ExpectExecute("TestExpectTrue(scene.graph.IsValidName('A'))"); - ExpectExecute("TestExpectTrue(scene.graph.GetNodeSeperationCharacter() == string.byte('.'))"); - } + // + // SceneManifestBehaviorScriptTest is meant to test the script abilities of the SceneManifest + // + class SceneManifestBehaviorScriptTest + : public UnitTest::AllocatorsFixture + { + public: + AZStd::unique_ptr m_componentApplication; + AZStd::unique_ptr m_scriptContext; + AZStd::unique_ptr m_behaviorContext; + AZStd::unique_ptr m_serializeContext; + AZStd::unique_ptr m_jsonRegistrationContext; + AZStd::string_view m_jsonMockData = R"JSON('{"values":[{"$type":"MockManifestRule","value":0.1},{"$type":"MockManifestRule","value":2.3},{"$type":"MockManifestRule","value":4.5}]}')JSON"; + + static void TestAssertTrue(bool value) + { + EXPECT_TRUE(value); + } - TEST_F(SceneGraphBehaviorScriptTest, SceneGraphNodeIndex_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeA = scene.graph:GetNodeChild(scene.graph:GetRoot())"); - ExpectExecute("TestExpectTrue(nodeA:IsValid())"); - ExpectExecute("TestExpectEquals(nodeA:AsNumber(), 1)"); - ExpectExecute("TestExpectEquals(scene.graph:GetRoot():Distance(nodeA), 1)"); - ExpectExecute("TestExpectEquals(nodeA:Distance(scene.graph:GetRoot()), -1)"); - ExpectExecute("TestExpectTrue(nodeA == scene.graph:FindWithPath('A'))"); - } + void SetUp() override + { + UnitTest::AllocatorsFixture::SetUp(); - TEST_F(SceneGraphBehaviorScriptTest, SceneGraphName_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("nodeNameG = scene.graph:GetNodeName(nodeG)"); - ExpectExecute("TestExpectTrue(nodeNameG:GetPath() == 'A.C.E.G')"); - ExpectExecute("TestExpectTrue(nodeNameG:GetName() == 'G')"); - } + m_serializeContext = AZStd::make_unique(); + MockBuilder::Reflect(m_serializeContext.get()); + MockManifestRule::Reflect(m_serializeContext.get()); + ReflectTypes(m_serializeContext.get()); - TEST_F(SceneGraphBehaviorScriptTest, SceneGraphIGraphNode_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); - ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); - ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); - ExpectExecute("TestExpectEquals(value, 7)"); - ExpectExecute("setIdArgs = vector_any(); setIdArgs:push_back(8);"); - ExpectExecute("proxy:Invoke('SetId', setIdArgs)"); - ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); - ExpectExecute("TestExpectEquals(value, 8)"); - ExpectExecute("addArgs = vector_any(); addArgs:push_back(8); addArgs:push_back(9)"); - ExpectExecute("proxy:Invoke('AddAndSet', addArgs)"); - ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); - ExpectExecute("TestExpectEquals(value, 17)"); - } + m_behaviorContext = AZStd::make_unique(); + m_behaviorContext->Method("TestAssertTrue", &TestAssertTrue); + AZ::MathReflect(m_behaviorContext.get()); + MockBuilder::Reflect(m_behaviorContext.get()); + MockManifestRule::Reflect(m_behaviorContext.get()); + ReflectBehavior(m_behaviorContext.get()); - TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_Loads) - { - SetupEditorPythonConsoleInterface(); - - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); - ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); - ExpectExecute("info = proxy:GetClassInfo()"); - ExpectExecute("TestExpectTrue(info ~= nil)"); - } + m_jsonRegistrationContext = AZStd::make_unique(); + AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); - TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_CorrectFormats) - { - SetupEditorPythonConsoleInterface(); - - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); - ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); - ExpectExecute("info = proxy:GetClassInfo()"); - ExpectExecute("TestExpectTrue(info.className == 'MockIGraphObject')"); - ExpectExecute("TestExpectTrue(info.classUuid == '{66A082CC-851D-4E1F-ABBD-45B58A216CFA}')"); - ExpectExecute("TestExpectTrue(info.methodList[1] == 'def GetId(self) -> int')"); - ExpectExecute("TestExpectTrue(info.methodList[2] == 'def SetId(self, arg1: int) -> None')"); - ExpectExecute("TestExpectTrue(info.methodList[3] == 'def AddAndSet(self, arg1: int, arg2: int) -> None')"); - } + m_scriptContext = AZStd::make_unique(); + m_scriptContext->BindTo(m_behaviorContext.get()); - // - // SceneManifestBehaviorScriptTest is meant to test the script abilities of the SceneManifest - // - class SceneManifestBehaviorScriptTest - : public UnitTest::AllocatorsFixture - { - public: - AZStd::unique_ptr m_componentApplication; - AZStd::unique_ptr m_scriptContext; - AZStd::unique_ptr m_behaviorContext; - AZStd::unique_ptr m_serializeContext; - AZStd::unique_ptr m_jsonRegistrationContext; - AZStd::string_view m_jsonMockData = R"JSON('{"values":[{"$type":"MockManifestRule","value":0.1},{"$type":"MockManifestRule","value":2.3},{"$type":"MockManifestRule","value":4.5}]}')JSON"; - - static void TestAssertTrue(bool value) - { - EXPECT_TRUE(value); - } + m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); - void SetUp() override + ON_CALL(*m_componentApplication, GetBehaviorContext()).WillByDefault(::testing::Invoke([this]() { - UnitTest::AllocatorsFixture::SetUp(); - - m_serializeContext = AZStd::make_unique(); - MockBuilder::Reflect(m_serializeContext.get()); - MockManifestRule::Reflect(m_serializeContext.get()); - ReflectTypes(m_serializeContext.get()); - - m_behaviorContext = AZStd::make_unique(); - m_behaviorContext->Method("TestAssertTrue", &TestAssertTrue); - AZ::MathReflect(m_behaviorContext.get()); - MockBuilder::Reflect(m_behaviorContext.get()); - MockManifestRule::Reflect(m_behaviorContext.get()); - ReflectBehavior(m_behaviorContext.get()); - - m_jsonRegistrationContext = AZStd::make_unique(); - AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); - - m_scriptContext = AZStd::make_unique(); - m_scriptContext->BindTo(m_behaviorContext.get()); - - m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); - - ON_CALL(*m_componentApplication, GetBehaviorContext()).WillByDefault(::testing::Invoke([this]() - { - return this->m_behaviorContext.get(); - })); - - ON_CALL(*m_componentApplication, GetSerializeContext()).WillByDefault(::testing::Invoke([this]() - { - return this->m_serializeContext.get(); - })); - - ON_CALL(*m_componentApplication, GetJsonRegistrationContext()).WillByDefault(::testing::Invoke([this]() - { - return this->m_jsonRegistrationContext.get(); - })); - } + return this->m_behaviorContext.get(); + })); - void TearDown() override + ON_CALL(*m_componentApplication, GetSerializeContext()).WillByDefault(::testing::Invoke([this]() { - m_jsonRegistrationContext->EnableRemoveReflection(); - AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); - m_jsonRegistrationContext->DisableRemoveReflection(); - - m_jsonRegistrationContext.reset(); - m_serializeContext.reset(); - m_scriptContext.reset(); - m_behaviorContext.reset(); - m_componentApplication.reset(); - UnitTest::AllocatorsFixture::TearDown(); - } + return this->m_serializeContext.get(); + })); - void ExpectExecute(AZStd::string_view script) + ON_CALL(*m_componentApplication, GetJsonRegistrationContext()).WillByDefault(::testing::Invoke([this]() { - EXPECT_TRUE(m_scriptContext->Execute(script.data())); - } - }; - - TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetDefaultJSON) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); - } + return this->m_jsonRegistrationContext.get(); + })); + } - TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetComplexJSON) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); - ExpectExecute(read); - } + void TearDown() override + { + m_jsonRegistrationContext->EnableRemoveReflection(); + AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); + m_jsonRegistrationContext->DisableRemoveReflection(); + + m_jsonRegistrationContext.reset(); + m_serializeContext.reset(); + m_scriptContext.reset(); + m_behaviorContext.reset(); + m_componentApplication.reset(); + UnitTest::AllocatorsFixture::TearDown(); + } - TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_SetComplexJSON) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); - auto load = AZStd::fixed_string<1024>::format("TestAssertTrue(scene.manifest:ImportFromJson(%s))", m_jsonMockData.data()); - ExpectExecute(load); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); - ExpectExecute(read); - } + void ExpectExecute(AZStd::string_view script) + { + EXPECT_TRUE(m_scriptContext->Execute(script.data())); } + }; + + TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetDefaultJSON) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); } -} + + TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetComplexJSON) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); + ExpectExecute(read); + } + + TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_SetComplexJSON) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); + auto load = AZStd::fixed_string<1024>::format("TestAssertTrue(scene.manifest:ImportFromJson(%s))", m_jsonMockData.data()); + ExpectExecute(load); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); + ExpectExecute(read); + } + +} // namespace AZ::SceneAPI::Containers diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp index 5ae547b577..b7fda1e0dc 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp @@ -25,213 +25,319 @@ #include #include #include +#include -namespace AZ +namespace AZ::SceneAPI::Behaviors { - namespace SceneAPI + class EditorPythonConsoleNotificationHandler final + : protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler { - namespace Behaviors + public: + EditorPythonConsoleNotificationHandler() { - class EditorPythonConsoleNotificationHandler final - : protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler - { - public: - EditorPythonConsoleNotificationHandler() - { - BusConnect(); - } + BusConnect(); + } - ~EditorPythonConsoleNotificationHandler() - { - BusDisconnect(); - } + ~EditorPythonConsoleNotificationHandler() + { + BusDisconnect(); + } - //////////////////////////////////////////////////////////////////////////////////////////// - // AzToolsFramework::EditorPythonConsoleNotifications - void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override - { - using namespace AZ::SceneAPI::Utilities; - AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message)); - } + //////////////////////////////////////////////////////////////////////////////////////////// + // AzToolsFramework::EditorPythonConsoleNotifications + void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override + { + using namespace AZ::SceneAPI::Utilities; + AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message)); + } - void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override - { - using namespace AZ::SceneAPI::Utilities; - AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message)); - } + void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override + { + using namespace AZ::SceneAPI::Utilities; + AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message)); + } - void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override - { - using namespace AZ::SceneAPI::Utilities; - AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message)); - } - }; + void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override + { + using namespace AZ::SceneAPI::Utilities; + AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message)); + } + }; - // a event bus to signal during scene building - struct ScriptBuildingNotifications - : public AZ::EBusTraits - { - virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0; - }; - using ScriptBuildingNotificationBus = AZ::EBus; + using ExportProductList = AZ::SceneAPI::Events::ExportProductList; + + // a event bus to signal during scene building + struct ScriptBuildingNotifications + : public AZ::EBusTraits + { + virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0; + virtual ExportProductList OnPrepareForExport( + const Containers::Scene& scene, + AZStd::string_view outputDirectory, + AZStd::string_view platformIdentifier, + const ExportProductList& productList) = 0; + }; + using ScriptBuildingNotificationBus = AZ::EBus; + + // a back end to handle scene builder events for a script + struct ScriptBuildingNotificationBusHandler final + : public ScriptBuildingNotificationBus::Handler + , public AZ::BehaviorEBusHandler + { + AZ_EBUS_BEHAVIOR_BINDER( + ScriptBuildingNotificationBusHandler, + "{DF2B51DE-A4D0-4139-B5D0-DF185832380D}", + AZ::SystemAllocator, + OnUpdateManifest, + OnPrepareForExport); - // a back end to handle scene builder events for a script - struct ScriptBuildingNotificationBusHandler final - : public ScriptBuildingNotificationBus::Handler - , public AZ::BehaviorEBusHandler + virtual ~ScriptBuildingNotificationBusHandler() = default; + + AZStd::string OnUpdateManifest(Containers::Scene& scene) override + { + AZStd::string result; + CallResult(result, FN_OnUpdateManifest, scene); + return result; + } + + ExportProductList OnPrepareForExport( + const Containers::Scene& scene, + AZStd::string_view outputDirectory, + AZStd::string_view platformIdentifier, + const ExportProductList& productList) override + { + ExportProductList result; + CallResult(result, FN_OnPrepareForExport, scene, outputDirectory, platformIdentifier, productList); + return result; + } + + static void Reflect(AZ::ReflectContext* context) + { + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { - AZ_EBUS_BEHAVIOR_BINDER( - ScriptBuildingNotificationBusHandler, - "{DF2B51DE-A4D0-4139-B5D0-DF185832380D}", - AZ::SystemAllocator, - OnUpdateManifest); + behaviorContext->EBus("ScriptBuildingNotificationBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Handler() + ->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest) + ->Event("OnPrepareForExport", &ScriptBuildingNotificationBus::Events::OnPrepareForExport); + } + } + }; - virtual ~ScriptBuildingNotificationBusHandler() = default; + struct ScriptProcessorRuleBehavior::ExportEventHandler final + : public AZ::SceneAPI::SceneCore::ExportingComponent + { + using PreExportEventContextFunction = AZStd::function; + PreExportEventContextFunction m_preExportEventContextFunction; - AZStd::string OnUpdateManifest(Containers::Scene& scene) override - { - AZStd::string result; - CallResult(result, FN_OnUpdateManifest, scene); - return result; - } + ExportEventHandler(PreExportEventContextFunction preExportEventContextFunction) + : m_preExportEventContextFunction(preExportEventContextFunction) + { + BindToCall(&ExportEventHandler::PrepareForExport); + AZ::SceneAPI::SceneCore::ExportingComponent::Activate(); + } - static void Reflect(AZ::ReflectContext* context) - { - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("ScriptBuildingNotificationBus") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) - ->Attribute(AZ::Script::Attributes::Module, "scene") - ->Handler() - ->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest); - } - } - }; + ~ExportEventHandler() + { + AZ::SceneAPI::SceneCore::ExportingComponent::Deactivate(); + } + + // this allows a Python script to add product assets on "scene export" + Events::ProcessingResult PrepareForExport(Events::PreExportEventContext& context) + { + return m_preExportEventContextFunction(context) ? Events::ProcessingResult::Success : Events::ProcessingResult::Failure; + } + }; + + void ScriptProcessorRuleBehavior::Activate() + { + Events::AssetImportRequestBus::Handler::BusConnect(); + m_exportEventHandler = AZStd::make_shared([this](Events::PreExportEventContext& context) + { + return this->DoPrepareForExport(context); + }); + } + + void ScriptProcessorRuleBehavior::Deactivate() + { + m_exportEventHandler.reset(); + Events::AssetImportRequestBus::Handler::BusDisconnect(); + UnloadPython(); + } + + bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene) + { + if (m_editorPythonEventsInterface && !m_scriptFilename.empty()) + { + return true; + } + + // get project folder + auto settingsRegistry = AZ::SettingsRegistry::Get(); + AZ::IO::FixedMaxPath projectPath; + if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath)) + { + return false; + } - void ScriptProcessorRuleBehavior::Activate() + const AZ::SceneAPI::Containers::SceneManifest& manifest = scene.GetManifest(); + auto view = Containers::MakeDerivedFilterView(manifest.GetValueStorage()); + for (const auto& scriptItem : view) + { + AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename()); + if (scriptFilename.empty()) { - Events::AssetImportRequestBus::Handler::BusConnect(); + AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str()); + continue; } - void ScriptProcessorRuleBehavior::Deactivate() + // check for file exist via absolute path + if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str())) { - Events::AssetImportRequestBus::Handler::BusDisconnect(); - if (m_editorPythonEventsInterface) + // check for script in the project folder + AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename; + if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str())) { - const bool silenceWarnings = true; - m_editorPythonEventsInterface->StopPython(silenceWarnings); - m_editorPythonEventsInterface = nullptr; - + AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)", + scriptFilename.c_str(), + scene.GetManifestFilename().c_str()); + continue; } + scriptFilename = AZStd::move(projectScriptPath); } - void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context) + // lazy load the Python interface + auto editorPythonEventsInterface = AZ::Interface::Get(); + if (editorPythonEventsInterface->IsPythonActive() == false) { - ScriptBuildingNotificationBusHandler::Reflect(context); - - SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) + const bool silenceWarnings = false; + if (editorPythonEventsInterface->StartPython(silenceWarnings) == false) { - serializeContext->Class()->Version(1); + editorPythonEventsInterface = nullptr; } } - Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest( - Containers::Scene& scene, - Events::AssetImportRequest::ManifestAction action, - [[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester) + // both Python and the script need to be ready + if (editorPythonEventsInterface == nullptr || scriptFilename.empty()) { - using namespace AzToolsFramework; + AZ_Warning("scene", false,"The scene manifest (%s) attempted to use script(%s) but Python is not enabled;" + "please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.", + scene.GetManifestFilename().c_str(), scriptFilename.c_str()); - if (action != ManifestAction::Update) - { - return Events::ProcessingResult::Ignored; - } + return false; + } - // get project folder - auto settingsRegistry = AZ::SettingsRegistry::Get(); - AZ::IO::FixedMaxPath projectPath; - if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath)) - { - return Events::ProcessingResult::Ignored; - } + m_editorPythonEventsInterface = editorPythonEventsInterface; + m_scriptFilename = scriptFilename.c_str(); + return true; + } + return false; + } + + void ScriptProcessorRuleBehavior::UnloadPython() + { + if (m_editorPythonEventsInterface) + { + const bool silenceWarnings = true; + m_editorPythonEventsInterface->StopPython(silenceWarnings); + m_editorPythonEventsInterface = nullptr; + } + } + + bool ScriptProcessorRuleBehavior::DoPrepareForExport(Events::PreExportEventContext& context) + { + using namespace AzToolsFramework; + + auto executeCallback = [this, &context]() + { + // set up script's hook callback + EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename, + m_scriptFilename.c_str()); + + // call script's callback to allow extra products + ExportProductList extraProducts; + ScriptBuildingNotificationBus::BroadcastResult(extraProducts, &ScriptBuildingNotificationBus::Events::OnPrepareForExport, + context.GetScene(), + context.GetOutputDirectory(), + context.GetPlatformIdentifier(), + context.GetProductList() + ); - auto& sceneManifest = scene.GetManifest(); - auto view = Containers::MakeDerivedFilterView(sceneManifest.GetValueStorage()); - for (const auto& scriptItem : view) + // add new products + for (const auto& product : extraProducts.GetProducts()) + { + context.GetProductList().AddProduct( + product.m_filename, + product.m_id, + product.m_assetType, + product.m_lod, + product.m_subId, + product.m_dependencyFlags); + } + }; + + if (LoadPython(context.GetScene())) + { + EditorPythonConsoleNotificationHandler logger; + m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); + } + + return true; + } + + void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context) + { + ScriptBuildingNotificationBusHandler::Reflect(context); + + SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) + { + serializeContext->Class()->Version(1); + } + } + + Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest( + Containers::Scene& scene, + Events::AssetImportRequest::ManifestAction action, + [[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester) + { + using namespace AzToolsFramework; + + if (action != ManifestAction::Update) + { + return Events::ProcessingResult::Ignored; + } + + if (LoadPython(scene)) + { + AZStd::string manifestUpdate; + auto executeCallback = [this, &scene, &manifestUpdate]() + { + EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename, + m_scriptFilename.c_str()); + + ScriptBuildingNotificationBus::BroadcastResult(manifestUpdate, &ScriptBuildingNotificationBus::Events::OnUpdateManifest, + scene); + }; + + EditorPythonConsoleNotificationHandler logger; + m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); + + // attempt to load the manifest string back to a JSON-scene-manifest + auto sceneManifestLoader = AZStd::make_unique(); + auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate); + if (loadOutcome.IsSuccess()) + { + scene.GetManifest().Clear(); + for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex) { - AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename()); - if (scriptFilename.empty()) - { - AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str()); - continue; - } - - // check for file exist via absolute path - if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str())) - { - // check for script in the project folder - AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename; - if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str())) - { - AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)", - scriptFilename.c_str(), - scene.GetManifestFilename().c_str()); - - continue; - } - scriptFilename = AZStd::move(projectScriptPath); - } - - // lazy load the Python interface - if (!m_editorPythonEventsInterface) - { - m_editorPythonEventsInterface = AZ::Interface::Get(); - const bool silenceWarnings = true; - m_editorPythonEventsInterface->StartPython(silenceWarnings); - } - - if (!m_editorPythonEventsInterface && !scriptFilename.empty()) - { - AZ_Warning("scene", false, - "The scene manifest (%s) attempted to use script(%s) but Python is not enabled;" - "please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.", - scene.GetManifestFilename().c_str(), scriptFilename.c_str()); - - return Events::ProcessingResult::Ignored; - } - - AZStd::string manifestUpdate; - auto executeCallback = [&scene, &scriptFilename, &manifestUpdate]() - { - EditorPythonRunnerRequestBus::Broadcast( - &EditorPythonRunnerRequestBus::Events::ExecuteByFilename, - scriptFilename.c_str()); - - ScriptBuildingNotificationBus::BroadcastResult( - manifestUpdate, - &ScriptBuildingNotificationBus::Events::OnUpdateManifest, - scene); - }; - EditorPythonConsoleNotificationHandler logger; - m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); - - // attempt to load the manifest string back to a JSON-scene-manifest - auto sceneManifestLoader = AZStd::make_unique(); - auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate); - if (loadOutcome.IsSuccess()) - { - sceneManifest.Clear(); - for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex) - { - sceneManifest.AddEntry(sceneManifestLoader->GetValue(entryIndex)); - } - return Events::ProcessingResult::Success; - } + scene.GetManifest().AddEntry(sceneManifestLoader->GetValue(entryIndex)); } - return Events::ProcessingResult::Ignored; + return Events::ProcessingResult::Success; } + } + return Events::ProcessingResult::Ignored; + } - } // namespace Behaviors - } // namespace SceneAPI } // namespace AZ diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h index da11614459..9dd1f5b970 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h @@ -11,40 +11,56 @@ #include #include #include +#include +#include namespace AzToolsFramework { class EditorPythonEventsInterface; } -namespace AZ +namespace AZ::SceneAPI::Events { - namespace SceneAPI + class PreExportEventContext; +} + +namespace AZ::SceneAPI::Containers +{ + class Scene; +} + +namespace AZ::SceneAPI::Behaviors +{ + class SCENE_DATA_CLASS ScriptProcessorRuleBehavior + : public SceneCore::BehaviorComponent + , public Events::AssetImportRequestBus::Handler { - namespace Behaviors - { - class SCENE_DATA_CLASS ScriptProcessorRuleBehavior - : public SceneCore::BehaviorComponent - , public Events::AssetImportRequestBus::Handler - { - public: - AZ_COMPONENT(ScriptProcessorRuleBehavior, "{24054E73-1B92-43B0-AC13-174B2F0E3F66}", SceneCore::BehaviorComponent); - - ~ScriptProcessorRuleBehavior() override = default; - - SCENE_DATA_API void Activate() override; - SCENE_DATA_API void Deactivate() override; - static void Reflect(ReflectContext* context); - - // AssetImportRequestBus::Handler - SCENE_DATA_API Events::ProcessingResult UpdateManifest( - Containers::Scene& scene, - ManifestAction action, - RequestingApplication requester) override; - - private: - AzToolsFramework::EditorPythonEventsInterface* m_editorPythonEventsInterface = nullptr; - }; - } // namespace SceneData - } // namespace SceneAPI -} // namespace AZ + public: + AZ_COMPONENT(ScriptProcessorRuleBehavior, "{24054E73-1B92-43B0-AC13-174B2F0E3F66}", SceneCore::BehaviorComponent); + + ~ScriptProcessorRuleBehavior() override = default; + + SCENE_DATA_API void Activate() override; + SCENE_DATA_API void Deactivate() override; + static void Reflect(ReflectContext* context); + + // AssetImportRequestBus::Handler + SCENE_DATA_API Events::ProcessingResult UpdateManifest( + Containers::Scene& scene, + ManifestAction action, + RequestingApplication requester) override; + + + protected: + bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene); + void UnloadPython(); + bool DoPrepareForExport(Events::PreExportEventContext& context); + + private: + AzToolsFramework::EditorPythonEventsInterface* m_editorPythonEventsInterface = nullptr; + AZStd::string m_scriptFilename; + + struct ExportEventHandler; + AZStd::shared_ptr m_exportEventHandler; + }; +} // namespace AZ::SceneAPI::Behaviors diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h deleted file mode 100644 index 90163dd363..0000000000 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace AZ -{ - class BehaviorContext; - class EditContext; - class SerializeContext; -} // namespace AZ - -// this just provides a convenient template to avoid the necessary boilerplate when you derive from AWSScriptBehaviorBase -#define AWS_SCRIPT_BEHAVIOR_DEFINITION(className, guidString) \ - AZ_TYPE_INFO(className, guidString) \ - AZ_CLASS_ALLOCATOR(className, AZ::SystemAllocator, 0) \ - void ReflectSerialization(AZ::SerializeContext* serializeContext) override; \ - void ReflectBehaviors(AZ::BehaviorContext* behaviorContext) override; \ - void ReflectEditParameters(AZ::EditContext* editContext) override; \ - className(); \ - -namespace AWSCore -{ - //! An interface for AWS ScriptCanvas Behaviors to inherit from - class AWSScriptBehaviorBase - { - public: - virtual ~AWSScriptBehaviorBase() = default; - - virtual void ReflectSerialization(AZ::SerializeContext* reflectContext) = 0; - virtual void ReflectBehaviors(AZ::BehaviorContext* behaviorContext) = 0; - virtual void ReflectEditParameters(AZ::EditContext* editContext) = 0; - - virtual void Init() {} - virtual void Activate() {} - virtual void Deactivate() {} - }; -} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h index 317d16dbe4..7244f57f6a 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h @@ -10,8 +10,6 @@ #include #include -#include - namespace AWSCore { using DynamoDBAttributeValueMap = AZStd::unordered_map; @@ -55,10 +53,14 @@ namespace AWSCore }; class AWSScriptBehaviorDynamoDB - : public AWSScriptBehaviorBase { public: - AWS_SCRIPT_BEHAVIOR_DEFINITION(AWSScriptBehaviorDynamoDB, "{569E74F6-1268-4199-9653-A3B603FC9F4F}"); + AZ_RTTI(AWSScriptBehaviorDynamoDB, "{569E74F6-1268-4199-9653-A3B603FC9F4F}"); + + AWSScriptBehaviorDynamoDB() = default; + virtual ~AWSScriptBehaviorDynamoDB() = default; + + static void Reflect(AZ::ReflectContext* context); static void GetItem(const AZStd::string& tableResourceKey, const DynamoDBAttributeValueMap& keyMap); static void GetItemRaw(const AZStd::string& table, const DynamoDBAttributeValueMap& keyMap, const AZStd::string& region); diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h index a8a807e7fb..64601d8e59 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h @@ -10,8 +10,6 @@ #include #include -#include - namespace AWSCore { //! AWS Script Behavior notifications for ScriptCanvas behaviors that interact with AWS Lambda @@ -53,10 +51,14 @@ namespace AWSCore }; class AWSScriptBehaviorLambda - : public AWSScriptBehaviorBase { public: - AWS_SCRIPT_BEHAVIOR_DEFINITION(AWSScriptBehaviorLambda, "{9E71534D-34B3-4723-B180-2552513DDA3D}"); + AZ_RTTI(AWSScriptBehaviorLambda, "{9E71534D-34B3-4723-B180-2552513DDA3D}"); + + AWSScriptBehaviorLambda() = default; + virtual ~AWSScriptBehaviorLambda() = default; + + static void Reflect(AZ::ReflectContext* context); static void Invoke(const AZStd::string& functionResourceKey, const AZStd::string& payload); static void InvokeRaw(const AZStd::string& functionName, const AZStd::string& payload, const AZStd::string& region); diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h index a75c3bce31..ac2df1c822 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h @@ -10,8 +10,6 @@ #include #include -#include - namespace AWSCore { //! AWS Script Behavior notifications for ScriptCanvas behaviors that interact with AWS S3 @@ -68,7 +66,6 @@ namespace AWSCore }; class AWSScriptBehaviorS3 - : public AWSScriptBehaviorBase { static constexpr const char AWSScriptBehaviorS3Name[] = "AWSScriptBehaviorS3"; static constexpr const char OutputFileIsEmptyErrorMessage[] = "Request validation failed, output file is empty."; @@ -81,7 +78,12 @@ namespace AWSCore static constexpr const char RegionNameIsEmptyErrorMessage[] = "Request validation failed, region name is empty."; public: - AWS_SCRIPT_BEHAVIOR_DEFINITION(AWSScriptBehaviorS3, "{7F4E956C-7463-4236-B320-C992D36A9C6E}"); + AZ_RTTI(AWSScriptBehaviorS3, "{7F4E956C-7463-4236-B320-C992D36A9C6E}"); + + AWSScriptBehaviorS3() = default; + virtual ~AWSScriptBehaviorS3() = default; + + static void Reflect(AZ::ReflectContext* context); static void GetObject(const AZStd::string& bucketResourceKey, const AZStd::string& objectKey, const AZStd::string& outFile); static void GetObjectRaw(const AZStd::string& bucket, const AZStd::string& objectKey, const AZStd::string& region, const AZStd::string& outFile); diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h index 8958425615..43bd15d726 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h @@ -10,7 +10,6 @@ #include #include #include -#include namespace AWSCore { @@ -30,23 +29,8 @@ namespace AWSCore static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - static bool AddedBehaviours() - { - return m_alreadyAddedBehaviors; - } - - protected: - - //////////////////////////////////////////////////////////////////////// // AZ::Component interface implementation - void Init() override; void Activate() override; void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - - static void AddBehaviors(); // Add any behaviors you derived from AWSScriptBehaviorBase to the implementation of this function - - static AZStd::vector> m_behaviors; - static bool m_alreadyAddedBehaviors; }; } // namespace AWSCore diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp index c25df555fc..41c1aff34d 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp @@ -20,39 +20,30 @@ namespace AWSCore { - AWSScriptBehaviorDynamoDB::AWSScriptBehaviorDynamoDB() + void AWSScriptBehaviorDynamoDB::Reflect(AZ::ReflectContext* context) { - } - - void AWSScriptBehaviorDynamoDB::ReflectSerialization(AZ::SerializeContext* serializeContext) - { - if (serializeContext) + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(0); } - } - - void AWSScriptBehaviorDynamoDB::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) - { - behaviorContext->Class("AWSScriptBehaviorDynamoDB") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Method("GetItem", &AWSScriptBehaviorDynamoDB::GetItem, - {{{"Table Resource KeyName", "The name of the table containing the requested item."}, - {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}}}) - ->Method("GetItemRaw", &AWSScriptBehaviorDynamoDB::GetItemRaw, - {{{"Table Name", "The name of the table containing the requested item."}, - {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}, - {"Region Name", "The region of the table located in."}}}); - behaviorContext->EBus("AWSDynamoDBBehaviorNotificationBus") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Handler(); - } + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("AWSScriptBehaviorDynamoDB") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Method("GetItem", &AWSScriptBehaviorDynamoDB::GetItem, + {{{"Table Resource KeyName", "The name of the table containing the requested item."}, + {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}}}) + ->Method("GetItemRaw", &AWSScriptBehaviorDynamoDB::GetItemRaw, + {{{"Table Name", "The name of the table containing the requested item."}, + {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}, + {"Region Name", "The region of the table located in."}}}); - void AWSScriptBehaviorDynamoDB::ReflectEditParameters(AZ::EditContext* editContext) - { - AZ_UNUSED(editContext); + behaviorContext->EBus("AWSDynamoDBBehaviorNotificationBus") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Handler(); + } } void AWSScriptBehaviorDynamoDB::GetItem(const AZStd::string& tableResourceKey, const DynamoDBAttributeValueMap& keyMap) diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp index a7420654de..d4137c313b 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp @@ -21,39 +21,30 @@ namespace AWSCore { - AWSScriptBehaviorLambda::AWSScriptBehaviorLambda() + void AWSScriptBehaviorLambda::Reflect(AZ::ReflectContext* context) { - } - - void AWSScriptBehaviorLambda::ReflectSerialization(AZ::SerializeContext* serializeContext) - { - if (serializeContext) + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(0); } - } - - void AWSScriptBehaviorLambda::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) - { - behaviorContext->Class("AWSScriptBehaviorLambda") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Method("Invoke", &AWSScriptBehaviorLambda::Invoke, - {{{"Function Resource KeyName", "The resource key name of the lambda function in resource mapping config file."}, - {"Payload", "The JSON that you want to provide to your Lambda function as input."}}}) - ->Method("InvokeRaw", &AWSScriptBehaviorLambda::InvokeRaw, - {{{"Function Name", "The name of the Lambda function, version, or alias."}, - {"Payload", "The JSON that you want to provide to your Lambda function as input."}, - {"Region Name", "The region of the lambda function located in."}}}); - behaviorContext->EBus("AWSLambdaBehaviorNotificationBus") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Handler(); - } + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("AWSScriptBehaviorLambda") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Method("Invoke", &AWSScriptBehaviorLambda::Invoke, + {{{"Function Resource KeyName", "The resource key name of the lambda function in resource mapping config file."}, + {"Payload", "The JSON that you want to provide to your Lambda function as input."}}}) + ->Method("InvokeRaw", &AWSScriptBehaviorLambda::InvokeRaw, + {{{"Function Name", "The name of the Lambda function, version, or alias."}, + {"Payload", "The JSON that you want to provide to your Lambda function as input."}, + {"Region Name", "The region of the lambda function located in."}}}); - void AWSScriptBehaviorLambda::ReflectEditParameters(AZ::EditContext* editContext) - { - AZ_UNUSED(editContext); + behaviorContext->EBus("AWSLambdaBehaviorNotificationBus") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Handler(); + } } void AWSScriptBehaviorLambda::Invoke(const AZStd::string& functionResourceKey, const AZStd::string& payload) diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp index f47dda8046..e82fff0c31 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp @@ -24,49 +24,39 @@ namespace AWSCore { - AWSScriptBehaviorS3::AWSScriptBehaviorS3() + void AWSScriptBehaviorS3::Reflect(AZ::ReflectContext* context) { - } - - void AWSScriptBehaviorS3::ReflectSerialization(AZ::SerializeContext* serializeContext) - { - if (serializeContext) + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(0); } - } - - void AWSScriptBehaviorS3::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) - { - behaviorContext->Class(AWSScriptBehaviorS3Name) - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Method("GetObject", &AWSScriptBehaviorS3::GetObject, - {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, - {"Object KeyName", "The object key."}, - {"Outfile Name", "Filename where the content will be saved."}}}) - ->Method("GetObjectRaw", &AWSScriptBehaviorS3::GetObjectRaw, - {{{"Bucket Name", "The name of the bucket containing the object."}, - {"Object KeyName", "The object key."}, - {"Region Name", "The region of the bucket located in."}, - {"Outfile Name", "Filename where the content will be saved."}}}) - ->Method("HeadObject", &AWSScriptBehaviorS3::HeadObject, - {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, - {"Object KeyName", "The object key."}}}) - ->Method("HeadObjectRaw", &AWSScriptBehaviorS3::HeadObjectRaw, - {{{"Bucket Name", "The name of the bucket containing the object."}, - {"Object KeyName", "The object key."}, - {"Region Name", "The region of the bucket located in."}}}) - ; - - behaviorContext->EBus("AWSS3BehaviorNotificationBus") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Handler(); - } - void AWSScriptBehaviorS3::ReflectEditParameters(AZ::EditContext* editContext) - { - AZ_UNUSED(editContext); + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class(AWSScriptBehaviorS3Name) + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Method("GetObject", &AWSScriptBehaviorS3::GetObject, + {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, + {"Object KeyName", "The object key."}, + {"Outfile Name", "Filename where the content will be saved."}}}) + ->Method("GetObjectRaw", &AWSScriptBehaviorS3::GetObjectRaw, + {{{"Bucket Name", "The name of the bucket containing the object."}, + {"Object KeyName", "The object key."}, + {"Region Name", "The region of the bucket located in."}, + {"Outfile Name", "Filename where the content will be saved."}}}) + ->Method("HeadObject", &AWSScriptBehaviorS3::HeadObject, + {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, + {"Object KeyName", "The object key."}}}) + ->Method("HeadObjectRaw", &AWSScriptBehaviorS3::HeadObjectRaw, + {{{"Bucket Name", "The name of the bucket containing the object."}, + {"Object KeyName", "The object key."}, + {"Region Name", "The region of the bucket located in."}}}); + + behaviorContext->EBus("AWSS3BehaviorNotificationBus") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Handler(); + } } void AWSScriptBehaviorS3::GetObject( diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp index 530c35cde2..4c41dc3f0e 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp @@ -12,35 +12,17 @@ namespace AWSCore { - AZStd::vector> AWSScriptBehaviorsComponent::m_behaviors; - bool AWSScriptBehaviorsComponent::m_alreadyAddedBehaviors = false; - - void AWSScriptBehaviorsComponent::AddBehaviors() - { - if (!m_alreadyAddedBehaviors) - { - // Add new script behaviors here - m_behaviors.push_back(AZStd::make_unique()); - m_behaviors.push_back(AZStd::make_unique()); - m_behaviors.push_back(AZStd::make_unique()); - m_alreadyAddedBehaviors = true; - } - } - void AWSScriptBehaviorsComponent::Reflect(AZ::ReflectContext* context) { - AddBehaviors(); + AWSScriptBehaviorDynamoDB::Reflect(context); + AWSScriptBehaviorLambda::Reflect(context); + AWSScriptBehaviorS3::Reflect(context); if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() ->Version(0); - for (auto&& behavior : m_behaviors) - { - behavior->ReflectSerialization(serialize); - } - if (AZ::EditContext* editContext = serialize->GetEditContext()) { editContext->Class("AWSScriptBehaviors", "Provides ScriptCanvas functions for calling AWS") @@ -49,19 +31,6 @@ namespace AWSCore ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("AWS")) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; - - for (auto&& behavior : m_behaviors) - { - behavior->ReflectEditParameters(editContext); - } - } - } - - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) - { - for (auto&& behavior : m_behaviors) - { - behavior->ReflectBehaviors(behaviorContext); } } } @@ -86,31 +55,12 @@ namespace AWSCore AZ_UNUSED(dependent); } - void AWSScriptBehaviorsComponent::Init() - { - for (auto&& behavior : m_behaviors) - { - behavior->Init(); - } - } - void AWSScriptBehaviorsComponent::Activate() { - for (auto&& behavior : m_behaviors) - { - behavior->Activate(); - } } void AWSScriptBehaviorsComponent::Deactivate() { - for (auto&& behavior : m_behaviors) - { - behavior->Deactivate(); - } - - // this forces the vector to release its capacity, clear/shrink_to_fit is not - m_behaviors.swap(AZStd::vector>()); } } diff --git a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp index 15ad297f9b..2283caa69e 100644 --- a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp +++ b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp @@ -15,18 +15,6 @@ using namespace AWSCore; -class AWSScriptBehaviorsComponentMock - : public AWSScriptBehaviorsComponent -{ -public: - AZ_COMPONENT(AWSScriptBehaviorsComponentMock, "{78579706-E1B2-4788-A34D-A58D3F273FF9}"); - - int GetBehaviorsNum() - { - return m_behaviors.size(); - } -}; - class AWSScriptBehaviorsComponentTest : public UnitTest::ScopedAllocatorSetupFixture { @@ -38,7 +26,7 @@ public: m_behaviorContext = AZStd::make_unique(); m_entity = AZStd::make_unique(); - m_scriptBehaviorsComponent.reset(m_entity->CreateComponent()); + m_scriptBehaviorsComponent.reset(m_entity->CreateComponent()); } void TearDown() override @@ -56,20 +44,16 @@ protected: AZStd::unique_ptr m_serializeContext; AZStd::unique_ptr m_behaviorContext; AZStd::unique_ptr m_componentDescriptor; - AZStd::unique_ptr m_scriptBehaviorsComponent; + AZStd::unique_ptr m_scriptBehaviorsComponent; AZStd::unique_ptr m_entity; }; -TEST_F(AWSScriptBehaviorsComponentTest, InitActivateDeactivate_Call_GetExpectedNumOfAddedBehaviors) +TEST_F(AWSScriptBehaviorsComponentTest, Reflect) { - m_componentDescriptor.reset(AWSScriptBehaviorsComponentMock::CreateDescriptor()); + int oldEBusNum = m_behaviorContext->m_ebuses.size(); + m_componentDescriptor.reset(AWSScriptBehaviorsComponent::CreateDescriptor()); m_componentDescriptor->Reflect(m_serializeContext.get()); m_componentDescriptor->Reflect(m_behaviorContext.get()); - EXPECT_TRUE(AWSScriptBehaviorsComponentMock::AddedBehaviours()); - EXPECT_TRUE(m_scriptBehaviorsComponent->GetBehaviorsNum() == 3); - m_entity->Init(); - m_entity->Activate(); - m_entity->Deactivate(); - EXPECT_TRUE(m_scriptBehaviorsComponent->GetBehaviorsNum() == 0); + EXPECT_TRUE(m_behaviorContext->m_ebuses.size() - oldEBusNum == 3); } diff --git a/Gems/AWSCore/Code/awscore_files.cmake b/Gems/AWSCore/Code/awscore_files.cmake index c1577ec1eb..8e8ed280f8 100644 --- a/Gems/AWSCore/Code/awscore_files.cmake +++ b/Gems/AWSCore/Code/awscore_files.cmake @@ -32,7 +32,6 @@ set(FILES Include/Public/Framework/ServiceRequestJobConfig.h Include/Public/Framework/Util.h Include/Public/ResourceMapping/AWSResourceMappingBus.h - Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp index afa11d8e16..f6b99cac12 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp @@ -95,7 +95,7 @@ namespace AZ shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder"; // Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update // ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder". - shaderVariantAssetBuilderDescriptor.m_version = 23; // ATOM-15472 + shaderVariantAssetBuilderDescriptor.m_version = 24; // ATOM-15978 shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid(); shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp index 7be98ab056..010778575e 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp @@ -48,6 +48,7 @@ #include "ShaderAssetBuilder.h" #include "ShaderBuilderUtility.h" +#include "SrgLayoutUtility.h" #include "AzslData.h" #include "AzslCompiler.h" #include @@ -520,6 +521,96 @@ namespace AZ return; } } + + static bool LoadSrgLayoutListFromShaderAssetBuilder( + const RHI::ShaderPlatformInterface* shaderPlatformInterface, + const AssetBuilderSDK::PlatformInfo& platformInfo, + const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath, + const RPI::SupervariantIndex supervariantIndex, + const bool platformUsesRegisterSpaces, + RPI::ShaderResourceGroupLayoutList& srgLayoutList, + RootConstantData& rootConstantData) + { + auto srgJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder( + shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::SrgJson); + if (!srgJsonPathOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", srgJsonPathOutcome.GetError().c_str()); + return false; + } + + auto srgJsonPath = srgJsonPathOutcome.TakeValue(); + auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(srgJsonPath); + if (!jsonOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str()); + return false; + } + SrgDataContainer srgData; + if (!azslCompiler.ParseSrgPopulateSrgData(jsonOutcome.GetValue(), srgData)) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse srg data"); + return false; + } + // Add all Shader Resource Group Assets that were defined in the shader code to the shader asset + if (!SrgLayoutUtility::LoadShaderResourceGroupLayouts(ShaderVariantAssetBuilderName, srgData, platformUsesRegisterSpaces, srgLayoutList)) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to load ShaderResourceGroupLayouts"); + return false; + } + + for (auto srgLayout : srgLayoutList) + { + if (!srgLayout->Finalize()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, + "Failed to finalize SrgLayout %s", srgLayout->GetName().GetCStr()); + return false; + } + } + + // Access the root constants reflection + if (!azslCompiler.ParseSrgPopulateRootConstantData( + jsonOutcome.GetValue(), + rootConstantData)) // consuming data from --srg ("InlineConstantBuffer" subjson section) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to obtain root constant data reflection"); + return false; + } + + return true; + } + + static bool LoadBindingDependenciesFromShaderAssetBuilder( + const RHI::ShaderPlatformInterface* shaderPlatformInterface, + const AssetBuilderSDK::PlatformInfo& platformInfo, + const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath, + const RPI::SupervariantIndex supervariantIndex, + BindingDependencies& bindingDependencies) + { + auto bindingsJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder( + shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::BindingdepJson); + if (!bindingsJsonPathOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", bindingsJsonPathOutcome.GetError().c_str()); + return false; + } + + auto bindingsJsonPath = bindingsJsonPathOutcome.TakeValue(); + auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(bindingsJsonPath); + if (!jsonOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str()); + return false; + } + if (!azslCompiler.ParseBindingdepPopulateBindingDependencies(jsonOutcome.GetValue(), bindingDependencies)) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse binding dependencies data"); + return false; + } + + return true; + } // Returns the content of the hlsl file for the given supervariant as produced by ShaderAsssetBuilder. @@ -773,6 +864,50 @@ namespace AZ response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; return; } + + //! It is important to keep this refcounted pointer outside of the if block to prevent it from being destroyed. + RHI::Ptr pipelineLayoutDescriptor; + if (shaderPlatformInterface->VariantCompilationRequiresSrgLayoutData()) + { + AZStd::string azslcCompilerParameters = + shaderPlatformInterface->GetAzslCompilerParameters(buildOptions.m_compilerArguments); + const bool platformUsesRegisterSpaces = + (AzFramework::StringFunc::Find(azslcCompilerParameters, "--use-spaces") != AZStd::string::npos); + + RPI::ShaderResourceGroupLayoutList srgLayoutList; + RootConstantData rootConstantData; + if (!LoadSrgLayoutListFromShaderAssetBuilder( + shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex, + platformUsesRegisterSpaces, + srgLayoutList, + rootConstantData)) + { + response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; + return; + } + + BindingDependencies bindingDependencies; + if (!LoadBindingDependenciesFromShaderAssetBuilder( + shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex, + bindingDependencies)) + { + response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; + return; + } + + pipelineLayoutDescriptor = + ShaderBuilderUtility::BuildPipelineLayoutDescriptorForApi( + ShaderVariantAssetBuilderName, srgLayoutList, shaderEntryPoints, buildOptions.m_compilerArguments, rootConstantData, + shaderPlatformInterface, bindingDependencies); + if (!pipelineLayoutDescriptor) + { + AZ_Error( + ShaderVariantAssetBuilderName, false, "Failed to build pipeline layout descriptor for api=[%s]", + shaderPlatformInterface->GetAPIName().GetCStr()); + response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; + return; + } + } // Setup the shader variant creation context: ShaderVariantCreationContext shaderVariantCreationContext = diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h index d83fbf2267..f7db5f865b 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h @@ -144,6 +144,12 @@ namespace AZ const ShaderResourceGroupInfoList& srgInfoList, const RootConstantsInfo& rootConstantsInfo, const ShaderCompilerArguments& shaderCompilerArguments) = 0; + + //! In general, shader compilation doesn't require SRG Layout data, but RHIs like + //! Metal don't do well if unused resources (descriptors) are not bound. If this function returns TRUE + //! the ShaderVariantAssetBuilder will invoke BuildPipelineLayoutDescriptor() so the RHI gets the chance to + //! build SRG Layout data which will be useful when compiling MetalISL to Metal byte code. + virtual bool VariantCompilationRequiresSrgLayoutData() const { return false; } //! See AZ::RHI::Factory::GetAPIUniqueIndex() for details. //! See AZ::RHI::Limits::APIType::PerPlatformApiUniqueIndexMax. diff --git a/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp b/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp index 0801101178..2f648acc05 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp @@ -159,7 +159,13 @@ namespace AZ arguments += " -Zi"; // Generate debug information arguments += " -Zss"; // Compute Shader Hash considering source information } - arguments += " " + m_dxcAdditionalFreeArguments; + // strip spaces at both sides + AZStd::string dxcAdditionalFreeArguments = m_dxcAdditionalFreeArguments; + AzFramework::StringFunc::TrimWhiteSpace(dxcAdditionalFreeArguments, true, true); + if (!dxcAdditionalFreeArguments.empty()) + { + arguments += " " + dxcAdditionalFreeArguments; + } return arguments; } } diff --git a/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp b/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp index de3bc23a11..cb9e72118a 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp @@ -43,11 +43,36 @@ namespace Platform } return physicalDeviceList; } + + float GetRefreshRate() + { + CGDirectDisplayID display = CGMainDisplayID(); + CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display); + return CGDisplayModeGetRefreshRate(currentMode); + } - void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval) + void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval, float refreshRate) { - AZ_UNUSED(syncInterval); - [mtlCommandBuffer presentDrawable:drawable]; + bool framePresented = false; + + //seconds per frame (1/refreshrate) * num frames (sync interval) + float presentAfterMinimumDuration = syncInterval / refreshRate; + +#if defined(__MAC_10_15_4) + if(@available(macOS 10.15.4, *)) + { + if(presentAfterMinimumDuration > 0.0f) + { + [mtlCommandBuffer presentDrawable:drawable afterMinimumDuration:presentAfterMinimumDuration]; + framePresented = true; + } + } +#endif + + if(!framePresented) + { + [mtlCommandBuffer presentDrawable:drawable]; + } } CGRect GetScreenBounds(NativeWindowType* nativeWindow) diff --git a/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp b/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp index b7c309fba2..007655a93e 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp @@ -29,13 +29,19 @@ namespace Platform return physicalDeviceList; } - void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval) + float GetRefreshRate() { - bool hasPresentAfterMinimumDuration = [drawable respondsToSelector:@selector(presentAfterMinimumDuration:)]; - - if (hasPresentAfterMinimumDuration && syncInterval > 0.0f) + NativeScreenType* nativeScreen = [NativeScreenType mainScreen]; + return [nativeScreen maximumFramesPerSecond]; + } + + void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval, float refreshRate) + { + //seconds per frame (1/refreshrate) * num frames (sync interval) + float presentAfterMinimumDuration = syncInterval / refreshRate; + if (hasPresentAfterMinimumDuration > 0.0f) { - [mtlCommandBuffer presentDrawable:drawable afterMinimumDuration:syncInterval]; + [mtlCommandBuffer presentDrawable:drawable afterMinimumDuration:presentAfterMinimumDuration]; } else { diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h b/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h index 935d2e6471..0be02053cd 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h @@ -40,6 +40,8 @@ namespace AZ const ShaderResourceGroupInfoList& srgInfoList, const RootConstantsInfo& rootConstantsInfo, const RHI::ShaderCompilerArguments& shaderCompilerArguments) override; + + bool VariantCompilationRequiresSrgLayoutData() const override { return true; } bool CompilePlatformInternal( const AssetBuilderSDK::PlatformInfo& platform, diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp index 675a593bc8..9df5f3362d 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp @@ -30,6 +30,7 @@ namespace AZ { AZ_UNUSED(device); m_hardwareQueueClass = hardwareQueueClass; + m_supportsInterDrawTimestamps = AZ::RHI::QueryTypeFlags::Timestamp == (device->GetFeatures().m_queryTypesMask[static_cast(hardwareQueueClass)] & AZ::RHI::QueryTypeFlags::Timestamp); } void CommandListBase::Reset() @@ -64,7 +65,10 @@ namespace AZ [m_encoder endEncoding]; m_encoder = nil; #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING - m_timeStampQueue.clear(); + if (m_supportsInterDrawTimestamps) + { + m_timeStampQueue.clear(); + } #endif } } @@ -144,9 +148,12 @@ namespace AZ m_isEncoded = true; #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING - for(auto& timeStamp: m_timeStampQueue) + if (m_supportsInterDrawTimestamps) { - SampleCounters(timeStamp.m_counterSampleBuffer, timeStamp.m_timeStampIndex); + for(auto& timeStamp: m_timeStampQueue) + { + SampleCounters(timeStamp.m_counterSampleBuffer, timeStamp.m_timeStampIndex); + } } #endif } @@ -195,6 +202,11 @@ namespace AZ #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING void CommandListBase::SampleCounters(id counterSampleBuffer, uint32_t sampleIndex) { + if (!m_supportsInterDrawTimestamps) + { + return; + } + AZ_Assert(sampleIndex >= 0, "Invalid sample index"); //useBarrier - Inserting a barrier ensures that encoded work is complete before the GPU samples the hardware counters. //If it is true there is a performance penalty but you will get consistent results @@ -231,6 +243,11 @@ namespace AZ void CommandListBase::SamplePassCounters(id counterSampleBuffer, uint32_t sampleIndex) { + if (!m_supportsInterDrawTimestamps) + { + return; + } + if(m_encoder == nil) { //Queue the query to be activated upon encoder creation. Applies to timestamp queries diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h index 70678aed01..a344222e63 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h @@ -101,6 +101,8 @@ namespace AZ const AZStd::set>* m_residentHeaps = nullptr; + bool m_supportsInterDrawTimestamps = AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING; // iOS/TVOS = false, MacOS = defaults to true + #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING struct TimeStampData { diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp index 5e23353b65..0da2ea6aaa 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp @@ -328,14 +328,28 @@ namespace AZ m_features.m_indirectDrawSupport = false; RHI::QueryTypeFlags counterSamplingFlags = RHI::QueryTypeFlags::None; - -#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING - counterSamplingFlags |= (RHI::QueryTypeFlags::Timestamp | RHI::QueryTypeFlags::PipelineStatistics); - m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Copy)] = RHI::QueryTypeFlags::Timestamp; + + bool supportsInterDrawTimestamps = true; +#if defined(__IPHONE_14_0) || defined(__MAC_11_0) || defined(__TVOS_14_0) + if (@available(macOS 11.0, iOS 14, tvOS 14, *)) + { + supportsInterDrawTimestamps = [m_metalDevice supportsCounterSampling:MTLCounterSamplingPointAtDrawBoundary]; + } + else #endif + { + supportsInterDrawTimestamps = ![m_metalDevice.name containsString:@"Apple"]; // Apple GPU's don't support inter draw timestamps at the M1/A14 generation + } + + if (supportsInterDrawTimestamps) + { + counterSamplingFlags |= (RHI::QueryTypeFlags::Timestamp | RHI::QueryTypeFlags::PipelineStatistics); + m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Copy)] = RHI::QueryTypeFlags::Timestamp; + } + m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Graphics)] = RHI::QueryTypeFlags::Occlusion | counterSamplingFlags; //Compute queue can do gfx work - m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Compute)] = RHI::QueryTypeFlags::Occlusion |counterSamplingFlags; + m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Compute)] = RHI::QueryTypeFlags::Occlusion | counterSamplingFlags; m_features.m_occlusionQueryPrecise = true; //Values taken from https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp index 31d23e5100..08d5d2be87 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp @@ -19,8 +19,9 @@ namespace Platform CGFloat GetScreenScale(); void AttachViewController(NativeWindowType* nativeWindow, NativeViewControllerType* viewController, RHIMetalView* metalView); void UnAttachViewController(NativeWindowType* nativeWindow, NativeViewControllerType* viewController); - void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval); + void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval, float refreshRate); void ResizeInternal(RHIMetalView* metalView, CGSize viewSize); + float GetRefreshRate(); RHIMetalView* GetMetalView(NativeWindowType* nativeWindow); } @@ -73,6 +74,15 @@ namespace AZ AddSubView(); } + m_refreshRate = Platform::GetRefreshRate(); + + //Assume 60hz if 0 is returned. + //Internal OSX displays have 'flexible' refresh rates, with a max of 60Hz - but report 0hz + if (m_refreshRate < 0.1f) + { + m_refreshRate = 60.0f; + } + m_drawables.resize(descriptor.m_dimensions.m_imageCount); if (nativeDimensions) @@ -148,10 +158,9 @@ namespace AZ uint32_t SwapChain::PresentInternal() { const uint32_t currentImageIndex = GetCurrentImageIndex(); - //GFX TODO][ATOM-432] - Hardcoding to 30fps for now. Only used by ios. This needs to be driven by higher level code. - float syncInterval = 1.0f/30.0f; + //Preset the drawable - Platform::PresentInternal(m_mtlCommandBuffer, m_drawables[currentImageIndex], syncInterval); + Platform::PresentInternal(m_mtlCommandBuffer, m_drawables[currentImageIndex], GetDescriptor().m_verticalSyncInterval, m_refreshRate); [m_drawables[currentImageIndex] release]; m_drawables[currentImageIndex] = nil; diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h index c86bd1f7a5..72014005ac 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h @@ -52,6 +52,7 @@ namespace AZ id m_mtlDevice = nil; NativeWindowType* m_nativeWindow = nullptr; AZStd::vector> m_drawables; + float m_refreshRate = 0.0f; }; } } diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp index 7586183b63..61149c19f7 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp @@ -218,7 +218,8 @@ namespace AZ createInfo.extent = extent; createInfo.mipLevels = AZStd::min(descriptor.m_mipLevels, formatProps.maxMipLevels); createInfo.arrayLayers = AZStd::min(descriptor.m_arraySize, formatProps.maxArrayLayers); - createInfo.samples = static_cast(RHI::FilterBits(static_cast(ConvertSampleCount(descriptor.m_multisampleState.m_samples)), formatProps.sampleCounts)); + VkSampleCountFlagBits sampleCountFlagBits = static_cast(RHI::FilterBits(static_cast(ConvertSampleCount(descriptor.m_multisampleState.m_samples)), formatProps.sampleCounts)); + createInfo.samples = (static_cast(sampleCountFlagBits) > 0) ? sampleCountFlagBits : VK_SAMPLE_COUNT_1_BIT; createInfo.tiling = VK_IMAGE_TILING_OPTIMAL; createInfo.usage = GetImageUsageFlags(); createInfo.sharingMode = exclusiveOwnership ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp index bf3107cfdf..5d621094ea 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp @@ -116,7 +116,7 @@ namespace AZ { AZ_Assert(IsQueryTypeValid(queryType), "Provided QueryType is invalid"); - return static_cast(m_queryTypeSupport) & static_cast(queryType); + return static_cast(m_queryTypeSupport) & AZ_BIT(static_cast(queryType)); } RPI::QueryPool* GpuQuerySystem::GetQueryPoolByType(RHI::QueryType queryType) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp index d8c69cf8a0..4e858e4880 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp @@ -58,8 +58,8 @@ namespace AZ RHI::ShaderResourceGroupPoolDescriptor poolDescriptor; poolDescriptor.m_layout = shaderAsset.FindShaderResourceGroupLayout(srgName, supervariantIndex).get(); - - m_pool->SetName(srgName); + m_pool->SetName(AZ::Name(AZStd::string::format("%s_%s",shaderAsset.GetName().GetCStr(),srgName.GetCStr()))); + const RHI::ResultCode resultCode = m_pool->Init(*device, poolDescriptor); return resultCode; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp index 16ad7a1155..4b8c061b68 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp @@ -27,7 +27,7 @@ void OnVsyncIntervalChanged(uint32_t const& interval) // NOTE: On change, broadcasts the new requested vsync interval to all windows. // The value of the vsync interval is constrained between 0 and 4 // Vsync intervals greater than 1 are not currently supported on the Vulkan RHI (see #2061 for discussion) -AZ_CVAR(uint32_t, rpi_vsync_interval, 0, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval"); +AZ_CVAR(uint32_t, rpi_vsync_interval, 1, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval"); namespace AZ { diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp index d0963a33ee..00eff6c047 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -166,6 +165,34 @@ namespace EMotionFX return finalMotionData; } + AZ::SceneAPI::DataTypes::MatrixType MotionDataBuilder::GetLocalSpaceBindPose(const SceneContainers::SceneGraph& sceneGraph, + const SceneContainers::SceneGraph::NodeIndex rootBoneNodeIndex, + const SceneContainers::SceneGraph::NodeIndex nodeIndex, + const SceneDataTypes::ITransform* transform, + const SceneDataTypes::IBoneData* bone) const + { + if (nodeIndex != rootBoneNodeIndex) + { + const SceneContainers::SceneGraph::NodeIndex parentNodeIndex = sceneGraph.GetNodeParent(nodeIndex); + const SceneDataTypes::IGraphObject* parentNode = sceneGraph.GetNodeContent(parentNodeIndex).get(); + if (const SceneDataTypes::IBoneData* parentBone = azrtti_cast(parentNode)) + { + return parentBone->GetWorldTransform().GetInverseFull() * bone->GetWorldTransform(); + } + } + + if (bone) + { + return bone->GetWorldTransform(); + } + else if (transform) + { + return transform->GetMatrix(); + } + + return AZ::SceneAPI::DataTypes::MatrixType::CreateIdentity(); + } + AZ::SceneAPI::Events::ProcessingResult MotionDataBuilder::BuildMotionData(MotionDataBuilderContext& context) { if (context.m_phase != AZ::RC::Phase::Filling) @@ -220,8 +247,10 @@ namespace EMotionFX continue; } - AZStd::shared_ptr nodeBone = azrtti_cast(it->second); - if (!nodeBone) + // Check if we are dealing with a transform node or a bone and only recurse down the node hierarchy in this case. + const SceneDataTypes::IBoneData* nodeBone = azrtti_cast(it->second.get()); + const SceneDataTypes::ITransform* nodeTransform = azrtti_cast(it->second.get()); + if (!nodeBone && !nodeTransform) { it.IgnoreNodeDescendants(); continue; @@ -289,24 +318,13 @@ namespace EMotionFX // Get the bind pose transform in local space. using SceneAPIMatrixType = AZ::SceneAPI::DataTypes::MatrixType; - SceneAPIMatrixType bindSpaceLocalTransform; - const SceneContainers::SceneGraph::NodeIndex parentIndex = graph.GetNodeParent(boneNodeIndex); - if (boneNodeIndex != rootBoneNodeIndex) - { - auto parentNode = graph.GetNodeContent(parentIndex); - AZStd::shared_ptr parentNodeBone = azrtti_cast(parentNode); - bindSpaceLocalTransform = parentNodeBone->GetWorldTransform().GetInverseFull() * nodeBone->GetWorldTransform(); - } - else - { - bindSpaceLocalTransform = nodeBone->GetWorldTransform(); - } + const SceneAPIMatrixType bindSpaceLocalTransform = GetLocalSpaceBindPose(graph, rootBoneNodeIndex, boneNodeIndex, nodeTransform, nodeBone); // Get the time step and make sure it didn't change compared to other joint animations. const double timeStep = animation->GetTimeStepBetweenFrames(); lowestTimeStep = AZ::GetMin(timeStep, lowestTimeStep); - SceneAPIMatrixType sampleFrameTransformInverse; + AZ::SceneAPI::DataTypes::MatrixType sampleFrameTransformInverse; if (additiveRule) { size_t sampleFrameIndex = additiveRule->GetSampleFrameIndex(); diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h index 5cf865324b..ca7402f83b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h @@ -9,6 +9,9 @@ #include #include +#include +#include +#include namespace EMotionFX { @@ -28,6 +31,14 @@ namespace EMotionFX static void Reflect(AZ::ReflectContext* context); AZ::SceneAPI::Events::ProcessingResult BuildMotionData(MotionDataBuilderContext& context); + + private: + //! Get the bind pose transform in local space. + AZ::SceneAPI::DataTypes::MatrixType GetLocalSpaceBindPose(const AZ::SceneAPI::Containers::SceneGraph& sceneGraph, + const AZ::SceneAPI::Containers::SceneGraph::NodeIndex rootBoneNodeIndex, + const AZ::SceneAPI::Containers::SceneGraph::NodeIndex nodeIndex, + const AZ::SceneAPI::DataTypes::ITransform* transform, + const AZ::SceneAPI::DataTypes::IBoneData* bone) const; }; } // namespace Pipeline } // namespace EMotionFX diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp index a2241b9953..a9e344f4ee 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp +++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp @@ -237,8 +237,8 @@ namespace EditorPythonBindings { ec->Class("PythonSystemComponent", "The Python interpreter") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; } } @@ -284,10 +284,10 @@ namespace EditorPythonBindings ReleaseFunction m_releaseFunction; }; ReleaseInitalizeWaiterScope scope([this]() - { - m_initalizeWaiter.release(m_initalizeWaiterCount); - m_initalizeWaiterCount = 0; - }); + { + m_initalizeWaiter.release(m_initalizeWaiterCount); + m_initalizeWaiterCount = 0; + }); if (Py_IsInitialized()) { @@ -327,6 +327,11 @@ namespace EditorPythonBindings return result; } + bool PythonSystemComponent::IsPythonActive() + { + return Py_IsInitialized() != 0; + } + void PythonSystemComponent::WaitForInitialization() { m_initalizeWaiterCount++; diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h index 82f44e674d..8e616ff85b 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h +++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h @@ -44,6 +44,7 @@ namespace EditorPythonBindings // AzToolsFramework::EditorPythonEventsInterface bool StartPython(bool silenceWarnings = false) override; bool StopPython(bool silenceWarnings = false) override; + bool IsPythonActive() override; void WaitForInitialization() override; void ExecuteWithLock(AZStd::function executionCallback) override; //////////////////////////////////////////////////////////////////////// diff --git a/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h b/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h index 69e28df102..e606d68a3e 100644 --- a/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h +++ b/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h @@ -209,12 +209,17 @@ namespace Gestures //////////////////////////////////////////////////////////////////////////////////////////////// inline uint32_t IRecognizer::GetGesturePointerIndex(const AzFramework::InputChannel& inputChannel) { - const auto& mouseButtonIt = AZStd::find(AzFramework::InputDeviceMouse::Button::All.cbegin(), - AzFramework::InputDeviceMouse::Button::All.cend(), - inputChannel.GetInputChannelId()); - if (mouseButtonIt != AzFramework::InputDeviceMouse::Button::All.cend()) + // Only recognize gestures for the default mouse input device. The Editor may register synthetic + // mouse input devices with the same mouse input channels, which can confuse gesture recognition. + if (inputChannel.GetInputDevice().GetInputDeviceId() == AzFramework::InputDeviceMouse::Id) { - return static_cast(mouseButtonIt - AzFramework::InputDeviceMouse::Button::All.cbegin()); + const auto& mouseButtonIt = AZStd::find(AzFramework::InputDeviceMouse::Button::All.cbegin(), + AzFramework::InputDeviceMouse::Button::All.cend(), + inputChannel.GetInputChannelId()); + if (mouseButtonIt != AzFramework::InputDeviceMouse::Button::All.cend()) + { + return static_cast(mouseButtonIt - AzFramework::InputDeviceMouse::Button::All.cbegin()); + } } const auto& touchIndexIt = AZStd::find(AzFramework::InputDeviceTouch::Touch::All.cbegin(), diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index fe5e2e77df..905228e414 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -63,7 +63,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) AUTORCC FILES_CMAKE lyshine_uicanvaseditor_files.cmake - lyshine_editor_builder_files.cmake INCLUDE_DIRECTORIES PRIVATE . @@ -78,7 +77,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) 3rdParty::Qt::Widgets AZ::AzCore AZ::AzToolsFramework - AZ::AssetBuilderSDK Legacy::EditorCommon Legacy::EditorCore Gem::LyShine.Static @@ -98,7 +96,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_target( NAME LyShine.Editor GEM_MODULE - NAMESPACE Gem FILES_CMAKE lyshine_common_module_files.cmake @@ -115,17 +112,72 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) BUILD_DEPENDENCIES PRIVATE Legacy::CryCommon - AZ::AssetBuilderSDK + AZ::AzToolsFramework Gem::LyShine.Editor.Static Gem::LmbrCentral.Editor Gem::TextureAtlas.Editor RUNTIME_DEPENDENCIES Gem::LmbrCentral.Editor Gem::TextureAtlas.Editor -) + ) + + # by naming this target LyShine.Builders it ensures that it is loaded + # in any pipeline tools (Like Asset Processor, AssetBuilder, etc) + ly_add_target( + NAME LyShine.Builders.Static STATIC + NAMESPACE Gem + FILES_CMAKE + lyshine_editor_builder_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + . + Source + PUBLIC + Include + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AzToolsFramework + AZ::AssetBuilderSDK + Gem::LyShine.Static + Legacy::CryCommon + Gem::LmbrCentral.Editor + Gem::TextureAtlas.Editor + Gem::AtomToolsFramework.Static + Gem::AtomToolsFramework.Editor + ${additional_dependencies} + PUBLIC + Gem::Atom_RPI.Public + Gem::Atom_Utils.Static + Gem::Atom_Bootstrap.Headers + ) + + ly_add_target( + NAME LyShine.Builders GEM_MODULE + NAMESPACE Gem + OUTPUT_NAME Gem.LyShine.Builders + FILES_CMAKE + lyshine_common_module_files.cmake + COMPILE_DEFINITIONS + PRIVATE + LYSHINE_BUILDER + INCLUDE_DIRECTORIES + PRIVATE + . + Source + Editor + PUBLIC + Include + BUILD_DEPENDENCIES + PRIVATE + Legacy::CryCommon + AZ::AssetBuilderSDK + Gem::LyShine.Builders.Static + Gem::LmbrCentral.Editor + Gem::TextureAtlas.Editor + ) # by default, load the above "Gem::LyShine.Editor" module in dev tools: - ly_create_alias(NAME LyShine.Builders NAMESPACE Gem TARGETS Gem::LyShine.Editor) ly_create_alias(NAME LyShine.Tools NAMESPACE Gem TARGETS Gem::LyShine.Editor) endif() @@ -169,6 +221,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) COMPILE_DEFINITIONS PRIVATE LYSHINE_EDITOR + LYSHINE_BUILDER INCLUDE_DIRECTORIES PRIVATE Tests @@ -182,6 +235,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) Legacy::CryCommon AZ::AssetBuilderSDK Gem::LyShine.Editor.Static + Gem::LyShine.Builders.Static Gem::LmbrCentral.Editor Gem::TextureAtlas RUNTIME_DEPENDENCIES diff --git a/Gems/LyShine/Code/Source/LyShineModule.cpp b/Gems/LyShine/Code/Source/LyShineModule.cpp index 011bb9f203..64ce61b07a 100644 --- a/Gems/LyShine/Code/Source/LyShineModule.cpp +++ b/Gems/LyShine/Code/Source/LyShineModule.cpp @@ -52,9 +52,9 @@ #include "World/UiCanvasProxyRefComponent.h" #include "World/UiCanvasOnMeshComponent.h" -#if defined (LYSHINE_EDITOR) -# include "Pipeline/LyShineBuilder/LyShineBuilderComponent.h" -#endif // LYSHINE_EDITOR +#if defined(LYSHINE_BUILDER) +#include "Pipeline/LyShineBuilder/LyShineBuilderComponent.h" +#endif // LYSHINE_BUILDER namespace LyShine { @@ -64,7 +64,7 @@ namespace LyShine // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. m_descriptors.insert(m_descriptors.end(), { LyShineSystemComponent::CreateDescriptor(), -#if defined (LYSHINE_EDITOR) +#if defined(LYSHINE_EDITOR) LyShineEditor::LyShineEditorSystemComponent::CreateDescriptor(), #endif UiCanvasAssetRefComponent::CreateDescriptor(), @@ -103,7 +103,7 @@ namespace LyShine UiRadioButtonComponent::CreateDescriptor(), UiRadioButtonGroupComponent::CreateDescriptor(), UiParticleEmitterComponent::CreateDescriptor(), - #if defined(LYSHINE_EDITOR) + #if defined(LYSHINE_BUILDER) // Builder LyShineBuilder::LyShineBuilderComponent::CreateDescriptor(), #endif @@ -123,7 +123,7 @@ namespace LyShine { return AZ::ComponentTypeList{ azrtti_typeid(), - #if defined (LYSHINE_EDITOR) + #if defined(LYSHINE_EDITOR) azrtti_typeid(), #endif #if AZ_LOADSCREENCOMPONENT_ENABLED diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp index 7521c8b6c1..b420e551b5 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp @@ -148,7 +148,6 @@ namespace LyShine { LyShineAllocatorScope::ActivateAllocators(); - LyShineRequestBus::Handler::BusConnect(); UiSystemBus::Handler::BusConnect(); UiSystemToolsBus::Handler::BusConnect(); UiFrameworkBus::Handler::BusConnect(); @@ -196,7 +195,6 @@ namespace LyShine UiSystemBus::Handler::BusDisconnect(); UiSystemToolsBus::Handler::BusDisconnect(); UiFrameworkBus::Handler::BusDisconnect(); - LyShineRequestBus::Handler::BusDisconnect(); CrySystemEventBus::Handler::BusDisconnect(); LyShineAllocatorScope::DeactivateAllocators(); diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.h b/Gems/LyShine/Code/Source/LyShineSystemComponent.h index 5b455715ee..70e7eb5fe5 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.h +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.h @@ -13,7 +13,6 @@ #include -#include #include #include #include @@ -28,7 +27,6 @@ namespace LyShine class LyShineSystemComponent : public AZ::Component - , protected LyShineRequestBus::Handler , protected UiSystemBus::Handler , protected UiSystemToolsBus::Handler , protected LyShineAllocatorScope diff --git a/Gems/LyShine/Code/lyshine_common_module_files.cmake b/Gems/LyShine/Code/lyshine_common_module_files.cmake index e725112e53..38d01eb181 100644 --- a/Gems/LyShine/Code/lyshine_common_module_files.cmake +++ b/Gems/LyShine/Code/lyshine_common_module_files.cmake @@ -8,4 +8,6 @@ set(FILES Source/LyShineModule.cpp Source/LyShineModule.h + Source/LyShineSystemComponent.cpp + Source/LyShineSystemComponent.h ) diff --git a/Gems/LyShine/Code/lyshine_static_files.cmake b/Gems/LyShine/Code/lyshine_static_files.cmake index 8c2275ab92..749ce06125 100644 --- a/Gems/LyShine/Code/lyshine_static_files.cmake +++ b/Gems/LyShine/Code/lyshine_static_files.cmake @@ -26,8 +26,6 @@ set(FILES Source/EditorPropertyTypes.h Source/LyShineLoadScreen.cpp Source/LyShineLoadScreen.h - Source/LyShineSystemComponent.cpp - Source/LyShineSystemComponent.h Source/RenderGraph.cpp Source/RenderGraph.h Source/TextMarkup.cpp diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/idle_cwby_01.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/idle_cwby_01.fbx.assetinfo deleted file mode 100644 index 2ca1f67d65..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/idle_cwby_01.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "idle_cwby_01", - "selectedRootBone": "RootNode.Reference", - "id": "{492E8A35-2647-581F-A701-F1D2A9FBB979}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/reload.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/reload.fbx.assetinfo deleted file mode 100644 index 3d935c330e..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/reload.fbx.assetinfo +++ /dev/null @@ -1,61 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "reload", - "selectedRootBone": "RootNode.Reference", - "id": "{28092685-3550-5583-A666-CD60018AB2E9}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "ReloadEvent", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "ReloadEvent", - "startTime": 0.509211003780365, - "endTime": 0.509211003780365, - "eventDatas": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "ReloadEvent", - "startTime": 1.2446810007095338, - "endTime": 1.2446810007095338, - "eventDatas": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "ReloadEvent", - "startTime": 1.4295190572738648, - "endTime": 1.4295190572738648, - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/run.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/run.fbx.assetinfo deleted file mode 100644 index c32d66694b..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/run.fbx.assetinfo +++ /dev/null @@ -1,59 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "run", - "selectedRootBone": "RootNode.Reference", - "id": "{7D6889F1-6536-57B6-8B02-93C815D1ADA9}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "Sync", - "startTime": 0.3396751880645752, - "endTime": 0.3396751880645752, - "eventDatas": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "Sync", - "startTime": 0.6319156885147095, - "endTime": 0.6319156885147095, - "eventDatas": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/shootrecoil.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/shootrecoil.fbx.assetinfo deleted file mode 100644 index 9536e6597d..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/shootrecoil.fbx.assetinfo +++ /dev/null @@ -1,47 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "shootrecoil", - "selectedRootBone": "RootNode.Reference", - "id": "{A1DC3BB2-3324-50F3-8C4B-BBFB61623129}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "RecoilEvent", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "RecoilEvent", - "startTime": 0.23250000178813935, - "endTime": 0.23250000178813935, - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeback.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeback.fbx.assetinfo deleted file mode 100644 index 9d7c7e299c..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeback.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafeback", - "selectedRootBone": "RootNode.Reference", - "id": "{CA0EF712-DA36-5DA8-B474-207BD250CF2F}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameEvents", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameEvents", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafebackl.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafebackl.fbx.assetinfo deleted file mode 100644 index b22d00d3fe..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafebackl.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafebackl", - "selectedRootBone": "RootNode.Reference", - "id": "{9433F0E6-EA1A-5473-AA21-EE4DC45387C1}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafebackr.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafebackr.fbx.assetinfo deleted file mode 100644 index 6b7dd5c4aa..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafebackr.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafebackr", - "selectedRootBone": "RootNode.Reference", - "id": "{5392AC3D-FF18-51F5-984E-248CAAF09F2E}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforward.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforward.fbx.assetinfo deleted file mode 100644 index a0dd296fa9..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforward.fbx.assetinfo +++ /dev/null @@ -1,59 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafeforward", - "selectedRootBone": "RootNode.Reference", - "id": "{2FB879C6-B3FB-5BD8-B52B-1012000351C2}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "Sync", - "startTime": 0.2708907127380371, - "endTime": 0.2708907127380371, - "eventDatas": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "Sync", - "startTime": 0.9699265956878662, - "endTime": 0.9699265956878662, - "eventDatas": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforwardl.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforwardl.fbx.assetinfo deleted file mode 100644 index 233d7d248e..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforwardl.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafeforwardl", - "selectedRootBone": "RootNode.Reference", - "id": "{2D945D52-C313-57A3-B722-C6402ACC3506}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforwardr.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforwardr.fbx.assetinfo deleted file mode 100644 index 5332ba04bd..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeforwardr.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafeforwardr", - "selectedRootBone": "RootNode.Reference", - "id": "{3E691B9F-C0D7-5BFD-BBBC-50BAE737886E}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeinplace.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeinplace.fbx.assetinfo deleted file mode 100644 index 4d7e41b48a..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeinplace.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafeinplace", - "selectedRootBone": "RootNode.Reference", - "id": "{A2686CFC-D49B-5468-AE9F-E3F84FA75C6D}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeleft.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeleft.fbx.assetinfo deleted file mode 100644 index 02114bd336..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/strafeleft.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "strafeleft", - "selectedRootBone": "RootNode.Reference", - "id": "{2093C7DF-0C51-5C2B-B763-4DC1CC81D10E}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/straferight.fbx.assetinfo b/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/straferight.fbx.assetinfo deleted file mode 100644 index 28ac40918d..0000000000 --- a/Gems/PhysXSamples/Assets/Characters/Cowboy/Animations/straferight.fbx.assetinfo +++ /dev/null @@ -1,45 +0,0 @@ -{ - "values": [ - { - "$type": "MotionGroup", - "name": "straferight", - "selectedRootBone": "RootNode.Reference", - "id": "{CE0E45E9-4B8C-5340-9521-B6290BAB24FC}", - "rules": { - "rules": [ - { - "$type": "MetaDataRule", - "commands": [ - { - "$type": "CommandSystem::CommandAdjustMotion", - "dirtyFlag": {}, - "motionExtractionFlags": {}, - "name": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "Sync", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEventTrack", - "eventTrackName": "GameState", - "eventTrackIndex": {}, - "isEnabled": {} - }, - { - "$type": "CommandSystem::CommandCreateMotionEvent", - "eventTrackName": "GameState", - "eventDatas": {} - } - ] - }, - { - "$type": "MotionSamplingRule" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/Gems/SceneProcessing/Code/CMakeLists.txt b/Gems/SceneProcessing/Code/CMakeLists.txt index 9aa5bc6763..b33e157e51 100644 --- a/Gems/SceneProcessing/Code/CMakeLists.txt +++ b/Gems/SceneProcessing/Code/CMakeLists.txt @@ -61,6 +61,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) RUNTIME_DEPENDENCIES AZ::SceneCore AZ::SceneData + AZ::SceneUI ) # the SceneProcessing.Editor module above is only used in Builders and Tools. ly_create_alias(NAME SceneProcessing.Builders NAMESPACE Gem TARGETS Gem::SceneProcessing.Editor) diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp index e3eb617601..a5d5510f8a 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp @@ -493,7 +493,8 @@ namespace AZ::SceneGenerationComponents // Copy node attributes AZStd::apply([](const auto&&... nodePairView) { ((AZStd::for_each(begin(nodePairView), end(nodePairView), [](const auto& nodePair) { - auto& [originalNode, optimizedNode] = nodePair; + auto& originalNode = nodePair.first; + auto& optimizedNode = nodePair.second; optimizedNode->CloneAttributesFrom(&originalNode.get()); })), ...); }, std::tuple { diff --git a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py index 2b6ff8292e..d108140977 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py @@ -45,4 +45,5 @@ def kill_asset_processor(): kill_processes_named('AssetProcessorBatch', ignore_extensions=True) kill_processes_named('AssetBuilder', ignore_extensions=True) kill_processes_named('rc', ignore_extensions=True) + kill_processes_named('Lua Editor', ignore_extensions=True) diff --git a/Tools/LyTestTools/tests/CMakeLists.txt b/Tools/LyTestTools/tests/CMakeLists.txt index e5f270197c..5e57cbf123 100644 --- a/Tools/LyTestTools/tests/CMakeLists.txt +++ b/Tools/LyTestTools/tests/CMakeLists.txt @@ -52,18 +52,4 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT AutomatedTesting.Assets COMPONENT TestTools ) - - # Example tests. - ly_add_pytest( - NAME LyTestTools_ExampleTests_periodic_no_gpu - PATH ${CMAKE_CURRENT_LIST_DIR}/example/test_system_example.py - TEST_SERIAL - TEST_SUITE periodic - RUNTIME_DEPENDENCIES - Legacy::Editor - AssetProcessor - AutomatedTesting.GameLauncher - AutomatedTesting.Assets - COMPONENT TestTools - ) endif() diff --git a/Tools/LyTestTools/tests/example/__init__.py b/Tools/LyTestTools/tests/example/__init__.py deleted file mode 100755 index e200fa77d0..0000000000 --- a/Tools/LyTestTools/tests/example/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" diff --git a/Tools/LyTestTools/tests/example/test_system_example.py b/Tools/LyTestTools/tests/example/test_system_example.py deleted file mode 100755 index 3cb6128802..0000000000 --- a/Tools/LyTestTools/tests/example/test_system_example.py +++ /dev/null @@ -1,129 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT - -Example test using LyTestTools to test Lumberyard. -""" -# Python built-in dependencies. -import logging - -# Third party dependencies. -import pytest - -# ly_test_tools dependencies. -import ly_test_tools.log.log_monitor -import ly_remote_console.remote_console_commands as remote_console_commands - -# Configuring the logging is done in ly_test_tools at the following location: -# ~/dev/Tools/LyTestTools/ly_test_tools/_internal/log/py_logging_util.py - -# Use the following logging pattern to hook all test logging together: -logger = logging.getLogger(__name__) - - -@pytest.fixture -def remote_console(request): - """ - Creates a RemoteConsole() class instance to send console commands to the - Lumberyard client console. - :param request: _pytest.fixtures.SubRequest class that handles getting - a pytest fixture from a pytest function/fixture. - :return: ly_remote_console.remote_console_commands.RemoteConsole class instance - representing the Lumberyard remote console executable. - """ - # Initialize the RemoteConsole object to send commands to the Lumberyard client console. - console = remote_console_commands.RemoteConsole() - - # Custom teardown method for this remote_console fixture. - def teardown(): - console.stop() - - # Utilize request.addfinalizer() to add custom teardown() methods. - request.addfinalizer(teardown) # This pattern must be used in pytest version - - return console - -# Shared parameters & fixtures for all test methods inside the TestSystemExample class. -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize('project', ['AutomatedTesting']) -class TestSystemExample(object): - """ - Example test case class to hold a set of test case methods. - - The amount of tests run is based on the parametrization stacking made in each test method or class. - For this test, we placed unique test values in test methods and shared test values in the test class. - We also assume building has already been done, but the test should error if the build is mis-configured. - """ - # This test method needs specific parameters not shared by all other tests in the class. - # For targeting specific launchers, use the 'launcher_platform' pytest param like below: - # @pytest.mark.parametrize("launcher_platform", ['android']) - # If you want to target different AssetProcessor platforms, use asset_processor_platform: - # @pytest.mark.parametrize("asset_processor_platform", ['android']) - @pytest.mark.parametrize('level', ['simple_jacklocomotion']) - @pytest.mark.parametrize('load_wait', [120]) - @pytest.mark.test_case_id('C16806863') - def test_SystemTestExample_AllSupportedPlatforms_LaunchAutomatedTesting( - # launcher_platform, asset_processor_platform, # Re-add these here if you plan to use them. - self, launcher, remote_console, level, load_wait): - """ - Tests launching the AutomatedTesting then launches the Lumberyard client & - loads the "simple_jacklocomotion" level using the remote console. - Assumes the user already setup & built their machine for the test. - """ - # Launch the Lumberyard client & remote console test case: - with launcher.start(): - remote_console.start() - launcher_load = remote_console.expect_log_line( - match_string='Level system is loading "simple_jacklocomotion"', - timeout=load_wait) - - # Assert loading was successful using remote console logs: - assert launcher_load, ( - 'Launcher failed to load Lumberyard client with the ' - f'"{level}" level - waited "{load_wait}" seconds.') - - # This test method only needs pytest.mark report values and shared test class parameters. - @pytest.mark.parametrize('processes_to_kill', ['Editor.exe']) - @pytest.mark.parametrize("launcher_platform", ['windows_editor']) - @pytest.mark.test_case_id('C16806864') - def test_SystemTestExample_AllSupportedPlatforms_LaunchEditor(self, editor, processes_to_kill, launcher_platform): - """ - Tests launching the Lumberyard Editor is successful with the current build. - """ - # Launch the Lumberyard editor & verify load is successful: - with editor.start(): - assert editor.is_alive(), ( - 'Editor failed to launch for the current Lumberyard build.') - - # Log monitoring example test. - @pytest.mark.parametrize('level', ['simple_jacklocomotion']) - @pytest.mark.parametrize('expected_lines', [['Log Monitoring test 1', 'Log Monitoring test 2']]) - @pytest.mark.parametrize('unexpected_lines', [['Unexpected test 1', 'Unexpected test 2']]) - @pytest.mark.test_case_id('C21202585') - def test_SystemTestExample_AllSupportedPlatforms_LogMonitoring(self, level, launcher, expected_lines, - unexpected_lines): - """ - Tests that the logging paths created by LyTestTools can be monitored for results using the log monitor. - """ - # Launch the Lumberyard client & initialize the log monitor. - file_to_monitor = launcher.workspace.info_log_path - log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, - log_file_path=file_to_monitor) - - # Generate log lines to the info log using logger. - for expected_line in expected_lines: - logger.info(expected_line) - - # Start the Lumberyard client & test that the lines we logged can be viewed by the log monitor. - with launcher.start(): - log_test = log_monitor.monitor_log_for_lines( - expected_lines=expected_lines, # Defaults to None. - unexpected_lines=unexpected_lines, # Defaults to None. - halt_on_unexpected=True, # Defaults to False. - timeout=60) # Defaults to 30 - - # Assert the log monitor detected expected lines and did not detect any unexpected lines. - assert log_test, ( - f'Log monitoring failed. Used expected_lines values: {expected_lines} & ' - f'unexpected_lines values: {unexpected_lines}') diff --git a/Tools/LyTestTools/tests/integ/sanity_tests.py b/Tools/LyTestTools/tests/integ/sanity_tests.py index c6c5ce0c31..f68bc9ae57 100755 --- a/Tools/LyTestTools/tests/integ/sanity_tests.py +++ b/Tools/LyTestTools/tests/integ/sanity_tests.py @@ -6,49 +6,86 @@ SPDX-License-Identifier: Apache-2.0 OR MIT A sanity test for the built-in fixtures. Launch the windows launcher attached to the currently installed instance. """ +# Import any dependencies for the test. import logging import pytest +# Import any desired LTT modules from the package `ly_test_tools`. All LTT modules can be viewed at `Tools/LyTestTools/ly_test_tools`. import ly_test_tools +# The `launchers.launcher_helper` module helps create Launcher objects which control the Open 3D Engine (O3DE) Editor and game clients. import ly_test_tools.launchers.launcher_helper as launcher_helper +# The `builtin.helpers` module helps create the Workspace object, which controls the testing workspace in LTT. import ly_test_tools.builtin.helpers as helpers +# The `environment` module contains tools that involve the system's environment such as processes or timed waiters. import ly_test_tools.environment.process_utils as process_utils import ly_test_tools.environment.waiter as waiter -pytestmark = pytest.mark.SUITE_smoke - +# Initialize a logger instance to hook all test logs together. The sub-logger pattern below makes it easy to track which file creates a log line. logger = logging.getLogger(__name__) # Note: For device testing, device ids must exist in ~/ly_test_tools/devices.ini, see README.txt for more info. +# First define the class `TestAutomatedTestingProject` to group test functions together. +# The example test contains two test functions: `test_StartGameLauncher_Sanity` and `test_StartEditor_Sanity`. @pytest.mark.parametrize("project", ["AutomatedTesting"]) +# The example test utilizes Pytest parameterization. The following sets the `project` parameter to `AutomatedTesting` +# for both test functions. Notice that the Pytest mark is defined at the class level to affect both test functions. class TestAutomatedTestingProject(object): + def test_StartGameLauncher_Sanity(self, project): + """ + The `test_StartGameLauncher_Sanity` test function verifies that the O3DE game client launches successfully. + Start the test by utilizing the `kill_processes_named` function to close any open O3DE processes that may + interfere with the test. The Workspace object emulates the O3DE package by locating the engine and project + directories. The Launcher object controls the O3DE game client and requires a Workspace object for + initialization. Add the `-rhi=Null` arg to the executable call to disable GPU rendering. This allows the + test to run on instances without a GPU. We launch the game client executable and wait for the process to exist. + A try/finally block ensures proper test cleanup if issues occur during the test. + """ + # Kill processes that may interfere with the test process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) try: + # Create the Workspace object workspace = helpers.create_builtin_workspace(project=project) + # Create the Launcher object and add args launcher = launcher_helper.create_launcher(workspace) - launcher.args.extend(['-NullRenderer', '-BatchMode']) + launcher.args.extend(['-rhi=Null']) + # Call the game client executable with launcher.start(): + # Wait for the process to exist waiter.wait_for(lambda: process_utils.process_exists(f"{project}.GameLauncher.exe", ignore_extensions=True)) finally: + # Clean up processes after the test is finished process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) @pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Editor currently only functions on Windows") def test_StartEditor_Sanity(self, project): + """ + The `test_StartEditor_Sanity` test function is similar to the previous example with minor adjustments. A + PyTest mark skips the test if the operating system is not Windows. We use the `create_editor` function instead + of `create_launcher` to create an Editor type launcher instead of a game client type launcher. The additional + `-autotest_mode` arg supresses modal dialogs from interfering with our test. We launch the Editor executable and + wait for the process to exist. + """ + # Kill processes that may interfere with the test process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) try: + # Create the Workspace object workspace = helpers.create_builtin_workspace(project=project) + # Create the Launcher object and add args editor = launcher_helper.create_editor(workspace) - editor.args.extend(['-NullRenderer', '-autotest_mode']) + editor.args.extend(['-rhi=Null', '-autotest_mode']) + # Call the Editor executable with editor.start(): + # Wait for the process to exist waiter.wait_for(lambda: process_utils.process_exists("Editor", ignore_extensions=True)) finally: + # Clean up processes after the test is finished process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 7ab6006220..20b7a7c81d 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -100,18 +100,29 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar cmake_path(RELATIVE_PATH target_library_output_directory BASE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} OUTPUT_VARIABLE target_library_output_subdirectory) endif() - install( - TARGETS ${TARGET_NAME} - ARCHIVE - DESTINATION ${archive_output_directory}/${PAL_PLATFORM_NAME}/$ - COMPONENT ${install_component} - LIBRARY - DESTINATION ${library_output_directory}/${PAL_PLATFORM_NAME}/$/${target_library_output_subdirectory} - COMPONENT ${install_component} - RUNTIME - DESTINATION ${runtime_output_directory}/${PAL_PLATFORM_NAME}/$/${target_runtime_output_subdirectory} - COMPONENT ${install_component} - ) + if(COMMAND ly_install_target_override) + # Mac needs special handling because of a cmake issue + ly_install_target_override(TARGET ${TARGET_NAME} + ARCHIVE_DIR ${archive_output_directory} + LIBRARY_DIR ${library_output_directory} + RUNTIME_DIR ${runtime_output_directory} + LIBRARY_SUBDIR ${target_library_output_subdirectory} + RUNTIME_SUBDIR ${target_runtime_output_subdirectory} + ) + else() + install( + TARGETS ${TARGET_NAME} + ARCHIVE + DESTINATION ${archive_output_directory}/${PAL_PLATFORM_NAME}/$ + COMPONENT ${install_component} + LIBRARY + DESTINATION ${library_output_directory}/${PAL_PLATFORM_NAME}/$/${target_library_output_subdirectory} + COMPONENT ${install_component} + RUNTIME + DESTINATION ${runtime_output_directory}/${PAL_PLATFORM_NAME}/$/${target_runtime_output_subdirectory} + COMPONENT ${install_component} + ) + endif() # CMakeLists.txt file string(REGEX MATCH "(.*)::(.*)$" match ${ALIAS_TARGET_NAME}) @@ -487,7 +498,7 @@ function(ly_setup_others) # Scripts file(GLOB o3de_scripts "${LY_ROOT_FOLDER}/scripts/o3de.*") - install(FILES + install(PROGRAMS ${o3de_scripts} DESTINATION ./scripts ) @@ -505,6 +516,14 @@ function(ly_setup_others) DESTINATION . REGEX "downloaded_packages" EXCLUDE REGEX "runtime" EXCLUDE + REGEX ".*$\.sh" EXCLUDE + ) + + # For Mac/Linux shell scripts need to be installed as PROGRAMS to have execute permission + file(GLOB python_scripts "${LY_ROOT_FOLDER}/python/*.sh") + install(PROGRAMS + ${python_scripts} + DESTINATION ./python ) # Registry diff --git a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake index cad0e818cb..a1ded72255 100644 --- a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake +++ b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake @@ -77,6 +77,7 @@ ly_append_configurations_options( /Zc:forScope # Force Conformance in for Loop Scope /diagnostics:caret # Compiler diagnostic options: includes the column where the issue was found and places a caret (^) under the location in the line of code where the issue was detected. /Zc:__cplusplus + /Zc:lambda # Use the new lambda processor (See https://developercommunity.visualstudio.com/t/A-lambda-that-binds-the-this-pointer-w/1467873 for more details) /favor:AMD64 # Create Code optimized for 64 bit /bigobj # Increase number of sections in obj files. Profiling has shown no meaningful impact in memory nore build times COMPILATION_DEBUG diff --git a/cmake/Platform/Mac/Configurations_mac.cmake b/cmake/Platform/Mac/Configurations_mac.cmake index a3551be3b9..bdb358e9d2 100644 --- a/cmake/Platform/Mac/Configurations_mac.cmake +++ b/cmake/Platform/Mac/Configurations_mac.cmake @@ -28,7 +28,9 @@ else() endif() # Signing -ly_set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS --deep) +# The "-o linker-signed" flag is required as a work-around for the following CMake issue: +# https://gitlab.kitware.com/cmake/cmake/-/issues/21854 +ly_set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep -o linker-signed") # Generate scheme files for Xcode ly_set(CMAKE_XCODE_GENERATE_SCHEME TRUE) diff --git a/cmake/Platform/Mac/Install_mac.cmake b/cmake/Platform/Mac/Install_mac.cmake index 74ebd293ae..40f09a16b0 100644 --- a/cmake/Platform/Mac/Install_mac.cmake +++ b/cmake/Platform/Mac/Install_mac.cmake @@ -5,7 +5,47 @@ # # -# Empty implementations for untested platforms to fix build errors. +#! ly_install_target_override: Mac specific target installation +function(ly_install_target_override) -function(ly_setup_o3de_install) -endfunction() \ No newline at end of file + set(options) + set(oneValueArgs TARGET ARCHIVE_DIR LIBRARY_DIR RUNTIME_DIR LIBRARY_SUBDIR RUNTIME_SUBDIR) + set(multiValueArgs) + cmake_parse_arguments(ly_platform_install_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + get_property(install_component TARGET ${ly_platform_install_target_TARGET} PROPERTY INSTALL_COMPONENT) + + # For bundles on Mac, we set the icons by passing in a path to the Images.xcassets directory. + # However, the CMake install command expects paths to files for the the RESOURCE property. + # More details can be found in the CMake issue: https://gitlab.kitware.com/cmake/cmake/-/issues/22409 + get_target_property(is_bundle ${ly_platform_install_target_TARGET} MACOSX_BUNDLE) + if (${is_bundle}) + get_target_property(cached_resources_dir ${ly_platform_install_target_TARGET} RESOURCE) + set_property(TARGET ${ly_platform_install_target_TARGET} PROPERTY RESOURCE "") + endif() + + install( + TARGETS ${ly_platform_install_target_TARGET} + ARCHIVE + DESTINATION ${ly_platform_install_target_ARCHIVE_DIR}/${PAL_PLATFORM_NAME}/$ + COMPONENT ${install_component} + LIBRARY + DESTINATION ${ly_platform_install_target_LIBRARY_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_LIBRARY_SUBDIR} + COMPONENT ${install_component} + RUNTIME + DESTINATION ${ly_platform_install_target_RUNTIME_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_RUNTIME_SUBDIR} + COMPONENT ${install_component} + BUNDLE + DESTINATION ${ly_platform_install_target_RUNTIME_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_RUNTIME_SUBDIR} + COMPONENT ${install_component} + RESOURCE + DESTINATION ${ly_platform_install_target_RUNTIME_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_RUNTIME_SUBDIR}/ + COMPONENT ${install_component} + ) + + if (${is_bundle}) + set_property(TARGET ${ly_platform_install_target_TARGET} PROPERTY RESOURCE ${cached_resources_dir}) + endif() +endfunction() + +include(cmake/Platform/Common/Install_common.cmake)