diff --git a/AutomatedTesting/Assets/Prefabs/PinkFlower.prefab b/AutomatedTesting/Assets/Prefabs/PinkFlower.prefab
new file mode 100644
index 0000000000..47dd6bc8d3
--- /dev/null
+++ b/AutomatedTesting/Assets/Prefabs/PinkFlower.prefab
@@ -0,0 +1,131 @@
+{
+ "ContainerEntity": {
+ "Id": "ContainerEntity",
+ "Name": "PinkFlower",
+ "Components": {
+ "Component_[10444337162843472597]": {
+ "$type": "EditorLockComponent",
+ "Id": 10444337162843472597
+ },
+ "Component_[14431042590323756177]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14431042590323756177,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[491002114939]"
+ }
+ ]
+ },
+ "Component_[14577735453176806353]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 14577735453176806353
+ },
+ "Component_[15674021346798629563]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 15674021346798629563
+ },
+ "Component_[16784074985702513600]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 16784074985702513600,
+ "Parent Entity": ""
+ },
+ "Component_[3351614541100572773]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3351614541100572773
+ },
+ "Component_[3600658560328167663]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 3600658560328167663
+ },
+ "Component_[6155673728651558934]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 6155673728651558934
+ },
+ "Component_[8458684662170321289]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 8458684662170321289
+ },
+ "Component_[8705192117416252351]": {
+ "$type": "SelectionComponent",
+ "Id": 8705192117416252351
+ },
+ "Component_[8801280051488695852]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 8801280051488695852
+ }
+ }
+ },
+ "Entities": {
+ "Entity_[491002114939]": {
+ "Id": "Entity_[491002114939]",
+ "Name": "PinkFlower",
+ "Components": {
+ "Component_[11083205340162142682]": {
+ "$type": "EditorLockComponent",
+ "Id": 11083205340162142682
+ },
+ "Component_[11327363779873517]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 11327363779873517
+ },
+ "Component_[12717389211269537921]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 12717389211269537921
+ },
+ "Component_[12826285685970138542]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 12826285685970138542,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{549F4C4D-A7D9-5F2A-A6BD-F24C8BC43BBF}",
+ "subId": 280086017
+ },
+ "assetHint": "assets/objects/foliage/grass_flower_pink.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[14101419970865342875]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 14101419970865342875
+ },
+ "Component_[14770464075286403207]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 14770464075286403207
+ },
+ "Component_[15205142653091190082]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 15205142653091190082,
+ "Parent Entity": "ContainerEntity"
+ },
+ "Component_[15510898811147803772]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 15510898811147803772,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 15205142653091190082
+ },
+ {
+ "ComponentId": 12826285685970138542,
+ "SortIndex": 1
+ }
+ ]
+ },
+ "Component_[15988401742428977134]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 15988401742428977134
+ },
+ "Component_[4300550837037679336]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 4300550837037679336
+ },
+ "Component_[996914988793716659]": {
+ "$type": "SelectionComponent",
+ "Id": 996914988793716659
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Assets/TestAnim/rin_skeleton.fbx b/AutomatedTesting/Assets/TestAnim/rin_skeleton.fbx
new file mode 100644
index 0000000000..f727c26ad2
--- /dev/null
+++ b/AutomatedTesting/Assets/TestAnim/rin_skeleton.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:27f87510ae07771dbad3e430e31502b1d1d13dee868f143b7f1de2a7febc8eb9
+size 7046400
diff --git a/AutomatedTesting/Assets/TestAnim/rin_skeleton.fbx.assetinfo b/AutomatedTesting/Assets/TestAnim/rin_skeleton.fbx.assetinfo
new file mode 100644
index 0000000000..2d5502f42f
--- /dev/null
+++ b/AutomatedTesting/Assets/TestAnim/rin_skeleton.fbx.assetinfo
@@ -0,0 +1,8 @@
+{
+ "values": [
+ {
+ "$type": "ScriptProcessorRule",
+ "scriptFilename": "Assets/TestAnim/scene_export_actor.py"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Assets/TestAnim/scene_export_actor.py b/AutomatedTesting/Assets/TestAnim/scene_export_actor.py
new file mode 100644
index 0000000000..9dddc056a2
--- /dev/null
+++ b/AutomatedTesting/Assets/TestAnim/scene_export_actor.py
@@ -0,0 +1,221 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+import traceback, sys, uuid, os, json
+
+#
+# Example for exporting ActorGroup scene rules
+#
+
+def log_exception_traceback():
+ exc_type, exc_value, exc_tb = sys.exc_info()
+ data = traceback.format_exception(exc_type, exc_value, exc_tb)
+ print(str(data))
+
+def get_node_names(sceneGraph, nodeTypeName, testEndPoint = False, validList = None):
+ import azlmbr.scene.graph
+ import scene_api.scene_data
+
+ node = sceneGraph.get_root()
+ nodeList = []
+ children = []
+ paths = []
+
+ while node.IsValid():
+ # store children to process after siblings
+ if sceneGraph.has_node_child(node):
+ children.append(sceneGraph.get_node_child(node))
+
+ nodeName = scene_api.scene_data.SceneGraphName(sceneGraph.get_node_name(node))
+ paths.append(nodeName.get_path())
+
+ include = True
+
+ if (validList is not None):
+ include = False # if a valid list filter provided, assume to not include node name
+ name_parts = nodeName.get_path().split('.')
+ for valid in validList:
+ if (valid in name_parts[-1]):
+ include = True
+ break
+
+ # store any node that has provides specifc data content
+ nodeContent = sceneGraph.get_node_content(node)
+ if include and nodeContent.CastWithTypeName(nodeTypeName):
+ if testEndPoint is not None:
+ include = sceneGraph.is_node_end_point(node) is testEndPoint
+ if include:
+ if (len(nodeName.get_path())):
+ nodeList.append(scene_api.scene_data.SceneGraphName(sceneGraph.get_node_name(node)))
+
+ # advance to next node
+ if sceneGraph.has_node_sibling(node):
+ node = sceneGraph.get_node_sibling(node)
+ elif children:
+ node = children.pop()
+ else:
+ node = azlmbr.scene.graph.NodeIndex()
+
+ return nodeList, paths
+
+def generate_mesh_group(scene, sceneManifest, meshDataList, paths):
+ # Compute the name of the scene file
+ clean_filename = scene.sourceFilename.replace('.', '_')
+ mesh_group_name = os.path.basename(clean_filename)
+
+ # make the mesh group
+ mesh_group = sceneManifest.add_mesh_group(mesh_group_name)
+ mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, clean_filename)) + '}'
+
+ # add all nodes to this mesh group
+ for activeMeshIndex in range(len(meshDataList)):
+ mesh_name = meshDataList[activeMeshIndex]
+ mesh_path = mesh_name.get_path()
+ sceneManifest.mesh_group_select_node(mesh_group, mesh_path)
+
+def create_shape_configuration(nodeName):
+ import scene_api.physics_data
+
+ if(nodeName in ['_foot_','_wrist_']):
+ shapeConfiguration = scene_api.physics_data.BoxShapeConfiguration()
+ shapeConfiguration.scale = [1.1, 1.1, 1.1]
+ shapeConfiguration.dimensions = [2.1, 3.1, 4.1]
+ return shapeConfiguration
+ else:
+ shapeConfiguration = scene_api.physics_data.CapsuleShapeConfiguration()
+ shapeConfiguration.scale = [1.0, 1.0, 1.0]
+ shapeConfiguration.height = 1.0
+ shapeConfiguration.radius = 1.0
+ return shapeConfiguration
+
+def create_collider_configuration(nodeName):
+ import scene_api.physics_data
+
+ colliderConfiguration = scene_api.physics_data.ColliderConfiguration()
+ colliderConfiguration.Position = [0.1, 0.1, 0.2]
+ colliderConfiguration.Rotation = [45.0, 35.0, 25.0]
+ return colliderConfiguration
+
+def generate_physics_nodes(actorPhysicsSetupRule, nodeNameList):
+ import scene_api.physics_data
+
+ hitDetectionConfig = scene_api.physics_data.CharacterColliderConfiguration()
+ simulatedObjectColliderConfig = scene_api.physics_data.CharacterColliderConfiguration()
+ clothConfig = scene_api.physics_data.CharacterColliderConfiguration()
+ ragdollConfig = scene_api.physics_data.RagdollConfiguration()
+
+ for nodeName in nodeNameList:
+ shapeConfiguration = create_shape_configuration(nodeName)
+ colliderConfiguration = create_collider_configuration(nodeName)
+ hitDetectionConfig.add_character_collider_node_configuration_node(nodeName, colliderConfiguration, shapeConfiguration)
+ simulatedObjectColliderConfig.add_character_collider_node_configuration_node(nodeName, colliderConfiguration, shapeConfiguration)
+ clothConfig.add_character_collider_node_configuration_node(nodeName, colliderConfiguration, shapeConfiguration)
+ #
+ ragdollNode = scene_api.physics_data.RagdollNodeConfiguration()
+ ragdollNode.JointConfig.Name = nodeName
+ ragdollConfig.add_ragdoll_node_configuration(ragdollNode)
+ ragdollConfig.colliders.add_character_collider_node_configuration_node(nodeName, colliderConfiguration, shapeConfiguration)
+
+ actorPhysicsSetupRule.set_simulated_object_collider_config(simulatedObjectColliderConfig)
+ actorPhysicsSetupRule.set_hit_detection_config(hitDetectionConfig)
+ actorPhysicsSetupRule.set_cloth_config(clothConfig)
+ actorPhysicsSetupRule.set_ragdoll_config(ragdollConfig)
+
+def generate_actor_group(scene, sceneManifest, meshDataList, paths):
+ import scene_api.scene_data
+ import scene_api.physics_data
+ import scene_api.actor_group
+
+ # fetch bone data
+ validNames = ['_neck_','_pelvis_','_leg_','_knee_','_spine_','_arm_','_clavicle_','_head_','_elbow_','_wrist_']
+ graph = scene_api.scene_data.SceneGraph(scene.graph)
+ nodeList, allNodePaths = get_node_names(graph, 'BoneData', validList = validNames)
+
+ nodeNameList = []
+ for activeMeshIndex, nodeName in enumerate(nodeList):
+ nodeNameList.append(nodeName.get_name())
+
+ # add comment
+ commentRule = scene_api.actor_group.CommentRule()
+ commentRule.text = str(nodeNameList)
+
+ # ActorPhysicsSetupRule
+ actorPhysicsSetupRule = scene_api.actor_group.ActorPhysicsSetupRule()
+ generate_physics_nodes(actorPhysicsSetupRule, nodeNameList)
+
+ # add scale of the Actor rule
+ actorScaleRule = scene_api.actor_group.ActorScaleRule()
+ actorScaleRule.scaleFactor = 2.0
+
+ # add coordinate system rule
+ coordinateSystemRule = scene_api.actor_group.CoordinateSystemRule()
+ coordinateSystemRule.useAdvancedData = False
+
+ # add morph target rule
+ morphTargetRule = scene_api.actor_group.MorphTargetRule()
+ morphTargetRule.targets.select_targets([nodeNameList[0]], nodeNameList)
+
+ # add skeleton optimization rule
+ skeletonOptimizationRule = scene_api.actor_group.SkeletonOptimizationRule()
+ skeletonOptimizationRule.autoSkeletonLOD = True
+ skeletonOptimizationRule.criticalBonesList.select_targets([nodeNameList[0:2]], nodeNameList)
+
+ # add LOD rule
+ lodRule = scene_api.actor_group.LodRule()
+ lodRule0 = lodRule.add_lod_level(0)
+ lodRule0.select_targets([nodeNameList[1:4]], nodeNameList)
+
+ actorGroup = scene_api.actor_group.ActorGroup()
+ actorGroup.name = os.path.basename(scene.sourceFilename)
+ actorGroup.add_rule(actorScaleRule)
+ actorGroup.add_rule(coordinateSystemRule)
+ actorGroup.add_rule(skeletonOptimizationRule)
+ actorGroup.add_rule(morphTargetRule)
+ actorGroup.add_rule(lodRule)
+ actorGroup.add_rule(actorPhysicsSetupRule)
+ actorGroup.add_rule(commentRule)
+ sceneManifest.manifest['values'].append(actorGroup.to_dict())
+
+def update_manifest(scene):
+ import json, uuid, os
+ import azlmbr.scene.graph
+ import scene_api.scene_data
+
+ graph = scene_api.scene_data.SceneGraph(scene.graph)
+ mesh_name_list, all_node_paths = get_node_names(graph, 'MeshData')
+ scene_manifest = scene_api.scene_data.SceneManifest()
+ generate_actor_group(scene, scene_manifest, mesh_name_list, all_node_paths)
+ generate_mesh_group(scene, scene_manifest, mesh_name_list, all_node_paths)
+
+ # Convert the manifest to a JSON string and return it
+ return scene_manifest.export()
+
+sceneJobHandler = None
+
+def on_update_manifest(args):
+ try:
+ scene = args[0]
+ return update_manifest(scene)
+ except RuntimeError as err:
+ print (f'ERROR - {err}')
+ log_exception_traceback()
+ except:
+ log_exception_traceback()
+
+ global sceneJobHandler
+ sceneJobHandler.disconnect()
+ sceneJobHandler = None
+
+# try to create SceneAPI handler for processing
+try:
+ import azlmbr.scene
+
+ sceneJobHandler = azlmbr.scene.ScriptBuildingNotificationBusHandler()
+ sceneJobHandler.connect()
+ sceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest)
+except:
+ sceneJobHandler = None
diff --git a/AutomatedTesting/Assets/Textures/image.png b/AutomatedTesting/Assets/Textures/image.png
new file mode 100644
index 0000000000..2f558c634e
--- /dev/null
+++ b/AutomatedTesting/Assets/Textures/image.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:011454252e40c927343cce16296412f02f45d1f345c75c036651bdcca473bda5
+size 2672
diff --git a/AutomatedTesting/Assets/Textures/normal.png b/AutomatedTesting/Assets/Textures/normal.png
new file mode 100644
index 0000000000..d3355e6699
--- /dev/null
+++ b/AutomatedTesting/Assets/Textures/normal.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7bafcc4aefab827e1414e64bcdde235500b51392e52c9ccd588b2d7a24b865a0
+size 20214
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_1B66C428-1D7C-4A53-BC9B-6F23E420FEC0_Irradiance_lutrgba16.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_1B66C428-1D7C-4A53-BC9B-6F23E420FEC0_Irradiance_lutrgba16.dds
new file mode 100644
index 0000000000..e208940f0d
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_1B66C428-1D7C-4A53-BC9B-6F23E420FEC0_Irradiance_lutrgba16.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ac841c02e81c9ae23476522b7e517889d746d4ff32b3251ac4360168f39b30a3
+size 450708
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_52D75B1C-90BE-40A8-A874-3376F6B39299_Relocation_lutrgba16f.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_52D75B1C-90BE-40A8-A874-3376F6B39299_Relocation_lutrgba16f.dds
new file mode 100644
index 0000000000..32f2ee1b17
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_52D75B1C-90BE-40A8-A874-3376F6B39299_Relocation_lutrgba16f.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3653ca7fb42c7e5991815c17fc9ebeab14a1aa861bfb1d37e233ada66a835f00
+size 7188
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_5A2C9A6B-F914-4D9E-8098-2AD411B69F87_Distance_lutrg32f.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_5A2C9A6B-F914-4D9E-8098-2AD411B69F87_Distance_lutrg32f.dds
new file mode 100644
index 0000000000..12c1d8d112
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_5A2C9A6B-F914-4D9E-8098-2AD411B69F87_Distance_lutrg32f.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a30b85428202c548e77cdcc0a595f9f26e82d29622be26891d569f4779a75830
+size 1802388
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_A483018F-78ED-4814-986F-F925B0AA5EF8_Classification_lutr32f.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_A483018F-78ED-4814-986F-F925B0AA5EF8_Classification_lutr32f.dds
new file mode 100644
index 0000000000..df2c69bfe9
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_01_A483018F-78ED-4814-986F-F925B0AA5EF8_Classification_lutr32f.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a3d76b7c93f8873ca7c4013dcc4eff887c25552c9c5847290481306656b22069
+size 3668
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_222F1F65-BF31-4E0D-9957-14AE73194A37_Classification_lutr32f.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_222F1F65-BF31-4E0D-9957-14AE73194A37_Classification_lutr32f.dds
new file mode 100644
index 0000000000..5c990de348
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_222F1F65-BF31-4E0D-9957-14AE73194A37_Classification_lutr32f.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:219f57137c5bd44093762ea9d0fc24308679956b980f26bf194edd3a1798fcda
+size 3668
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_84D0F8A4-AD4F-4FD1-BA26-4803EAD88FE2_Distance_lutrg32f.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_84D0F8A4-AD4F-4FD1-BA26-4803EAD88FE2_Distance_lutrg32f.dds
new file mode 100644
index 0000000000..367da91f13
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_84D0F8A4-AD4F-4FD1-BA26-4803EAD88FE2_Distance_lutrg32f.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:96ed61c66d1d1f71e940ab75899ee253007e704004e1157c900c6308151a8bf1
+size 1802388
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_9DC8C208-5327-4F0F-B1DF-C98F7F81F07D_Relocation_lutrgba16f.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_9DC8C208-5327-4F0F-B1DF-C98F7F81F07D_Relocation_lutrgba16f.dds
new file mode 100644
index 0000000000..b6d735cf50
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_9DC8C208-5327-4F0F-B1DF-C98F7F81F07D_Relocation_lutrgba16f.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:70a7dc4e2455624067e842b059954f6c4bb9b0debc3cb1ffa783b14bffc61786
+size 7188
diff --git a/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_A78EEAF4-7CB2-4635-AA6F-2ED677328706_Irradiance_lutrgba16.dds b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_A78EEAF4-7CB2-4635-AA6F-2ED677328706_Irradiance_lutrgba16.dds
new file mode 100644
index 0000000000..e46f54586a
--- /dev/null
+++ b/AutomatedTesting/DiffuseProbeGrids/DiffuseGI_02_A78EEAF4-7CB2-4635-AA6F-2ED677328706_Irradiance_lutrgba16.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7f5a945c61f92f3da77dfd9fdd2c95aa257f4df6bcb82483c608ab660bb72e5f
+size 450708
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
index 87a66c880e..26eb96e7ec 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
@@ -47,18 +47,4 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED)
COMPONENT
Atom
)
- ly_add_pytest(
- NAME AutomatedTesting::Atom_TestSuite_Main_GPU_Optimized
- TEST_SUITE main
- TEST_REQUIRES gpu
- TEST_SERIAL
- TIMEOUT 1200
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_GPU_Optimized.py
- RUNTIME_DEPENDENCIES
- AssetProcessor
- AutomatedTesting.Assets
- Editor
- COMPONENT
- Atom
- )
endif()
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
index 6a220d1bd8..14d850245c 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
@@ -4,129 +4,82 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-
-import datetime
import logging
import os
-import zipfile
import pytest
+import editor_python_test_tools.hydra_test_utils as hydra
import ly_test_tools.environment.file_system as file_system
from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator
+from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
+from Atom.atom_utils.atom_component_helper import compare_screenshot_to_golden_image, golden_images_directory
-import editor_python_test_tools.hydra_test_utils as hydra
-from .atom_utils.atom_component_helper import compare_screenshot_similarity, ImageComparisonTestFailure
-
-logger = logging.getLogger(__name__)
DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots'
-TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
-
-
-def golden_images_directory():
- """
- Uses this file location to return the valid location for golden image files.
- :return: The path to the golden_images directory, but raises an IOError if the golden_images directory is missing.
- """
- current_file_directory = os.path.join(os.path.dirname(__file__))
- golden_images_dir = os.path.join(current_file_directory, 'golden_images')
-
- if not os.path.exists(golden_images_dir):
- raise IOError(
- f'golden_images" directory was not found at path "{golden_images_dir}"'
- f'Please add a "golden_images" directory inside: "{current_file_directory}"'
- )
-
- return golden_images_dir
-
-
-def create_screenshots_archive(screenshot_path):
- """
- Creates a new zip file archive at archive_path containing all files listed within archive_path.
- :param screenshot_path: location containing the files to archive, the zip archive file will also be saved here.
- :return: None, but creates a new zip file archive inside path containing all of the files inside archive_path.
- """
- files_to_archive = []
-
- # Search for .png and .ppm files to add to the zip archive file.
- for (folder_name, sub_folders, file_names) in os.walk(screenshot_path):
- for file_name in file_names:
- if file_name.endswith(".png") or file_name.endswith(".ppm"):
- file_path = os.path.join(folder_name, file_name)
- files_to_archive.append(file_path)
-
- # Setup variables for naming the zip archive file.
- timestamp = datetime.datetime.now().timestamp()
- formatted_timestamp = datetime.datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d_%H-%M-%S")
- screenshots_file = os.path.join(screenshot_path, f'zip_archive_{formatted_timestamp}.zip')
-
- # Write all of the valid .png and .ppm files to the archive file.
- with zipfile.ZipFile(screenshots_file, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) as zip_archive:
- for file_path in files_to_archive:
- file_name = os.path.basename(file_path)
- zip_archive.write(file_path, file_name)
+logger = logging.getLogger(__name__)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
-@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
-@pytest.mark.parametrize("level", ["Base"])
-class TestAllComponentsIndepthTests(object):
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+class TestAutomation(EditorTestSuite):
+ # Remove -autotest_mode from global_extra_cmdline_args since we need rendering for these tests.
+ global_extra_cmdline_args = ["-BatchMode"] # Default is ["-BatchMode", "-autotest_mode"]
+
+ enable_prefab_system = False
- @pytest.mark.parametrize("screenshot_name", ["AtomBasicLevelSetup.ppm"])
@pytest.mark.test_case_id("C34603773")
- def test_BasicLevelSetup_SetsUpLevel(
- self, request, editor, workspace, project, launcher_platform, level, screenshot_name):
- """
- Please review the hydra script run by this test for more specific test info.
- Tests that a basic rendering level setup can be created (lighting, meshes, materials, etc.).
- """
+ class AtomGPU_BasicLevelSetup_SetsUpLevel(EditorSharedTest):
+ use_null_renderer = False # Default is True
+ screenshot_name = "AtomBasicLevelSetup.ppm"
+ test_screenshots = [] # Gets set by setup()
+ screenshot_directory = "" # Gets set by setup()
+
# Clear existing test screenshots before starting test.
- screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
- test_screenshots = [os.path.join(screenshot_directory, screenshot_name)]
- file_system.delete(test_screenshots, True, True)
+ def setup(self, workspace):
+ screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
+ test_screenshots = [os.path.join(screenshot_directory, self.screenshot_name)]
+ file_system.delete(test_screenshots, True, True)
golden_images = [os.path.join(golden_images_directory(), screenshot_name)]
- level_creation_expected_lines = [
- "Viewport is set to the expected size: True",
- "Exited game mode"
- ]
- unexpected_lines = ["Traceback (most recent call last):"]
+ from Atom.tests import hydra_AtomGPU_BasicLevelSetup as test_module
- hydra.launch_and_validate_results(
- request,
- TEST_DIRECTORY,
- editor,
- "hydra_GPUTest_BasicLevelSetup.py",
- timeout=180,
- expected_lines=level_creation_expected_lines,
- unexpected_lines=unexpected_lines,
- halt_on_unexpected=True,
- cfg_args=[level],
- null_renderer=False,
- enable_prefab_system=False,
- )
-
- similarity_threshold = 0.99
- for test_screenshot, golden_image in zip(test_screenshots, golden_images):
- screenshot_comparison_result = compare_screenshot_similarity(
- test_screenshot, golden_image, similarity_threshold, True, screenshot_directory)
- if screenshot_comparison_result != "Screenshots match":
- raise Exception(f"Screenshot test failed: {screenshot_comparison_result}")
+ assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True
@pytest.mark.test_case_id("C34525095")
- def test_LightComponent_ScreenshotMatchesGoldenImage(
- self, request, editor, workspace, project, launcher_platform, level):
- """
- Please review the hydra script run by this test for more specific test info.
- Tests that the Light component screenshots in a rendered level appear the same as the golden images.
- """
+ class AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages(EditorSharedTest):
+ use_null_renderer = False # Default is True
screenshot_names = [
"AreaLight_1.ppm",
"AreaLight_2.ppm",
"AreaLight_3.ppm",
"AreaLight_4.ppm",
"AreaLight_5.ppm",
+ ]
+ test_screenshots = [] # Gets set by setup()
+ screenshot_directory = "" # Gets set by setup()
+
+ # Clear existing test screenshots before starting test.
+ def setup(self, workspace):
+ screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
+ for screenshot in self.screenshot_names:
+ screenshot_path = os.path.join(screenshot_directory, screenshot)
+ self.test_screenshots.append(screenshot_path)
+ file_system.delete(self.test_screenshots, True, True)
+
+ golden_images = []
+ for golden_image in screenshot_names:
+ golden_image_path = os.path.join(golden_images_directory(), golden_image)
+ golden_images.append(golden_image_path)
+
+ from Atom.tests import hydra_AtomGPU_AreaLightScreenshotTest as test_module
+
+ assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True
+
+ @pytest.mark.test_case_id("C34525110")
+ class AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages(EditorSharedTest):
+ use_null_renderer = False # Default is True
+ screenshot_names = [
"SpotLight_1.ppm",
"SpotLight_2.ppm",
"SpotLight_3.ppm",
@@ -134,40 +87,25 @@ class TestAllComponentsIndepthTests(object):
"SpotLight_5.ppm",
"SpotLight_6.ppm",
]
- screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
- test_screenshots = []
- for screenshot in screenshot_names:
- screenshot_path = os.path.join(screenshot_directory, screenshot)
- test_screenshots.append(screenshot_path)
- file_system.delete(test_screenshots, True, True)
+ test_screenshots = [] # Gets set by setup()
+ screenshot_directory = "" # Gets set by setup()
+
+ # Clear existing test screenshots before starting test.
+ def setup(self, workspace):
+ screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
+ for screenshot in self.screenshot_names:
+ screenshot_path = os.path.join(screenshot_directory, screenshot)
+ self.test_screenshots.append(screenshot_path)
+ file_system.delete(self.test_screenshots, True, True)
golden_images = []
for golden_image in screenshot_names:
golden_image_path = os.path.join(golden_images_directory(), golden_image)
golden_images.append(golden_image_path)
- expected_lines = ["spot_light Controller|Configuration|Shadows|Shadowmap size: SUCCESS"]
- unexpected_lines = ["Traceback (most recent call last):"]
- hydra.launch_and_validate_results(
- request,
- TEST_DIRECTORY,
- editor,
- "hydra_GPUTest_LightComponent.py",
- timeout=180,
- expected_lines=expected_lines,
- unexpected_lines=unexpected_lines,
- halt_on_unexpected=True,
- cfg_args=[level],
- null_renderer=False,
- enable_prefab_system=False,
- )
+ from Atom.tests import hydra_AtomGPU_SpotLightScreenshotTest as test_module
- similarity_threshold = 0.99
- for test_screenshot, golden_image in zip(test_screenshots, golden_images):
- screenshot_comparison_result = compare_screenshot_similarity(
- test_screenshot, golden_image, similarity_threshold, True, screenshot_directory)
- if screenshot_comparison_result != "Screenshots match":
- raise ImageComparisonTestFailure(f"Screenshot test failed: {screenshot_comparison_result}")
+ assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True
@pytest.mark.parametrize('rhi', ['dx12', 'vulkan'])
@@ -198,7 +136,7 @@ class TestPerformanceBenchmarkSuite(object):
hydra.launch_and_validate_results(
request,
- TEST_DIRECTORY,
+ os.path.join(os.path.dirname(__file__), "tests"),
editor,
"hydra_GPUTest_AtomFeatureIntegrationBenchmark.py",
timeout=600,
@@ -235,7 +173,7 @@ class TestMaterialEditor(object):
hydra.launch_and_validate_results(
request,
- TEST_DIRECTORY,
+ os.path.join(os.path.dirname(__file__), "tests"),
generic_launcher,
editor_script="",
run_python="--runpython",
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py
deleted file mode 100644
index 7f97c132bb..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project.
-For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-"""
-import os
-
-import pytest
-
-import ly_test_tools.environment.file_system as file_system
-from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
-from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots
-from .atom_utils.atom_component_helper import create_screenshots_archive, golden_images_directory
-
-DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots'
-
-
-@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-class TestAutomation(EditorTestSuite):
- # Remove -autotest_mode from global_extra_cmdline_args since we need rendering for these tests.
- global_extra_cmdline_args = ["-BatchMode"] # Default is ["-BatchMode", "-autotest_mode"]
-
- enable_prefab_system = False
-
- @pytest.mark.test_case_id("C34603773")
- class AtomGPU_BasicLevelSetup_SetsUpLevel(EditorSharedTest):
- use_null_renderer = False # Default is True
- screenshot_name = "AtomBasicLevelSetup.ppm"
- test_screenshots = [] # Gets set by setup()
- screenshot_directory = "" # Gets set by setup()
-
- # Clear existing test screenshots before starting test.
- def setup(self, workspace):
- screenshot_directory = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH)
- test_screenshots = [os.path.join(screenshot_directory, self.screenshot_name)]
- file_system.delete(test_screenshots, True, True)
-
- from Atom.tests import hydra_AtomGPU_BasicLevelSetup as test_module
-
- golden_images = [os.path.join(golden_images_directory(), screenshot_name)]
- for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
- compare_screenshots(test_screenshot, golden_screenshot)
- create_screenshots_archive(screenshot_directory)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
index 9f37873557..5fdd4c810d 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
@@ -93,161 +93,165 @@ def compare_screenshot_similarity(
return result
-def create_basic_atom_level(level_name):
+def compare_screenshot_to_golden_image(
+ screenshot_directory, test_screenshots, golden_images, similarity_threshold=0.99):
"""
- Creates a new level inside the Editor matching level_name & adds the following:
- 1. "default_level" entity to hold all other entities.
- 2. Adds Grid, Global Skylight (IBL), ground Mesh, Directional Light, Sphere w/ material+mesh, & Camera components.
- 3. Each of these components has its settings tweaked slightly to match the ideal scene to test Atom rendering.
- :param level_name: name of the level to create and apply this basic setup to.
+ Compares a list of test_screenshots to a list of golden_images and return True if they match within the
+ similarity threshold set. Otherwise, it will raise ImageComparisonTestFailure with a failure message.
+ :param screenshot_directory: path to the directory containing screenshots for creating .zip archives.
+ :param test_screenshots: list of test screenshot path strings.
+ :param golden_images: list of golden image path strings.
+ :param similarity_threshold: float threshold tolerance to set when comparing screenshots to golden images.
+ """
+ for test_screenshot, golden_image in zip(test_screenshots, golden_images):
+ screenshot_comparison_result = compare_screenshot_similarity(
+ test_screenshot, golden_image, similarity_threshold, True, screenshot_directory)
+ if screenshot_comparison_result != "Screenshots match":
+ raise ImageComparisonTestFailure(f"Screenshot test failed: {screenshot_comparison_result}")
+
+ return True
+
+
+def initial_viewport_setup(screen_width=1280, screen_height=720):
+ """
+ For setting up the initial viewport resolution to expected default values before running a screenshot test.
+ Defaults to 1280 x 720 resolution (in pixels).
+ :param screen_width: Width in pixels to set the viewport width size to.
+ :param screen_height: Height in pixels to set the viewport height size to.
+ :return: None
+ """
+ import azlmbr.legacy.general as general
+
+ general.set_viewport_size(screen_width, screen_height)
+ general.update_viewport()
+
+
+def enter_exit_game_mode_take_screenshot(screenshot_name, enter_game_tuple, exit_game_tuple, timeout_in_seconds=4):
+ """
+ Enters game mode, takes a screenshot named screenshot_name (must include file extension), and exits game mode.
+ :param screenshot_name: string representing the name of the screenshot file, including file extension.
+ :param enter_game_tuple: tuple where the 1st string is success & 2nd string is failure for entering the game.
+ :param exit_game_tuple: tuple where the 1st string is success & 2nd string is failure for exiting the game.
+ :param timeout_in_seconds: int or float seconds to wait for entering/exiting game mode.
:return: None
"""
- import azlmbr.asset as asset
- import azlmbr.bus as bus
- import azlmbr.camera as camera
- import azlmbr.editor as editor
- import azlmbr.entity as entity
import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.utils import TestHelper
+
+ from Atom.atom_utils.screenshot_utils import ScreenshotHelper
+
+ TestHelper.enter_game_mode(enter_game_tuple)
+ TestHelper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=timeout_in_seconds)
+ ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(screenshot_name)
+ TestHelper.exit_game_mode(exit_game_tuple)
+ TestHelper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=timeout_in_seconds)
+
+
+def create_basic_atom_rendering_scene():
+ """
+ Sets up a new scene inside the Editor for testing Atom rendering GPU output.
+ Setup: Deletes all existing entities before creating the scene.
+ The created scene includes:
+ 1. "Default Level" entity that holds all of the other entities.
+ 2. "Grid" entity: Contains a Grid component.
+ 3. "Global Skylight (IBL)" entity: Contains HDRI Skybox & Global Skylight (IBL) components.
+ 4. "Ground Plane" entity: Contains Material & Mesh components.
+ 5. "Directional Light" entity: Contains Directional Light component.
+ 6. "Sphere" entity: Contains Material & Mesh components.
+ 7. "Camera" entity: Contains Camera component.
+ :return: None
+ """
import azlmbr.math as math
- import azlmbr.object
+ import azlmbr.paths
- import editor_python_test_tools.hydra_editor_utils as hydra
- from editor_python_test_tools.editor_test_helper import EditorTestHelper
+ from editor_python_test_tools.asset_utils import Asset
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
- helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
- # Wait for Editor idle loop before executing Python hydra scripts.
- general.idle_enable(True)
+ DEGREE_RADIAN_FACTOR = 0.0174533
- # Basic setup for opened level.
- helper.open_level(level_name="Base")
- general.idle_wait(1.0)
- general.update_viewport()
- general.idle_wait(0.5) # half a second is more than enough for updating the viewport.
-
- # Close out problematic windows, FPS meters, and anti-aliasing.
- if general.is_helpers_shown(): # Turn off the helper gizmos if visible
- general.toggle_helpers()
- general.idle_wait(1.0)
- if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus.
- general.close_pane("Error Report")
- if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus.
- general.close_pane("Error Log")
- general.idle_wait(1.0)
- general.run_console("r_displayInfo=0")
- general.idle_wait(1.0)
-
- # Delete all existing entities & create default_level entity
+ # Setup: Deletes all existing entities before creating the scene.
search_filter = azlmbr.entity.SearchFilter()
- all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
- editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
- default_level = hydra.Entity("default_level")
- default_position = math.Vector3(0.0, 0.0, 0.0)
- default_level.create_entity(default_position, ["Grid"])
- default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0)
-
- # Set the viewport up correctly after adding the parent default_level entity.
- screen_width = 1280
- screen_height = 720
- degree_radian_factor = 0.0174533 # Used by "Rotation" property for the Transform component.
- general.set_viewport_size(screen_width, screen_height)
- general.update_viewport()
- helper.wait_for_condition(
- function=lambda: helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1)
- and helper.isclose(a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1),
- timeout_in_seconds=4.0
- )
- result = helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) and helper.isclose(
- a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1)
- general.log(general.get_viewport_size().x)
- general.log(general.get_viewport_size().y)
- general.log(general.get_viewport_size().z)
- general.log(f"Viewport is set to the expected size: {result}")
- general.log("Basic level created")
- general.run_console("r_DisplayInfo = 0")
-
- # Create global_skylight entity and set the properties
- global_skylight = hydra.Entity("global_skylight")
- global_skylight.create_entity(
- entity_position=default_position,
- components=["HDRi Skybox", "Global Skylight (IBL)"],
- parent_id=default_level.id)
- global_skylight_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
- global_skylight_asset_value = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False)
- global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value)
- global_skylight.get_set_test(1, "Controller|Configuration|Diffuse Image", global_skylight_asset_value)
- global_skylight.get_set_test(1, "Controller|Configuration|Specular Image", global_skylight_asset_value)
-
- # Create ground_plane entity and set the properties
- ground_plane = hydra.Entity("ground_plane")
- ground_plane.create_entity(
- entity_position=default_position,
- components=["Material"],
- parent_id=default_level.id)
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0)
-
- # Work around to add the correct Atom Mesh component and asset.
- mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId
- ground_plane.components.append(
- editor.EditorComponentAPIBus(
- bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id]
- ).GetValue()[0]
- )
+ all_entities = azlmbr.entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
+ azlmbr.editor.ToolsApplicationRequestBus(azlmbr.bus.Broadcast, "DeleteEntities", all_entities)
+
+ # 1. "Default Level" entity that holds all of the other entities.
+ default_level_entity_name = "Default Level"
+ default_level_entity = EditorEntity.create_editor_entity_at(math.Vector3(0.0, 0.0, 0.0), default_level_entity_name)
+
+ # 2. "Grid" entity: Contains a Grid component.
+ grid_entity = EditorEntity.create_editor_entity(AtomComponentProperties.grid(), default_level_entity.id)
+ grid_component = grid_entity.add_component(AtomComponentProperties.grid())
+ secondary_grid_spacing_value = 1.0
+ grid_component.set_component_property_value(
+ AtomComponentProperties.grid('Secondary Grid Spacing'), secondary_grid_spacing_value)
+
+ # 3. "Global Skylight (IBL)" entity: Contains HDRI Skybox & Global Skylight (IBL) components.
+ global_skylight_entity = EditorEntity.create_editor_entity(
+ AtomComponentProperties.global_skylight(), default_level_entity.id)
+ hdri_skybox_component = global_skylight_entity.add_component(AtomComponentProperties.hdri_skybox())
+ global_skylight_component = global_skylight_entity.add_component(AtomComponentProperties.global_skylight())
+ global_skylight_image_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
+ global_skylight_image_asset = Asset.find_asset_by_path(global_skylight_image_asset_path, False)
+ hdri_skybox_component.set_component_property_value(
+ AtomComponentProperties.hdri_skybox('Cubemap Texture'), global_skylight_image_asset.id)
+ global_skylight_diffuse_image_asset_path = os.path.join(
+ "LightingPresets", "default_iblskyboxcm_ibldiffuse.exr.streamingimage")
+ global_skylight_diffuse_image_asset = Asset.find_asset_by_path(global_skylight_diffuse_image_asset_path, False)
+ global_skylight_component.set_component_property_value(
+ AtomComponentProperties.global_skylight('Diffuse Image'), global_skylight_diffuse_image_asset.id)
+ global_skylight_specular_image_asset_path = os.path.join(
+ "LightingPresets", "default_iblskyboxcm_iblspecular.exr.streamingimage")
+ global_skylight_specular_image_asset = Asset.find_asset_by_path(
+ global_skylight_specular_image_asset_path, False)
+ global_skylight_component.set_component_property_value(
+ AtomComponentProperties.global_skylight('Specular Image'), global_skylight_specular_image_asset.id)
+
+ # 4. "Ground Plane" entity: Contains Material & Mesh components.
+ ground_plane_name = "Ground Plane"
+ ground_plane_entity = EditorEntity.create_editor_entity(ground_plane_name, default_level_entity.id)
+ ground_plane_material_component = ground_plane_entity.add_component(AtomComponentProperties.material())
+ ground_plane_entity.set_local_uniform_scale(32.0)
+ ground_plane_mesh_component = ground_plane_entity.add_component(AtomComponentProperties.mesh())
ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel")
- ground_plane_mesh_asset_value = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False)
- ground_plane.get_set_test(1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset_value)
-
- # Add Atom Material component and asset.
+ ground_plane_mesh_asset = Asset.find_asset_by_path(ground_plane_mesh_asset_path, False)
+ ground_plane_mesh_component.set_component_property_value(
+ AtomComponentProperties.mesh('Mesh Asset'), ground_plane_mesh_asset.id)
ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial")
- ground_plane_material_asset_value = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False)
- ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset_value)
-
- # Create directional_light entity and set the properties
- directional_light = hydra.Entity("directional_light")
- directional_light.create_entity(
- entity_position=math.Vector3(0.0, 0.0, 10.0),
- components=["Directional Light"],
- parent_id=default_level.id)
- directional_light_rotation = math.Vector3(degree_radian_factor * -90.0, 0.0, 0.0)
- azlmbr.components.TransformBus(
- azlmbr.bus.Event, "SetLocalRotation", directional_light.id, directional_light_rotation)
-
- # Create sphere entity and set the properties
- sphere_entity = hydra.Entity("sphere")
- sphere_entity.create_entity(
- entity_position=math.Vector3(0.0, 0.0, 1.0),
- components=["Material"],
- parent_id=default_level.id)
-
- # Work around to add the correct Atom Mesh component and asset.
- sphere_entity.components.append(
- editor.EditorComponentAPIBus(
- bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id]
- ).GetValue()[0]
- )
+ ground_plane_material_asset = Asset.find_asset_by_path(ground_plane_material_asset_path, False)
+ ground_plane_material_component.set_component_property_value(
+ AtomComponentProperties.material('Material Asset'), ground_plane_material_asset.id)
+
+ # 5. "Directional Light" entity: Contains Directional Light component.
+ directional_light_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(0.0, 0.0, 10.0), AtomComponentProperties.directional_light(), default_level_entity.id)
+ directional_light_entity.add_component(AtomComponentProperties.directional_light())
+ directional_light_entity_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * -90.0, 0.0, 0.0)
+ directional_light_entity.set_local_rotation(directional_light_entity_rotation)
+
+ # 6. "Sphere" entity: Contains Material & Mesh components.
+ sphere_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(0.0, 0.0, 1.0), "Sphere", default_level_entity.id)
+ sphere_mesh_component = sphere_entity.add_component(AtomComponentProperties.mesh())
sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel")
- sphere_mesh_asset_value = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False)
- sphere_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset_value)
-
- # Add Atom Material component and asset.
+ sphere_mesh_asset = Asset.find_asset_by_path(sphere_mesh_asset_path, False)
+ sphere_mesh_component.set_component_property_value(
+ AtomComponentProperties.mesh('Mesh Asset'), sphere_mesh_asset.id)
+ sphere_material_component = sphere_entity.add_component(AtomComponentProperties.material())
sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial")
- sphere_material_asset_value = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False)
- sphere_entity.get_set_test(0, "Default Material|Material Asset", sphere_material_asset_value)
-
- # Create camera component and set the properties
- camera_entity = hydra.Entity("camera")
- camera_entity.create_entity(
- entity_position=math.Vector3(5.5, -12.0, 9.0),
- components=["Camera"],
- parent_id=default_level.id)
- rotation = math.Vector3(
- degree_radian_factor * -27.0, degree_radian_factor * -12.0, degree_radian_factor * 25.0
- )
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation)
- camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0)
- camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
+ sphere_material_asset = Asset.find_asset_by_path(sphere_material_asset_path, False)
+ sphere_material_component.set_component_property_value(
+ AtomComponentProperties.material('Material Asset'), sphere_material_asset.id)
+
+ # 7. "Camera" entity: Contains Camera component.
+ camera_entity = EditorEntity.create_editor_entity_at(
+ math.Vector3(5.5, -12.0, 9.0), AtomComponentProperties.camera(), default_level_entity.id)
+ camera_component = camera_entity.add_component(AtomComponentProperties.camera())
+ camera_entity_rotation = math.Vector3(
+ DEGREE_RADIAN_FACTOR * -27.0, DEGREE_RADIAN_FACTOR * -12.0, DEGREE_RADIAN_FACTOR * 25.0)
+ camera_entity.set_local_rotation(camera_entity_rotation)
+ camera_fov_value = 60.0
+ camera_component.set_component_property_value(AtomComponentProperties.camera('Field of view'), camera_fov_value)
+ azlmbr.camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py
index c73f75fbc0..e6d6ac7fb1 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py
@@ -18,6 +18,13 @@ LIGHT_TYPES = {
'simple_spot': 7,
}
+
+# Attenuation Radius Mode options for the Light component.
+ATTENUATION_RADIUS_MODE = {
+ 'automatic': 1,
+ 'explicit': 0,
+}
+
# Qualiity Level settings for Diffuse Global Illumination level component
GLOBAL_ILLUMINATION_QUALITY = {
'Low': 0,
@@ -276,13 +283,27 @@ class AtomComponentProperties:
def light(property: str = 'name') -> str:
"""
Light component properties.
+ - 'Attenuation Radius Mode' controls whether the attenuation radius is calculated automatically or explicitly.
+ - 'Color' the RGB value to set for the color of the light.
+ - 'Enable shadow' toggle for enabling shadows for the light.
+ - 'Enable shutters' toggle for enabling shutters for the light.
+ - 'Inner angle' inner angle value for the shutters (in degrees)
+ - 'Intensity' the intensity of the light in the set photometric unit (float with no ceiling).
- 'Light type' from atom_constants.py LIGHT_TYPES
+ - 'Outer angle' outer angle value for the shutters (in degrees)
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'Light',
+ 'Attenuation Radius Mode': 'Controller|Configuration|Attenuation radius|Mode',
+ 'Color': 'Controller|Configuration|Color',
+ 'Enable shadow': 'Controller|Configuration|Shadows|Enable shadow',
+ 'Enable shutters': 'Controller|Configuration|Shutters|Enable shutters',
+ 'Inner angle': 'Controller|Configuration|Shutters|Inner angle',
+ 'Intensity': 'Controller|Configuration|Intensity',
'Light type': 'Controller|Configuration|Light type',
+ 'Outer angle': 'Controller|Configuration|Shutters|Outer angle',
}
return properties[property]
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py
new file mode 100644
index 0000000000..a56c72e46c
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_AreaLightScreenshotTest.py
@@ -0,0 +1,199 @@
+"""
+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
+"""
+
+
+class Tests:
+ area_light_entity_created = (
+ "Area Light entity successfully created",
+ "Area Light entity failed to be created")
+ area_light_entity_deleted = (
+ "Area Light entity was deleted",
+ "Area Light entity was not deleted")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ light_component_added = (
+ "Light component was added",
+ "Light component wasn't added")
+ light_component_attenuation_radius_property_set = (
+ "Light component Attenuation Radius Property was set",
+ "Light component Attenuation Radius Property was not set")
+ light_component_color_property_set = (
+ "Light component Color property was set",
+ "Light component Color property was not set")
+ light_component_intensity_property_set = (
+ "Light component Intensity property was set",
+ "Light component Intensity property was not set")
+ light_component_light_type_property_set = (
+ "Light type property was set",
+ "Light type property was not set")
+
+
+def AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages():
+ """
+ Summary:
+ Light component test using the Capsule, Spot (disk), and Point (sphere) Light type property options.
+ Sets each scene up and then takes a screenshot of each scene for test comparison.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+ - Close error windows and display helpers then update the viewport size.
+ - Runs the create_basic_atom_rendering_scene() function to setup the test scene.
+
+ Expected Behavior:
+ The test scripts sets up the scenes correctly and takes accurate screenshots.
+
+ Test Steps:
+ 1. Create Area Light entity with no components.
+ 2. Add a Light component to the Area Light entity.
+ 3. Set the Light type property to Capsule for the Light component.
+ 4. Set the Light component's Color property to 255, 0, 0.
+ 5. Enter game mode and take a screenshot then exit game mode.
+ 6. Set the Intensity property of the Light component to 0.0.
+ 7. Set the Attenuation Radius Mode property of the Light component to 1 (automatic).
+ 8. Enter game mode and take a screenshot then exit game mode.
+ 9. Set the Intensity property of the Light component to 1000.0
+ 10. Enter game mode and take a screenshot then exit game mode.
+ 11. Set the Light type property to Spot (disk) for the Light component & rotate DEGREE_RADIAN_FACTOR * 90 degrees.
+ 12. Enter game mode and take a screenshot then exit game mode.
+ 13. Set the Light type property to Point (sphere) instead of Spot (disk) for the Light component.
+ 14. Enter game mode and take a screenshot then exit game mode.
+ 15. Delete the Area Light entity.
+ 16. Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+ import azlmbr.paths
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+
+ from Atom.atom_utils.atom_constants import AtomComponentProperties, ATTENUATION_RADIUS_MODE, LIGHT_TYPES
+ from Atom.atom_utils.atom_component_helper import (
+ initial_viewport_setup, create_basic_atom_rendering_scene, enter_exit_game_mode_take_screenshot)
+
+ DEGREE_RADIAN_FACTOR = 0.0174533
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
+
+ # Setup: Close error windows and display helpers then update the viewport size.
+ TestHelper.close_error_windows()
+ TestHelper.close_display_helpers()
+ initial_viewport_setup()
+ general.update_viewport()
+
+ # Setup: Runs the create_basic_atom_rendering_scene() function to setup the test scene.
+ create_basic_atom_rendering_scene()
+
+ # Test steps begin.
+ # 1. Create Area Light entity with no components.
+ area_light_entity_name = "Area Light"
+ area_light_entity = EditorEntity.create_editor_entity_at(
+ azlmbr.math.Vector3(0.0, 0.0, 0.0), area_light_entity_name)
+ Report.critical_result(Tests.area_light_entity_created, area_light_entity.exists())
+
+ # 2. Add a Light component to the Area Light entity.
+ light_component = area_light_entity.add_component(AtomComponentProperties.light())
+ Report.critical_result(
+ Tests.light_component_added, area_light_entity.has_component(AtomComponentProperties.light()))
+
+ # 3. Set the Light type property to Capsule for the Light component.
+ light_component.set_component_property_value(
+ AtomComponentProperties.light('Light type'), LIGHT_TYPES['capsule'])
+ Report.result(
+ Tests.light_component_light_type_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Light type')) == LIGHT_TYPES['capsule'])
+
+ # 4. Set the Light component's Color property to 255, 0, 0.
+ light_component_color_value = azlmbr.math.Color(255.0, 0.0, 0.0, 0.0)
+ light_component.set_component_property_value(
+ AtomComponentProperties.light('Color'), light_component_color_value)
+ Report.result(
+ Tests.light_component_color_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Color')) == light_component_color_value)
+
+ # 5. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("AreaLight_1.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 6. Set the Intensity property of the Light component to 0.0.
+ light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 0.0)
+ Report.result(
+ Tests.light_component_intensity_property_set,
+ light_component.get_component_property_value(AtomComponentProperties.light('Intensity')) == 0.0)
+
+ # 7. Set the Attenuation Radius Mode property of the Light component to 1 (automatic).
+ light_component.set_component_property_value(
+ AtomComponentProperties.light('Attenuation Radius Mode'), ATTENUATION_RADIUS_MODE['automatic'])
+ Report.result(
+ Tests.light_component_attenuation_radius_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Attenuation Radius Mode')) == ATTENUATION_RADIUS_MODE['automatic'])
+
+ # 8. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("AreaLight_2.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 9. Set the Intensity property of the Light component to 1000.0
+ light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 1000.0)
+ Report.result(
+ Tests.light_component_intensity_property_set,
+ light_component.get_component_property_value(AtomComponentProperties.light('Intensity')) == 1000.0)
+
+ # 10. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("AreaLight_3.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 11. Set the Light type property to Spot (disk) for the Light component &
+ # rotate DEGREE_RADIAN_FACTOR * 90 degrees.
+ light_component.set_component_property_value(
+ AtomComponentProperties.light('Light type'), LIGHT_TYPES['spot_disk'])
+ area_light_rotation = azlmbr.math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0)
+ azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light_entity.id, area_light_rotation)
+ Report.result(
+ Tests.light_component_light_type_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Light type')) == LIGHT_TYPES['spot_disk'])
+
+ # 12. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("AreaLight_4.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 13. Set the Light type property to Point (sphere) instead of Spot (disk) for the Light component.
+ light_component.set_component_property_value(
+ AtomComponentProperties.light('Light type'), LIGHT_TYPES['sphere'])
+ Report.result(
+ Tests.light_component_light_type_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Light type')) == LIGHT_TYPES['sphere'])
+
+ # 14. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("AreaLight_5.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 15. Delete the Area Light entity.
+ area_light_entity.delete()
+ Report.result(Tests.area_light_entity_deleted, not area_light_entity.exists())
+
+ # 16. Look for errors.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(AtomGPU_LightComponent_AreaLightScreenshotsMatchGoldenImages)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py
index 127b3e5b5f..b15e5b2131 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py
@@ -80,6 +80,7 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
Test setup:
- Wait for Editor idle loop.
- Open the "Base" level.
+ - Deletes all existing entities before creating the scene.
Expected Behavior:
The scene can be setup for a basic level.
@@ -115,7 +116,6 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
"""
import os
- from math import isclose
import azlmbr.legacy.general as general
import azlmbr.math as math
@@ -126,21 +126,11 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
from editor_python_test_tools.utils import Report, Tracer, TestHelper
from Atom.atom_utils.atom_constants import AtomComponentProperties
+ from Atom.atom_utils.atom_component_helper import initial_viewport_setup
from Atom.atom_utils.screenshot_utils import ScreenshotHelper
- SCREENSHOT_NAME = "AtomBasicLevelSetup"
- SCREEN_WIDTH = 1280
- SCREEN_HEIGHT = 720
DEGREE_RADIAN_FACTOR = 0.0174533
-
- def initial_viewport_setup(screen_width, screen_height):
- general.set_viewport_size(screen_width, screen_height)
- general.update_viewport()
- TestHelper.wait_for_condition(
- function=lambda: isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1)
- and isclose(a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1),
- timeout_in_seconds=4.0
- )
+ SCREENSHOT_NAME = "AtomBasicLevelSetup"
with Tracer() as error_tracer:
# Test setup begins.
@@ -148,11 +138,16 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
TestHelper.init_idle()
TestHelper.open_level("", "Base")
+ # Setup: Deletes all existing entities before creating the scene.
+ search_filter = azlmbr.entity.SearchFilter()
+ all_entities = azlmbr.entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
+ azlmbr.editor.ToolsApplicationRequestBus(azlmbr.bus.Broadcast, "DeleteEntities", all_entities)
+
# Test steps begin.
# 1. Close error windows and display helpers then update the viewport size.
TestHelper.close_error_windows()
TestHelper.close_display_helpers()
- initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT)
+ initial_viewport_setup()
general.update_viewport()
# 2. Create Default Level Entity.
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py
new file mode 100644
index 0000000000..fbfb6e3468
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_SpotLightScreenshotTest.py
@@ -0,0 +1,248 @@
+"""
+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
+"""
+
+
+class Tests:
+ directional_light_component_disabled = (
+ "Disabled Directional Light component",
+ "Couldn't disable Directional Light component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ global_skylight_component_disabled = (
+ "Disabled Global Skylight (IBL) component",
+ "Couldn't disable Global Skylight (IBL) component")
+ hdri_skybox_component_disabled = (
+ "Disabled HDRi Skybox component",
+ "Couldn't disable HDRi Skybox component")
+ light_component_added = (
+ "Light component added",
+ "Couldn't add Light component")
+ light_component_color_property_set = (
+ "Color property was set",
+ "Color property was not set")
+ light_component_enable_shadow_property_set = (
+ "Enable shadow property was set",
+ "Enable shadow property was not set")
+ light_component_enable_shutters_property_set = (
+ "Enable shutters property was set",
+ "Enable shutters property was not set")
+ light_component_inner_angle_property_set = (
+ "Inner angle property was set",
+ "Inner angle property was not set")
+ light_component_intensity_property_set = (
+ "Intensity property was set",
+ "Intensity property was not set")
+ light_component_light_type_property_set = (
+ "Light type property was set",
+ "Light type property was not set")
+ light_component_outer_angle_property_set = (
+ "Outer angle property was set",
+ "Outer angle property was not set")
+ material_component_material_asset_property_set = (
+ "Material Asset property was set",
+ "Material Asset property was not set")
+ spot_light_entity_created = (
+ "Spot Light entity created",
+ "Couldn't create Spot Light entity")
+
+
+def AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages():
+ """
+ Summary:
+ Light component test using the Spot (disk) Light type property option and modifying the shadows and colors.
+ Sets each scene up and then takes a screenshot of each scene for test comparison.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+ - Close error windows and display helpers then update the viewport size.
+ - Runs the create_basic_atom_rendering_scene() function to setup the test scene.
+
+ Expected Behavior:
+ The test scripts sets up the scenes correctly and takes accurate screenshots.
+
+ Test Steps:
+ 1. Find the Directional Light entity then disable its Directional Light component.
+ 2. Disable Global Skylight (IBL) component on the Global Skylight (IBL) entity.
+ 3. Disable HDRi Skybox component on the Global Skylight (IBL) entity.
+ 4. Create a Spot Light entity and rotate it.
+ 5. Attach a Light component to the Spot Light entity.
+ 6. Set the Light component Light Type to Spot (disk).
+ 7. Enter game mode and take a screenshot then exit game mode.
+ 8. Change the default material asset for the Ground Plane entity.
+ 9. Enter game mode and take a screenshot then exit game mode.
+ 10. Increase the Intensity value of the Light component.
+ 11. Enter game mode and take a screenshot then exit game mode.
+ 12. Change the Light component Color property value.
+ 13. Enter game mode and take a screenshot then exit game mode.
+ 14. Change the Light component Enable shutters, Inner angle, and Outer angle property values.
+ 15. Enter game mode and take a screenshot then exit game mode.
+ 16. Change the Light component Enable shadow and Shadowmap size property values then move Spot Light entity.
+ 17. Enter game mode and take a screenshot then exit game mode.
+ 18. Look for errors.
+
+ :return: None
+ """
+ import os
+
+ import azlmbr.legacy.general as general
+ import azlmbr.paths
+
+ from editor_python_test_tools.asset_utils import Asset
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+
+ from Atom.atom_utils.atom_constants import AtomComponentProperties, LIGHT_TYPES
+ from Atom.atom_utils.atom_component_helper import (
+ initial_viewport_setup, create_basic_atom_rendering_scene, enter_exit_game_mode_take_screenshot)
+
+ DEGREE_RADIAN_FACTOR = 0.0174533
+
+ with Tracer() as error_tracer:
+ # Test setup begins.
+ # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
+
+ # Setup: Close error windows and display helpers then update the viewport size.
+ TestHelper.close_error_windows()
+ TestHelper.close_display_helpers()
+ initial_viewport_setup()
+ general.update_viewport()
+
+ # Setup: Runs the create_basic_atom_rendering_scene() function to setup the test scene.
+ create_basic_atom_rendering_scene()
+
+ # Test steps begin.
+ # 1. Find the Directional Light entity then disable its Directional Light component.
+ directional_light_entity = EditorEntity.find_editor_entity(AtomComponentProperties.directional_light())
+ directional_light_component = directional_light_entity.get_components_of_type(
+ [AtomComponentProperties.directional_light()])[0]
+ directional_light_component.disable_component()
+ Report.critical_result(Tests.directional_light_component_disabled, not directional_light_component.is_enabled())
+
+ # 2. Disable Global Skylight (IBL) component on the Global Skylight (IBL) entity.
+ global_skylight_entity = EditorEntity.find_editor_entity(AtomComponentProperties.global_skylight())
+ global_skylight_component = global_skylight_entity.get_components_of_type(
+ [AtomComponentProperties.global_skylight()])[0]
+ global_skylight_component.disable_component()
+ Report.critical_result(Tests.global_skylight_component_disabled, not global_skylight_component.is_enabled())
+
+ # 3. Disable HDRi Skybox component on the Global Skylight (IBL) entity.
+ hdri_skybox_component = global_skylight_entity.get_components_of_type(
+ [AtomComponentProperties.hdri_skybox()])[0]
+ hdri_skybox_component.disable_component()
+ Report.critical_result(Tests.hdri_skybox_component_disabled, not hdri_skybox_component.is_enabled())
+
+ # 4. Create a Spot Light entity and rotate it.
+ spot_light_name = "Spot Light"
+ spot_light_entity = EditorEntity.create_editor_entity_at(
+ azlmbr.math.Vector3(0.7, -2.0, 1.0), spot_light_name)
+ rotation = azlmbr.math.Vector3(DEGREE_RADIAN_FACTOR * 300.0, 0.0, 0.0)
+ spot_light_entity.set_local_rotation(rotation)
+ Report.critical_result(Tests.spot_light_entity_created, spot_light_entity.exists())
+
+ # 5. Attach a Light component to the Spot Light entity.
+ light_component = spot_light_entity.add_component(AtomComponentProperties.light())
+ Report.critical_result(Tests.light_component_added, light_component.is_enabled())
+
+ # 6. Set the Light component Light Type to Spot (disk).
+ light_component.set_component_property_value(
+ AtomComponentProperties.light('Light type'), LIGHT_TYPES['spot_disk'])
+ Report.result(
+ Tests.light_component_light_type_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Light type')) == LIGHT_TYPES['spot_disk'])
+
+ # 7. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("SpotLight_1.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 8. Change the default material asset for the Ground Plane entity.
+ ground_plane_name = "Ground Plane"
+ ground_plane_entity = EditorEntity.find_editor_entity(ground_plane_name)
+ ground_plane_material_component_name = AtomComponentProperties.material()
+ ground_plane_material_component = ground_plane_entity.get_components_of_type(
+ [ground_plane_material_component_name])[0]
+ ground_plane_material_asset_path = os.path.join(
+ "Materials", "Presets", "Macbeth", "22_neutral_5-0_0-70d.azmaterial")
+ ground_plane_material_asset = Asset.find_asset_by_path(ground_plane_material_asset_path, False)
+ ground_plane_material_component.set_component_property_value(
+ AtomComponentProperties.material('Material Asset'), ground_plane_material_asset.id)
+ Report.result(
+ Tests.material_component_material_asset_property_set,
+ ground_plane_material_component.get_component_property_value(
+ AtomComponentProperties.material('Material Asset')) == ground_plane_material_asset.id)
+
+ # 9. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("SpotLight_2.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 10. Increase the Intensity value of the Light component.
+ light_component.set_component_property_value(AtomComponentProperties.light('Intensity'), 800.0)
+ Report.result(
+ Tests.light_component_intensity_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Intensity')) == 800.0)
+
+ # 11. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("SpotLight_3.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 12. Change the Light component Color property value.
+ color_value = azlmbr.math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0)
+ light_component.set_component_property_value(AtomComponentProperties.light('Color'), color_value)
+ Report.result(
+ Tests.light_component_color_property_set,
+ light_component.get_component_property_value(AtomComponentProperties.light('Color')) == color_value)
+
+ # 13. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("SpotLight_4.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 14. Change the Light component Enable shutters, Inner angle, and Outer angle property values.
+ enable_shutters = True
+ inner_angle = 60.0
+ outer_angle = 75.0
+ light_component.set_component_property_value(AtomComponentProperties.light('Enable shutters'), enable_shutters)
+ light_component.set_component_property_value(AtomComponentProperties.light('Inner angle'), inner_angle)
+ light_component.set_component_property_value(AtomComponentProperties.light('Outer angle'), outer_angle)
+ Report.result(
+ Tests.light_component_enable_shutters_property_set,
+ light_component.get_component_property_value(
+ AtomComponentProperties.light('Enable shutters')) == enable_shutters)
+ Report.result(
+ Tests.light_component_inner_angle_property_set,
+ light_component.get_component_property_value(AtomComponentProperties.light('Inner angle')) == inner_angle)
+ Report.result(
+ Tests.light_component_outer_angle_property_set,
+ light_component.get_component_property_value(AtomComponentProperties.light('Outer angle')) == outer_angle)
+
+ # 15. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("SpotLight_5.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 16. Change the Light component Enable shadow and slightly move Spot Light entity.
+ light_component.set_component_property_value(AtomComponentProperties.light('Enable shadow'), True)
+ Report.result(
+ Tests.light_component_enable_shadow_property_set,
+ light_component.get_component_property_value(AtomComponentProperties.light('Enable shadow')) is True)
+ spot_light_entity.set_world_rotation(azlmbr.math.Vector3(0.7, -2.0, 1.9))
+
+ # 17. Enter game mode and take a screenshot then exit game mode.
+ enter_exit_game_mode_take_screenshot("SpotLight_6.ppm", Tests.enter_game_mode, Tests.exit_game_mode)
+
+ # 18. Look for errors.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(AtomGPU_LightComponent_SpotLightScreenshotsMatchGoldenImages)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
deleted file mode 100644
index 1641b529ae..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
+++ /dev/null
@@ -1,200 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project.
-For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-"""
-
-import os
-
-import editor_python_test_tools.hydra_editor_utils as hydra
-from editor_python_test_tools.editor_test_helper import EditorTestHelper
-from Atom.atom_utils.screenshot_utils import ScreenshotHelper
-
-SCREEN_WIDTH = 1280
-SCREEN_HEIGHT = 720
-DEGREE_RADIAN_FACTOR = 0.0174533
-
-helper = EditorTestHelper(log_prefix="Test_Atom_BasicLevelSetup")
-
-
-def run():
- """
- 1. View -> Layouts -> Restore Default Layout, sets the viewport to ratio 16:9 @ 1280 x 720
- 2. Runs console command r_DisplayInfo = 0
- 3. Deletes all entities currently present in the level.
- 4. Creates a "default_level" entity to hold all other entities, setting the translate values to x:0, y:0, z:0
- 5. Adds a Grid component to the "default_level" & updates its Grid Spacing to 1.0m
- 6. Adds a "global_skylight" entity to "default_level", attaching an HDRi Skybox w/ a Cubemap Texture.
- 7. Adds a Global Skylight (IBL) component w/ diffuse image and specular image to "global_skylight" entity.
- 8. Adds a "ground_plane" entity to "default_level", attaching a Mesh component & Material component.
- 9. Adds a "directional_light" entity to "default_level" & adds a Directional Light component.
- 10. Adds a "sphere" entity to "default_level" & adds a Mesh component with a Material component to it.
- 11. Adds a "camera" entity to "default_level" & adds a Camera component with 80 degree FOV and Transform values:
- Translate - x:5.5m, y:-12.0m, z:9.0m
- Rotate - x:-27.0, y:-12.0, z:25.0
- 12. Finally enters game mode, takes a screenshot, & exits game mode.
- :return: None
- """
- import azlmbr.asset as asset
- import azlmbr.bus as bus
- import azlmbr.camera as camera
- import azlmbr.entity as entity
- import azlmbr.legacy.general as general
- import azlmbr.math as math
- import azlmbr.paths
- import azlmbr.editor as editor
-
- def initial_viewport_setup(screen_width, screen_height):
- general.set_viewport_size(screen_width, screen_height)
- general.update_viewport()
- helper.wait_for_condition(
- function=lambda: helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1)
- and helper.isclose(a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1),
- timeout_in_seconds=4.0
- )
- result = helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) and helper.isclose(
- a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1)
- general.log(general.get_viewport_size().x)
- general.log(general.get_viewport_size().y)
- general.log(general.get_viewport_size().z)
- general.log(f"Viewport is set to the expected size: {result}")
- general.run_console("r_DisplayInfo = 0")
-
- def after_level_load():
- """Function to call after creating/opening a level to ensure it loads."""
- # Give everything a second to initialize.
- general.idle_enable(True)
- general.idle_wait(1.0)
- general.update_viewport()
- general.idle_wait(0.5) # half a second is more than enough for updating the viewport.
-
- # Close out problematic windows, FPS meters, and anti-aliasing.
- if general.is_helpers_shown(): # Turn off the helper gizmos if visible
- general.toggle_helpers()
- general.idle_wait(1.0)
- if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus.
- general.close_pane("Error Report")
- if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus.
- general.close_pane("Error Log")
- general.idle_wait(1.0)
- general.run_console("r_displayInfo=0")
- general.idle_wait(1.0)
-
- # Wait for Editor idle loop before executing Python hydra scripts.
- general.idle_enable(True)
-
- # Basic setup for opened level.
- helper.open_level(level_name="Base")
- after_level_load()
- initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT)
-
- # Create default_level entity
- search_filter = azlmbr.entity.SearchFilter()
- all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
- editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
-
- default_level = hydra.Entity("default_level")
- position = math.Vector3(0.0, 0.0, 0.0)
- default_level.create_entity(position, ["Grid"])
- default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0)
-
- # Create global_skylight entity and set the properties
- global_skylight = hydra.Entity("global_skylight")
- global_skylight.create_entity(
- entity_position=math.Vector3(0.0, 0.0, 0.0),
- components=["HDRi Skybox", "Global Skylight (IBL)"],
- parent_id=default_level.id
- )
- global_skylight_image_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
- global_skylight_image_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", global_skylight_image_asset_path, math.Uuid(), False)
- global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_image_asset)
- hydra.get_set_test(global_skylight, 1, "Controller|Configuration|Diffuse Image", global_skylight_image_asset)
- hydra.get_set_test(global_skylight, 1, "Controller|Configuration|Specular Image", global_skylight_image_asset)
-
- # Create ground_plane entity and set the properties
- ground_plane = hydra.Entity("ground_plane")
- ground_plane.create_entity(
- entity_position=math.Vector3(0.0, 0.0, 0.0),
- components=["Material"],
- parent_id=default_level.id
- )
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0)
-
- # Work around to add the correct Atom Mesh component and asset.
- mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId
- ground_plane.components.append(
- editor.EditorComponentAPIBus(
- bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id]
- ).GetValue()[0]
- )
- ground_plane_mesh_asset_path = os.path.join("TestData", "Objects", "plane.azmodel")
- ground_plane_mesh_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False)
- hydra.get_set_test(ground_plane, 1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset)
-
- # Add Atom Material component and asset.
- ground_plane_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_chrome.azmaterial")
- ground_plane_material_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False)
- ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset)
-
- # Create directional_light entity and set the properties
- directional_light = hydra.Entity("directional_light")
- directional_light.create_entity(
- entity_position=math.Vector3(0.0, 0.0, 10.0),
- components=["Directional Light"],
- parent_id=default_level.id
- )
- rotation = math.Vector3(DEGREE_RADIAN_FACTOR * -90.0, 0.0, 0.0)
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", directional_light.id, rotation)
-
- # Create sphere entity and set the properties
- sphere = hydra.Entity("sphere")
- sphere.create_entity(
- entity_position=math.Vector3(0.0, 0.0, 1.0),
- components=["Material"],
- parent_id=default_level.id
- )
-
- # Work around to add the correct Atom Mesh component and asset.
- sphere.components.append(
- editor.EditorComponentAPIBus(
- bus.Broadcast, "AddComponentsOfType", sphere.id, [mesh_type_id]
- ).GetValue()[0]
- )
- sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel")
- sphere_mesh_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False)
- hydra.get_set_test(sphere, 1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset)
-
- # Add Atom Material component and asset.
- sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial")
- sphere_material_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False)
- sphere.get_set_test(0, "Default Material|Material Asset", sphere_material_asset)
-
- # Create camera component and set the properties
- camera_entity = hydra.Entity("camera")
- position = math.Vector3(5.5, -12.0, 9.0)
- camera_entity.create_entity(components=["Camera"], entity_position=position, parent_id=default_level.id)
- rotation = math.Vector3(
- DEGREE_RADIAN_FACTOR * -27.0, DEGREE_RADIAN_FACTOR * -12.0, DEGREE_RADIAN_FACTOR * 25.0
- )
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation)
- camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0)
- camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
-
- # Enter game mode, take screenshot, & exit game mode.
- general.idle_wait(0.5)
- general.enter_game_mode()
- general.idle_wait(1.0)
- helper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=2.0)
- ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{'AtomBasicLevelSetup'}.ppm")
- general.exit_game_mode()
- helper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=2.0)
-
-
-if __name__ == "__main__":
- run()
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py
deleted file mode 100644
index f69ceb2120..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_LightComponent.py
+++ /dev/null
@@ -1,261 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project.
-For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-"""
-import os
-import sys
-
-import azlmbr.asset as asset
-import azlmbr.bus as bus
-import azlmbr.editor as editor
-import azlmbr.math as math
-import azlmbr.paths
-import azlmbr.legacy.general as general
-
-sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
-
-import editor_python_test_tools.hydra_editor_utils as hydra
-from Atom.atom_utils import atom_component_helper, atom_constants, screenshot_utils
-from editor_python_test_tools.editor_test_helper import EditorTestHelper
-
-helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
-
-LEVEL_NAME = "Base"
-LIGHT_COMPONENT = "Light"
-LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
-DEGREE_RADIAN_FACTOR = 0.0174533
-
-
-def run():
- """
- Sets up the tests by making sure the required level is created & setup correctly.
- It then executes 2 test cases - see each associated test function's docstring for more info.
-
- Finally prints the string "Light component tests completed" after completion
-
- Tests will fail immediately if any of these log lines are found:
- 1. Trace::Assert
- 2. Trace::Error
- 3. Traceback (most recent call last):
-
- :return: None
- """
- atom_component_helper.create_basic_atom_level(level_name=LEVEL_NAME)
-
- # Run tests.
- area_light_test()
- spot_light_test()
- general.log("Light component tests completed.")
-
-
-def area_light_test():
- """
- Basic test for the "Light" component attached to an "area_light" entity.
-
- Test Case - Light Component: Capsule, Spot (disk), and Point (sphere):
- 1. Creates "area_light" entity w/ a Light component that has a Capsule Light type w/ the color set to 255, 0, 0
- 2. Enters game mode to take a screenshot for comparison, then exits game mode.
- 3. Sets the Light component Intensity Mode to Lumens (default).
- 4. Ensures the Light component Mode is Automatic (default).
- 5. Sets the Intensity value of the Light component to 0.0
- 6. Enters game mode again, takes another screenshot for comparison, then exits game mode.
- 7. Updates the Intensity value of the Light component to 1000.0
- 8. Enters game mode again, takes another screenshot for comparison, then exits game mode.
- 9. Swaps the Capsule light type option to Spot (disk) light type on the Light component
- 10. Updates "area_light" entity Transform rotate value to x: 90.0, y:0.0, z:0.0
- 11. Enters game mode again, takes another screenshot for comparison, then exits game mode.
- 12. Swaps the Spot (disk) light type for the Point (sphere) light type in the Light component.
- 13. Enters game mode again, takes another screenshot for comparison, then exits game mode.
- 14. Deletes the Light component from the "area_light" entity and verifies its successful.
- """
- # Create an "area_light" entity with "Light" component using Light type of "Capsule"
- area_light_entity_name = "area_light"
- area_light = hydra.Entity(area_light_entity_name)
- area_light.create_entity(math.Vector3(-1.0, -2.0, 3.0), [LIGHT_COMPONENT])
- general.log(
- f"{area_light_entity_name}_test: Component added to the entity: "
- f"{hydra.has_components(area_light.id, [LIGHT_COMPONENT])}")
- light_component_id_pair = hydra.attach_component_to_entity(area_light.id, LIGHT_COMPONENT)
-
- # Select the "Capsule" light type option.
- azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast,
- 'SetComponentProperty',
- light_component_id_pair,
- LIGHT_TYPE_PROPERTY,
- atom_constants.LIGHT_TYPES['capsule']
- )
-
- # Update color and take screenshot in game mode
- color = math.Color(255.0, 0.0, 0.0, 0.0)
- area_light.get_set_test(0, "Controller|Configuration|Color", color)
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("AreaLight_1", area_light_entity_name)
-
- # Update intensity value to 0.0 and take screenshot in game mode
- area_light.get_set_test(0, "Controller|Configuration|Attenuation Radius|Mode", 1)
- area_light.get_set_test(0, "Controller|Configuration|Intensity", 0.0)
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("AreaLight_2", area_light_entity_name)
-
- # Update intensity value to 1000.0 and take screenshot in game mode
- area_light.get_set_test(0, "Controller|Configuration|Intensity", 1000.0)
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("AreaLight_3", area_light_entity_name)
-
- # Swap the "Capsule" light type option to "Spot (disk)" light type
- azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast,
- 'SetComponentProperty',
- light_component_id_pair,
- LIGHT_TYPE_PROPERTY,
- atom_constants.LIGHT_TYPES['spot_disk']
- )
- area_light_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0)
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light.id, area_light_rotation)
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("AreaLight_4", area_light_entity_name)
-
- # Swap the "Spot (disk)" light type to the "Point (sphere)" light type and take screenshot.
- azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast,
- 'SetComponentProperty',
- light_component_id_pair,
- LIGHT_TYPE_PROPERTY,
- atom_constants.LIGHT_TYPES['sphere']
- )
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("AreaLight_5", area_light_entity_name)
-
- editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", area_light.id)
-
-
-def spot_light_test():
- """
- Basic test for the Light component attached to a "spot_light" entity.
-
- Test Case - Light Component: Spot (disk) with shadows & colors:
- 1. Creates "spot_light" entity w/ a Light component attached to it.
- 2. Selects the "directional_light" entity already present in the level and disables it.
- 3. Selects the "global_skylight" entity already present in the level and disables the HDRi Skybox component,
- as well as the Global Skylight (IBL) component.
- 4. Enters game mode to take a screenshot for comparison, then exits game mode.
- 5. Selects the "ground_plane" entity and changes updates the material to a new material.
- 6. Enters game mode to take a screenshot for comparison, then exits game mode.
- 7. Selects the "spot_light" entity and increases the Light component Intensity to 800 lm
- 8. Enters game mode to take a screenshot for comparison, then exits game mode.
- 9. Selects the "spot_light" entity and sets the Light component Color to 47, 75, 37
- 10. Enters game mode to take a screenshot for comparison, then exits game mode.
- 11. Selects the "spot_light" entity and modifies the Shutter controls to the following values:
- - Enable shutters: True
- - Inner Angle: 60.0
- - Outer Angle: 75.0
- 12. Enters game mode to take a screenshot for comparison, then exits game mode.
- 13. Selects the "spot_light" entity and modifies the Shadow controls to the following values:
- - Enable Shadow: True
- - ShadowmapSize: 256
- 14. Modifies the world translate position of the "spot_light" entity to 0.7, -2.0, 1.9 (for casting shadows better)
- 15. Enters game mode to take a screenshot for comparison, then exits game mode.
- """
- # Disable "Directional Light" component for the "directional_light" entity
- # "directional_light" entity is created by the create_basic_atom_level() function by default.
- directional_light_entity_id = hydra.find_entity_by_name("directional_light")
- directional_light = hydra.Entity(name='directional_light', id=directional_light_entity_id)
- directional_light_component_type = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Directional Light"], 0)[0]
- directional_light_component = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'GetComponentOfType', directional_light.id, directional_light_component_type
- ).GetValue()
- editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [directional_light_component])
- general.idle_wait(0.5)
-
- # Disable "Global Skylight (IBL)" and "HDRi Skybox" components for the "global_skylight" entity
- global_skylight_entity_id = hydra.find_entity_by_name("global_skylight")
- global_skylight = hydra.Entity(name='global_skylight', id=global_skylight_entity_id)
- global_skylight_component_type = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Global Skylight (IBL)"], 0)[0]
- global_skylight_component = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, global_skylight_component_type
- ).GetValue()
- editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [global_skylight_component])
- hdri_skybox_component_type = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["HDRi Skybox"], 0)[0]
- hdri_skybox_component = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, hdri_skybox_component_type
- ).GetValue()
- editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [hdri_skybox_component])
- general.idle_wait(0.5)
-
- # Create a "spot_light" entity with "Light" component using Light Type of "Spot (disk)"
- spot_light_entity_name = "spot_light"
- spot_light = hydra.Entity(spot_light_entity_name)
- spot_light.create_entity(math.Vector3(0.7, -2.0, 1.0), [LIGHT_COMPONENT])
- general.log(
- f"{spot_light_entity_name}_test: Component added to the entity: "
- f"{hydra.has_components(spot_light.id, [LIGHT_COMPONENT])}")
- rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 300.0, 0.0, 0.0)
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", spot_light.id, rotation)
- light_component_type = hydra.attach_component_to_entity(spot_light.id, LIGHT_COMPONENT)
- editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast,
- 'SetComponentProperty',
- light_component_type,
- LIGHT_TYPE_PROPERTY,
- atom_constants.LIGHT_TYPES['spot_disk']
- )
-
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("SpotLight_1", spot_light_entity_name)
-
- # Change default material of ground plane entity and take screenshot
- ground_plane_entity_id = hydra.find_entity_by_name("ground_plane")
- ground_plane = hydra.Entity(name='ground_plane', id=ground_plane_entity_id)
- ground_plane_asset_path = os.path.join("Materials", "Presets", "MacBeth", "22_neutral_5-0_0-70d.azmaterial")
- ground_plane_asset_value = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", ground_plane_asset_path, math.Uuid(), False)
- material_property_path = "Default Material|Material Asset"
- material_component_type = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Material"], 0)[0]
- material_component = azlmbr.editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast, 'GetComponentOfType', ground_plane.id, material_component_type).GetValue()
- editor.EditorComponentAPIBus(
- azlmbr.bus.Broadcast,
- 'SetComponentProperty',
- material_component,
- material_property_path,
- ground_plane_asset_value
- )
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("SpotLight_2", spot_light_entity_name)
-
- # Increase intensity value of the Spot light and take screenshot in game mode
- spot_light.get_set_test(0, "Controller|Configuration|Intensity", 800.0)
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("SpotLight_3", spot_light_entity_name)
-
- # Update the Spot light color and take screenshot in game mode
- color_value = math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0)
- spot_light.get_set_test(0, "Controller|Configuration|Color", color_value)
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("SpotLight_4", spot_light_entity_name)
-
- # Update the Shutter controls of the Light component and take screenshot
- spot_light.get_set_test(0, "Controller|Configuration|Shutters|Enable shutters", True)
- spot_light.get_set_test(0, "Controller|Configuration|Shutters|Inner angle", 60.0)
- spot_light.get_set_test(0, "Controller|Configuration|Shutters|Outer angle", 75.0)
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("SpotLight_5", spot_light_entity_name)
-
- # Update the Shadow controls, move the spot_light entity world translate position and take screenshot
- spot_light.get_set_test(0, "Controller|Configuration|Shadows|Enable shadow", True)
- spot_light.get_set_test(0, "Controller|Configuration|Shadows|Shadowmap size", 256.0)
- azlmbr.components.TransformBus(
- azlmbr.bus.Event, "SetWorldTranslation", spot_light.id, math.Vector3(0.7, -2.0, 1.9))
- general.idle_wait(1.0)
- screenshot_utils.take_screenshot_game_mode("SpotLight_6", spot_light_entity_name)
-
-
-if __name__ == "__main__":
- run()
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py
index 2d1c34b9c4..72530325e0 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py
@@ -25,7 +25,7 @@ class EditorComponent:
"""
EditorComponent class used to set and get the component property value using path
EditorComponent object is returned from either of
- EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_component_objects()
+ EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_components_of_type()
which also assigns self.id and self.type_id to the EditorComponent object.
"""
@@ -94,6 +94,13 @@ class EditorComponent:
"""
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", self.id)
+ def disable_component(self):
+ """
+ Used to disable the component using its id value.
+ :return: None
+ """
+ editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id])
+
@staticmethod
def get_type_ids(component_names: list) -> list:
"""
@@ -136,10 +143,11 @@ class EditorEntity:
# Creation functions
@classmethod
- def find_editor_entity(cls, entity_name: str, must_be_unique : bool = False) -> EditorEntity:
+ def find_editor_entity(cls, entity_name: str, must_be_unique: bool = False) -> EditorEntity:
"""
Given Entity name, outputs entity object
:param entity_name: Name of entity to find
+ :param must_be_unique: bool that asserts the entity_name specified is unique when set to True
:return: EditorEntity class object
"""
entities = cls.find_editor_entities([entity_name])
@@ -147,14 +155,14 @@ class EditorEntity:
if must_be_unique:
assert len(entities) == 1, f"Failure: Multiple entities with name: '{entity_name}' when expected only one"
- entity = cls(entities[0])
+ entity = entities[0]
return entity
@classmethod
- def find_editor_entities(cls, entity_names: List[str]) -> EditorEntity:
+ def find_editor_entities(cls, entity_names: List[str]) -> List[EditorEntity]:
"""
Given Entities names, returns a list of EditorEntity
- :param entity_name: Name of entity to find
+ :param entity_names: List of entity names to find
:return: List[EditorEntity] class object
"""
searchFilter = azlmbr.entity.SearchFilter()
@@ -438,7 +446,7 @@ class EditorEntity:
def set_local_rotation(self, new_rotation) -> None:
"""
Sets the set the local rotation(relative to the parent) of the current entity.
- :param vector3_rotation: The math.Vector3 value to use for rotation on the entity (uses radians).
+ :param new_rotation: The math.Vector3 value to use for rotation on the entity (uses radians).
:return: None
"""
new_rotation = convert_to_azvector3(new_rotation)
@@ -454,7 +462,7 @@ class EditorEntity:
def set_local_translation(self, new_translation) -> None:
"""
Sets the local translation(relative to the parent) of the current entity.
- :param vector3_translation: The math.Vector3 value to use for translation on the entity.
+ :param new_translation: The math.Vector3 value to use for translation on the entity.
:return: None
"""
new_translation = convert_to_azvector3(new_translation)
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py
index 19aa6e9d3c..5e3828ad02 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py
@@ -46,6 +46,18 @@ def get_component_type_id(component_name):
return component_type_id
+def get_level_component_type_id(component_name):
+ """
+ Gets the component_type_id from a given component name
+ :param component_name: String of component name to search for
+ :return component type ID
+ """
+ type_ids_list = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [component_name],
+ entity.EntityType().Level)
+ component_type_id = type_ids_list[0]
+ return component_type_id
+
+
def add_level_component(component_name):
"""
Adds the specified component to the Level Inspector
@@ -145,6 +157,20 @@ def get_component_property_value(component, component_propertyPath):
print(f'FAILURE: Could not get value from {component_propertyPath}')
return None
+def set_component_property_value(component, component_propertyPath, value):
+ """
+ Given a component name and component property path, set component property value
+ :param component: Component object to act on.
+ :param componentPropertyPath: String of component property. (e.g. 'Settings|Visible')
+ :param value: new value for the variable being changed in the component
+ """
+ componentPropertyObj = editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component,
+ component_propertyPath, value)
+ if componentPropertyObj.IsSuccess():
+ print(f'{component_propertyPath} set to {value}')
+ else:
+ print(f'FAILURE: Could not set value in {component_propertyPath}')
+
def get_property_tree(component):
"""
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
index c719c8dc34..7b526033dd 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
@@ -88,8 +88,7 @@ class TestHelper:
general.idle_wait_frames(200)
@staticmethod
- def enter_game_mode(msgtuple_success_fail : Tuple[str, str]):
- # type: (tuple) -> None
+ def enter_game_mode(msgtuple_success_fail: Tuple[str, str]) -> None:
"""
:param msgtuple_success_fail: The tuple with the expected/unexpected messages for entering game mode.
@@ -102,8 +101,7 @@ class TestHelper:
Report.critical_result(msgtuple_success_fail, general.is_in_game_mode())
@staticmethod
- def multiplayer_enter_game_mode(msgtuple_success_fail : Tuple[str, str], sv_default_player_spawn_asset : str):
- # type: (tuple) -> None
+ def multiplayer_enter_game_mode(msgtuple_success_fail: Tuple[str, str], sv_default_player_spawn_asset: str) -> None:
"""
:param msgtuple_success_fail: The tuple with the expected/unexpected messages for entering game mode.
:param sv_default_player_spawn_asset: The path to the network player prefab that will be automatically spawned upon entering gamemode. The engine default is "prefabs/player.network.spawnable"
diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Main.py
index f35f098b0f..49a776a48c 100644
--- a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Main.py
@@ -25,8 +25,8 @@ class TestAutomation(TestAutomationBase):
def test_NvCloth_AddClothSimulationToMesh(self, request, workspace, editor, launcher_platform):
from .tests import NvCloth_AddClothSimulationToMesh as test_module
- self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer, enable_prefab_system=False)
+ self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer)
def test_NvCloth_AddClothSimulationToActor(self, request, workspace, editor, launcher_platform):
from .tests import NvCloth_AddClothSimulationToActor as test_module
- self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer, enable_prefab_system=False)
+ self._run_test(request, workspace, editor, test_module, use_null_renderer = self.use_null_renderer)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Prefab/CMakeLists.txt
index 48c24d1ebf..629db72dc7 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/CMakeLists.txt
@@ -12,7 +12,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
NAME AutomatedTesting::PrefabTests
TEST_SUITE main
TEST_SERIAL
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
+ PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
RUNTIME_DEPENDENCIES
Legacy::Editor
AZ::AssetProcessor
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main_Optimized.py
new file mode 100644
index 0000000000..bf67b2c661
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main_Optimized.py
@@ -0,0 +1,52 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+import pytest
+
+from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
+
+
+@pytest.mark.SUITE_main
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+class TestAutomationNoAutoTestMode(EditorTestSuite):
+
+ # Enable only -BatchMode for these tests. Some tests cannot run in -autotest_mode due to UI interactions
+ global_extra_cmdline_args = ["-BatchMode"]
+
+ class test_CreatePrefab_UnderAnEntity(EditorSharedTest):
+ from .tests.create_prefab import CreatePrefab_UnderAnEntity as test_module
+
+ class test_CreatePrefab_UnderAnotherPrefab(EditorSharedTest):
+ from .tests.create_prefab import CreatePrefab_UnderAnotherPrefab as test_module
+
+ class test_DeleteEntity_UnderAnotherPrefab(EditorSharedTest):
+ from .tests.delete_entity import DeleteEntity_UnderAnotherPrefab as test_module
+
+ class test_DeleteEntity_UnderLevelPrefab(EditorSharedTest):
+ from .tests.delete_entity import DeleteEntity_UnderLevelPrefab as test_module
+
+ class test_ReparentPrefab_UnderAnotherPrefab(EditorSharedTest):
+ from .tests.reparent_prefab import ReparentPrefab_UnderAnotherPrefab as test_module
+
+ class test_DetachPrefab_UnderAnotherPrefab(EditorSharedTest):
+ from .tests.detach_prefab import DetachPrefab_UnderAnotherPrefab as test_module
+
+ class test_OpenLevel_ContainingTwoEntities(EditorSharedTest):
+ from .tests.open_level import OpenLevel_ContainingTwoEntities as test_module
+
+ class test_CreatePrefab_WithSingleEntity(EditorSharedTest):
+ from .tests.create_prefab import CreatePrefab_WithSingleEntity as test_module
+
+ class test_InstantiatePrefab_ContainingASingleEntity(EditorSharedTest):
+ from .tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
+
+ class test_DeletePrefab_ContainingASingleEntity(EditorSharedTest):
+ from .tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
+
+ class test_DuplicatePrefab_ContainingASingleEntity(EditorSharedTest):
+ from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py
index 5c97f0b032..69dbcfc89c 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py
@@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
def DetachPrefab_UnderAnotherPrefab():
- CAR_PREFAB_FILE_NAME = 'car_prefab'
- WHEEL_PREFAB_FILE_NAME = 'wheel_prefab'
+ CAR_PREFAB_FILE_NAME = 'car_prefab2'
+ WHEEL_PREFAB_FILE_NAME = 'wheel_prefab2'
import editor_python_test_tools.pyside_utils as pyside_utils
diff --git a/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainMacroMaterialComponent_MacroMaterialActivates.py b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainMacroMaterialComponent_MacroMaterialActivates.py
new file mode 100644
index 0000000000..71ff02739a
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainMacroMaterialComponent_MacroMaterialActivates.py
@@ -0,0 +1,166 @@
+"""
+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
+"""
+
+class MacroMaterialTests:
+ setup_test = (
+ "Setup successful",
+ "Setup failed"
+ )
+ material_changed_not_called_when_inactive = (
+ "OnTerrainMacroMaterialRegionChanged not called successfully",
+ "OnTerrainMacroMaterialRegionChanged called when component inactive."
+ )
+ material_created = (
+ "MaterialCreated called successfully",
+ "MaterialCreated failed"
+ )
+ material_destroyed = (
+ "MaterialDestroyed called successfully",
+ "MaterialDestroyed failed"
+ )
+ material_recreated = (
+ "MaterialCreated called successfully on second test",
+ "MaterialCreated failed on second test"
+ )
+ material_changed_call_on_aabb_change = (
+ "OnTerrainMacroMaterialRegionChanged called successfully",
+ "Timed out waiting for OnTerrainMacroMaterialRegionChanged"
+ )
+
+def TerrainMacroMaterialComponent_MacroMaterialActivates():
+ """
+ Summary:
+ Load an empty level, create a MacroMaterialComponent and check assigning textures results in the correct callbacks.
+ :return: None
+ """
+
+ import os
+ import math as sys_math
+
+ import azlmbr.legacy.general as general
+ import azlmbr.asset as asset
+ import azlmbr.bus as bus
+ import azlmbr.math as math
+ import azlmbr.terrain as terrain
+ import azlmbr.editor as editor
+ import azlmbr.vegetation as vegetation
+ import azlmbr.entity as EntityId
+
+ import editor_python_test_tools.hydra_editor_utils as hydra
+ from editor_python_test_tools.utils import Report
+ from editor_python_test_tools.utils import TestHelper as helper
+ import editor_python_test_tools.pyside_utils as pyside_utils
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.asset_utils import Asset
+
+ material_created_called = False
+ material_changed_called = False
+ material_region_changed_called = False
+ material_destroyed_called = False
+
+ def create_entity_at(entity_name, components_to_add, x, y, z):
+ entity = EditorEntity.create_editor_entity_at([x, y, z], entity_name)
+ for component in components_to_add:
+ entity.add_component(component)
+
+ return entity
+
+ def on_macro_material_created(args):
+ nonlocal material_created_called
+ material_created_called = True
+
+ def on_macro_material_changed(args):
+ nonlocal material_changed_called
+ material_changed_called = True
+
+ def on_macro_material_region_changed(args):
+ nonlocal material_region_changed_called
+ material_region_changed_called = True
+
+ def on_macro_material_destroyed(args):
+ nonlocal material_destroyed_called
+ material_destroyed_called = True
+
+ helper.init_idle()
+
+ # Open a level.
+ helper.open_level("Physics", "Base")
+ helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
+
+ general.idle_wait_frames(1)
+
+ # Set up a handler to wait for notifications from the TerrainSystem.
+ handler = terrain.TerrainMacroMaterialAutomationBusHandler()
+ handler.connect()
+ handler.add_callback("OnTerrainMacroMaterialCreated", on_macro_material_created)
+ handler.add_callback("OnTerrainMacroMaterialChanged", on_macro_material_changed)
+ handler.add_callback("OnTerrainMacroMaterialRegionChanged", on_macro_material_region_changed)
+ handler.add_callback("OnTerrainMacroMaterialDestroyed", on_macro_material_destroyed)
+
+ macro_material_entity = create_entity_at("macro", ["Terrain Macro Material", "Axis Aligned Box Shape"], 0.0, 0.0, 0.0)
+
+ # Check that no macro material callbacks happened. It should be "inactive" as it has no assets assigned.
+ setup_success = not material_created_called and not material_changed_called and not material_region_changed_called and not material_destroyed_called
+ Report.result(MacroMaterialTests.setup_test, setup_success)
+
+ # Find the aabb component.
+ aabb_component_type_id_type = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Axis Aligned Box Shape"], 0)[0]
+ aabb_component_id = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'GetComponentOfType', macro_material_entity.id, aabb_component_type_id_type).GetValue()
+
+ # Change the aabb dimensions
+ material_region_changed_called = False
+ box_dimensions_path = "Axis Aligned Box Shape|Box Configuration|Dimensions"
+ editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", aabb_component_id, box_dimensions_path, math.Vector3(1.0, 1.0, 1.0))
+
+ # Check we don't receive a callback. The macro material component should be inactive as it has no images assigned.
+ general.idle_wait_frames(1)
+ Report.result(MacroMaterialTests.material_changed_not_called_when_inactive, material_region_changed_called == False)
+
+ # Find the macro material component.
+ macro_material_id_type = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Terrain Macro Material"], 0)[0]
+ macro_material_component_id = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'GetComponentOfType', macro_material_entity.id, macro_material_id_type).GetValue()
+
+ # Find a color image asset.
+ color_image_path = os.path.join("assets", "textures", "image.png.streamingimage")
+ color_image_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", color_image_path, math.Uuid(), False)
+
+ # Assign the image to the MacroMaterial component, which should result in a created message.
+ material_created_called = False
+ color_texture_path = "Configuration|Color Texture"
+ editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", macro_material_component_id, color_texture_path, color_image_asset)
+
+ call_result = helper.wait_for_condition(lambda: material_created_called == True, 2.0)
+ Report.result(MacroMaterialTests.material_created, call_result)
+
+ # Find a normal image asset.
+ normal_image_path = os.path.join("assets", "textures", "normal.png.streamingimage")
+ normal_image_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", normal_image_path, math.Uuid(), False)
+
+ # Assign the normal image to the MacroMaterial component, which should result in a created message.
+ material_created_called = False
+ material_destroyed_called = False
+ normal_texture_path = "Configuration|Normal Texture"
+ editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", macro_material_component_id, normal_texture_path, normal_image_asset)
+
+ # Check the MacroMaterial was destroyed and recreated.
+ destroyed_call_result = helper.wait_for_condition(lambda: material_destroyed_called == True, 2.0)
+ Report.result(MacroMaterialTests.material_destroyed, destroyed_call_result)
+
+ recreated_call_result = helper.wait_for_condition(lambda: material_created_called == True, 2.0)
+ Report.result(MacroMaterialTests.material_recreated, recreated_call_result)
+
+ # Change the aabb dimensions.
+ box_dimensions_path = "Axis Aligned Box Shape|Box Configuration|Dimensions"
+ editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", aabb_component_id, box_dimensions_path, math.Vector3(1.0, 1.0, 1.0))
+
+ # Check that a callback is received.
+ region_changed_call_result = helper.wait_for_condition(lambda: material_region_changed_called == True, 2.0)
+ Report.result(MacroMaterialTests.material_changed_call_on_aabb_change, region_changed_call_result)
+
+if __name__ == "__main__":
+
+ from editor_python_test_tools.utils import Report
+ Report.start_test(TerrainMacroMaterialComponent_MacroMaterialActivates)
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainSystem_VegetationSpawnsOnTerrainSurfaces.py b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainSystem_VegetationSpawnsOnTerrainSurfaces.py
new file mode 100644
index 0000000000..f1769ae3d9
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainSystem_VegetationSpawnsOnTerrainSurfaces.py
@@ -0,0 +1,214 @@
+"""
+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
+"""
+
+class VegetationTests:
+ vegetation_on_gradient_1 = (
+ "Vegetation detected at correct position on Gradient1",
+ "Vegetation not detected at correct position on Gradient1"
+ )
+ vegetation_on_gradient_2 = (
+ "Vegetation detected at correct position on Gradient2",
+ "Vegetation not detected at correct position on Gradient2"
+ )
+ unfiltered_vegetation_count_correct = (
+ "Unfiltered vegetation spawn count correct",
+ "Unfiltered vegetation spawn count incorrect"
+ )
+
+ testTag2_excluded_vegetation_count_correct = (
+ "TestTag2 filtered vegetation count correct",
+ "TestTag2 filtered vegetation count incorrect"
+ )
+ testTag2_excluded_vegetation_z_correct = (
+ "TestTag2 filtered vegetation spawned in correct position",
+ "TestTag2 filtered vegetation failed to spawn in correct position"
+ )
+
+ testTag3_excluded_vegetation_count_correct = (
+ "TestTag3 filtered vegetation count correct",
+ "TestTag3 filtered vegetation count incorrect"
+ )
+ testTag3_excluded_vegetation_z_correct = (
+ "TestTag3 filtered vegetation spawned in correct position",
+ "TestTag3 filtered vegetation failed to spawn in correct position"
+ )
+
+ cleared_exclusion_vegetation_count_correct = (
+ "Cleared filter vegetation count correct",
+ "Cleared filter vegetation count incorrect"
+ )
+
+def TerrainSystem_VegetationSpawnsOnTerrainSurfaces():
+ """
+ Summary:
+ Load an empty level,
+ Create two entities with constant gradient components with different values.
+ Create two entities with TerrainLayerSpawners
+ Create an entity to spawn vegetation
+ Ensure that vegetation spawns at the correct heights
+ Add a VegetationSurfaceMaskFilter and ensure it responds correctly to surface changes.
+ :return: None
+ """
+
+ import os
+ import sys
+ import math as sys_math
+
+ import azlmbr.legacy.general as general
+ import azlmbr.bus as bus
+ import azlmbr.math as math
+
+ import azlmbr.areasystem as areasystem
+ import azlmbr.editor as editor
+ import azlmbr.vegetation as vegetation
+ import azlmbr.terrain as terrain
+ import azlmbr.entity as EntityId
+ import azlmbr.surface_data as surface_data
+
+ import editor_python_test_tools.hydra_editor_utils as hydra
+ from editor_python_test_tools.utils import Report
+ from editor_python_test_tools.utils import TestHelper as helper
+
+ def create_entity_at(entity_name, components_to_add, x, y, z):
+ entity = hydra.Entity(entity_name)
+ entity.create_entity(math.Vector3(x, y, z), components_to_add)
+
+ return entity
+
+ def FindHighestAndLowestZValuesInArea(aabb):
+ vegetation_items = areasystem.AreaSystemRequestBus(bus.Broadcast, 'GetInstancesInAabb', aabb)
+
+ lowest_z = min([item.position.z for item in vegetation_items])
+ highest_z = max([item.position.z for item in vegetation_items])
+
+ return highest_z, lowest_z
+
+ helper.init_idle()
+
+ # Open an empty level.
+ helper.open_level("Physics", "Base")
+ helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
+
+ general.idle_wait_frames(1)
+
+ box_height = 20.0
+ box_y_position = 10.0
+ box_dimensions = math.Vector3(20.0, 20.0, box_height)
+
+ # Add Terrain Rendering
+ hydra.add_level_component("Terrain World")
+ hydra.add_level_component("Terrain World Renderer")
+
+ # Create two terrain entities at adjoining positions
+ terrain_entity_1 = create_entity_at("Terrain1", ["Terrain Layer Spawner", "Axis Aligned Box Shape", "Terrain Height Gradient List", "Terrain Surface Gradient List"], 0.0, box_y_position, box_height/2.0)
+ terrain_entity_1.get_set_test(1, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
+
+ terrain_entity_2 = create_entity_at("Terrain2", ["Terrain Layer Spawner", "Axis Aligned Box Shape", "Terrain Height Gradient List", "Terrain Surface Gradient List"], 20.0, box_y_position, box_height/2.0)
+ terrain_entity_2.get_set_test(1, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
+
+ # Create two gradient entities.
+ gradient_value_1 = 0.25
+ gradient_value_2 = 0.5
+
+ gradient_entity_1 = create_entity_at("Gradient1", ["Constant Gradient"], 0.0, 0.0, 0.0)
+ gradient_entity_1.get_set_test(0, "Configuration|Value", gradient_value_1)
+
+ gradient_entity_2 = create_entity_at("Gradient2", ["Constant Gradient"], 0.0, 0.0, 0.0)
+ gradient_entity_2.get_set_test(0, "Configuration|Value", gradient_value_2)
+
+ mapping = terrain.TerrainSurfaceGradientMapping()
+ mapping.gradientEntityId = gradient_entity_1.id
+ pte = hydra.get_property_tree(terrain_entity_1.components[3])
+ pte.add_container_item("Configuration|Gradient to Surface Mappings", 0, mapping)
+
+ mapping = terrain.TerrainSurfaceGradientMapping()
+ mapping.gradientEntityId = gradient_entity_2.id
+ pte = hydra.get_property_tree(terrain_entity_2.components[3])
+ pte.add_container_item("Configuration|Gradient to Surface Mappings", 0, mapping)
+
+ # create a vegetation entity that overlaps both terrain entities.
+ vegetation_entity = create_entity_at("Vegetation", ["Vegetation Layer Spawner", "Axis Aligned Box Shape", "Vegetation Asset List", "Vegetation Surface Mask Filter"], 10.0, box_y_position, box_height/2.0)
+ vegetation_entity.get_set_test(1, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
+
+ # Set the vegetation area to a PrefabInstanceSpawner with a specific prefab asset selected.
+ prefab_spawner = vegetation.PrefabInstanceSpawner()
+ prefab_spawner.SetPrefabAssetPath(os.path.join("Prefabs", "PinkFlower.spawnable"))
+ descriptor = hydra.get_component_property_value(vegetation_entity.components[2], 'Configuration|Embedded Assets|[0]')
+ descriptor.spawner = prefab_spawner
+ vegetation_entity.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor)
+
+ # Assign gradients to layer spawners.
+ terrain_entity_1.get_set_test(2, "Configuration|Gradient Entities", [gradient_entity_1.id])
+ terrain_entity_2.get_set_test(2, "Configuration|Gradient Entities", [gradient_entity_2.id])
+
+ # Move view so that the entities are visible.
+ general.set_current_view_position(17.0, -66.0, 41.0)
+ general.set_current_view_rotation(-15, 0, 0)
+
+ # Expected item counts under conditions to be tested.
+ # By default, vegetation spawns at a density of 20 items per 16 meters,
+ # so in a 20m square, there should be around 25 ^ 2 items depending on whether area edges are included.
+ # In this case there are 26 ^ 2 items.
+ expected_surface_tag_excluded_item_count = 338
+ expected_no_exclusions_item_count = 676
+
+ # Wait for the vegetation to spawn
+ helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_no_exclusions_item_count, 5.0)
+
+ # Check the spawn count is correct.
+ item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
+ Report.result(VegetationTests.unfiltered_vegetation_count_correct, item_count == expected_no_exclusions_item_count)
+
+ test_aabb = math.Aabb_CreateFromMinMax(math.Vector3(-10.0, -10.0, 0.0), math.Vector3(30.0, 10.0, box_height))
+
+ # Find the z positions of the items with the lowest and highest x values, this will avoid the overlap area where z values are blended between the surface heights.
+ highest_z, lowest_z = FindHighestAndLowestZValuesInArea(test_aabb)
+
+ # Check that the z values are as expected.
+ Report.result(VegetationTests.vegetation_on_gradient_1, sys_math.isclose(lowest_z, box_height * gradient_value_1, abs_tol=0.01))
+ Report.result(VegetationTests.vegetation_on_gradient_2, sys_math.isclose(highest_z, box_height * gradient_value_2, abs_tol=0.01))
+
+ # Assign SurfaceTags to the SurfaceGradientLists
+ terrain_entity_1.get_set_test(3, "Configuration|Gradient to Surface Mappings|[0]|Surface Tag", surface_data.SurfaceTag("test_tag2"))
+ terrain_entity_2.get_set_test(3, "Configuration|Gradient to Surface Mappings|[0]|Surface Tag", surface_data.SurfaceTag("test_tag3"))
+
+ # Give the VegetationSurfaceFilter an exclusion list, set it to exclude test_tag2 which should remove all the lower items which are in terrain_entity_1.
+ vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags", [surface_data.SurfaceTag()])
+ vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags|[0]", surface_data.SurfaceTag("test_tag2"))
+
+ # Wait for the vegetation to respawn and check z values.
+ helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_surface_tag_excluded_item_count, 5.0)
+
+ item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
+ Report.result(VegetationTests.testTag2_excluded_vegetation_count_correct, item_count == expected_surface_tag_excluded_item_count)
+
+ highest_z, lowest_z = FindHighestAndLowestZValuesInArea(test_aabb)
+
+ Report.result(VegetationTests.testTag2_excluded_vegetation_z_correct, lowest_z > box_height * gradient_value_1)
+
+ # Clear the filter and ensure vegetation respawns.
+ vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags|[0]", surface_data.SurfaceTag("invalid"))
+ helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_no_exclusions_item_count, 5.0)
+
+ item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
+ Report.result(VegetationTests.cleared_exclusion_vegetation_count_correct, item_count == expected_no_exclusions_item_count)
+
+ # Exclude test_tag3 to exclude the higher items in terrain_entity_2 and recheck.
+ vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags|[0]", surface_data.SurfaceTag("test_tag3"))
+
+ helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_surface_tag_excluded_item_count, 5.0)
+
+ item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
+ Report.result(VegetationTests.testTag3_excluded_vegetation_count_correct, item_count == expected_surface_tag_excluded_item_count)
+
+ highest_z, lowest_z = FindHighestAndLowestZValuesInArea(test_aabb)
+
+ Report.result(VegetationTests.testTag3_excluded_vegetation_z_correct, highest_z < box_height * gradient_value_2)
+
+if __name__ == "__main__":
+
+ from editor_python_test_tools.utils import Report
+ Report.start_test(TerrainSystem_VegetationSpawnsOnTerrainSurfaces)
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/Terrain_World_ConfigurationWorks.py b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/Terrain_World_ConfigurationWorks.py
new file mode 100644
index 0000000000..bb5dcb3bea
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/Terrain_World_ConfigurationWorks.py
@@ -0,0 +1,168 @@
+"""
+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
+"""
+
+#fmt: off
+class Tests():
+ level_components_added = ("Level components added correctly", "Failed to create level components")
+ create_terrain_spawner_entity = ("Terrain_spawner_entity created successfully", "Failed to create terrain_spawner_entity")
+ create_height_provider_entity = ("Height_provider_entity created successfully", "Failed to create height_provider_entity")
+ bounds_max_changed = ("Terrain World Bounds Max changed successfully", "Failed to change Terrain World Bounds Max")
+ bounds_min_changed = ("Terrain World Bounds Min changed successfully", "Failed to change Terrain World Bounds Min")
+ height_query_changed = ("Terrain World Height Query Resolution changed successfully", "Failed to change Height Query Resolution")
+ box_dimensions_changed = ("Aabb dimensions changed successfully", "Failed to change Aabb dimensions")
+ shape_changed = ("Shape changed successfully", "Failed Shape change")
+ frequency_changed = ("Frequency changed successfully", "Failed Frequency change")
+ entity_added = ("Entity added successfully", "Failed Entity add")
+ terrain_exists = ("Terrain exists at the provided point", "Terrain does not exist at the provided point")
+ terrain_does_not_exist = ("Terrain does not exist at the provided point", "Terrain exists at the provided point")
+ values_not_the_same = ("The tested values are not the same", "The tested values are the same")
+ no_errors_and_warnings_found = ("No errors and warnings found", "Found errors and warnings")
+#fmt: on
+
+def Terrain_World_ConfigurationWorks():
+ """
+ Summary:
+ Test the Terrain World configuration changes when parameters are changed in the component
+
+ Test Steps:
+ Expected Behavior:
+ The Editor is stable there are no warnings or errors.
+
+ Test Steps:
+ 1) Start the Tracer to catch any errors and warnings
+ 2) Load the base level
+ 3) Load the level components
+ 4) Create 2 test entities, one parent at 512.0, 512.0, 50.0 and one child at the default position and add the required components
+ 5) Set the base Terrain World values
+ 6) Change the Axis Aligned Box Shape dimensions
+ 7) Set the Shape Reference to terrain_spawner_entity
+ 8) Set the FastNoise Gradient frequency to 0.01
+ 9) Set the Gradient List to height_provider_entity
+ 10) Disable and Enable the Terrain Gradient List so that it is recognised
+ 11) Check terrain exists at a known position in the world
+ 12) Check terrain does not exist at a known position outside the world
+ 13) Check height value is the expected one when query resolution is changed
+ """
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import TestHelper as helper, Report
+ from editor_python_test_tools.utils import Report, Tracer
+ import editor_python_test_tools.hydra_editor_utils as hydra
+ import azlmbr.math as azmath
+ import azlmbr.legacy.general as general
+ import azlmbr.bus as bus
+ import azlmbr.editor as editor
+ import azlmbr.terrain as terrain
+ import math
+
+ SET_BOX_X_SIZE = 2048.0
+ SET_BOX_Y_SIZE = 2048.0
+ SET_BOX_Z_SIZE = 100.0
+ CLAMP = 1
+
+ helper.init_idle()
+
+ # 1) Start the Tracer to catch any errors and warnings
+ with Tracer() as section_tracer:
+ # 2) Load the level
+ helper.open_level("", "Base")
+ helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
+
+ # 3) Load the level components
+ terrain_world_component = hydra.add_level_component("Terrain World")
+ terrain_world_renderer = hydra.add_level_component("Terrain World Renderer")
+ Report.critical_result(Tests.level_components_added,
+ terrain_world_component is not None and terrain_world_renderer is not None)
+
+ # 4) Create 2 test entities, one parent at 512.0, 512.0, 50.0 and one child at the default position and add the required components
+ entity1_components_to_add = ["Axis Aligned Box Shape", "Terrain Layer Spawner", "Terrain Height Gradient List", "Terrain Physics Heightfield Collider"]
+ entity2_components_to_add = ["Shape Reference", "Gradient Transform Modifier", "FastNoise Gradient"]
+ terrain_spawner_entity = hydra.Entity("TerrainEntity")
+ terrain_spawner_entity.create_entity(azmath.Vector3(512.0, 512.0, 50.0), entity1_components_to_add)
+ Report.result(Tests.create_terrain_spawner_entity, terrain_spawner_entity.id.IsValid())
+ height_provider_entity = hydra.Entity("HeightProviderEntity")
+ height_provider_entity.create_entity(azmath.Vector3(0.0, 0.0, 0.0), entity2_components_to_add,terrain_spawner_entity.id)
+ Report.result(Tests.create_height_provider_entity, height_provider_entity.id.IsValid())
+
+ # Give everything a chance to finish initializing.
+ general.idle_wait_frames(1)
+
+ # 5) Set the base Terrain World values
+ world_bounds_max = azmath.Vector3(1100.0, 1100.0, 1100.0)
+ world_bounds_min = azmath.Vector3(10.0, 10.0, 10.0)
+ height_query_resolution = azmath.Vector2(1.0, 1.0)
+ hydra.set_component_property_value(terrain_world_component, "Configuration|World Bounds (Max)", world_bounds_max)
+ hydra.set_component_property_value(terrain_world_component, "Configuration|World Bounds (Min)", world_bounds_min)
+ hydra.set_component_property_value(terrain_world_component, "Configuration|Height Query Resolution (m)", height_query_resolution)
+ world_max = hydra.get_component_property_value(terrain_world_component, "Configuration|World Bounds (Max)")
+ world_min = hydra.get_component_property_value(terrain_world_component, "Configuration|World Bounds (Min)")
+ world_query = hydra.get_component_property_value(terrain_world_component, "Configuration|Height Query Resolution (m)")
+ Report.result(Tests.bounds_max_changed, world_max == world_bounds_max)
+ Report.result(Tests.bounds_min_changed, world_min == world_bounds_min)
+ Report.result(Tests.height_query_changed, world_query == height_query_resolution)
+
+ # 6) Change the Axis Aligned Box Shape dimensions
+ box_dimensions = azmath.Vector3(SET_BOX_X_SIZE, SET_BOX_Y_SIZE, SET_BOX_Z_SIZE)
+ terrain_spawner_entity.get_set_test(0, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
+ box_shape_dimensions = hydra.get_component_property_value(terrain_spawner_entity.components[0], "Axis Aligned Box Shape|Box Configuration|Dimensions")
+ Report.result(Tests.box_dimensions_changed, box_dimensions == box_shape_dimensions)
+
+ # 7) Set the Shape Reference to terrain_spawner_entity
+ height_provider_entity.get_set_test(0, "Configuration|Shape Entity Id", terrain_spawner_entity.id)
+ entityId = hydra.get_component_property_value(height_provider_entity.components[0], "Configuration|Shape Entity Id")
+ Report.result(Tests.shape_changed, entityId == terrain_spawner_entity.id)
+
+ # 8) Set the FastNoise Gradient frequency to 0.01
+ frequency = 0.01
+ height_provider_entity.get_set_test(2, "Configuration|Frequency", frequency)
+ frequencyVal = hydra.get_component_property_value(height_provider_entity.components[2], "Configuration|Frequency")
+ Report.result(Tests.frequency_changed, math.isclose(frequency, frequencyVal, abs_tol = 0.00001))
+
+ # 9) Set the Gradient List to height_provider_entity
+ propertyTree = hydra.get_property_tree(terrain_spawner_entity.components[2])
+ propertyTree.add_container_item("Configuration|Gradient Entities", 0, height_provider_entity.id)
+ checkID = propertyTree.get_container_item("Configuration|Gradient Entities", 0)
+ Report.result(Tests.entity_added, checkID.GetValue() == height_provider_entity.id)
+
+ general.idle_wait_frames(1)
+
+ # 10) Disable and Enable the Terrain Gradient List so that it is recognised, EnableComponents performs both actions.
+ editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [terrain_spawner_entity.components[2]])
+
+ # 11) Check terrain exists at a known position in the world
+ terrainExists = not terrain.TerrainDataRequestBus(bus.Broadcast, 'GetIsHoleFromFloats', 10.0, 10.0, CLAMP)
+ Report.result(Tests.terrain_exists, terrainExists)
+
+ terrainExists = not terrain.TerrainDataRequestBus(bus.Broadcast, 'GetIsHoleFromFloats', 1100.0, 1100.0, CLAMP)
+ Report.result(Tests.terrain_exists, terrainExists)
+
+ # 12) Check terrain does not exist at a known position outside the world
+ terrainDoesNotExist = terrain.TerrainDataRequestBus(bus.Broadcast, 'GetIsHoleFromFloats', 1101.0, 1101.0, CLAMP)
+ Report.result(Tests.terrain_does_not_exist, terrainDoesNotExist)
+
+ terrainDoesNotExist = terrain.TerrainDataRequestBus(bus.Broadcast, 'GetIsHoleFromFloats', 9.0, 9.0, CLAMP)
+ Report.result(Tests.terrain_does_not_exist, terrainDoesNotExist)
+
+ # 13) Check height value is the expected one when query resolution is changed
+ testpoint = terrain.TerrainDataRequestBus(bus.Broadcast, 'GetHeightFromFloats', 10.5, 10.5, CLAMP)
+ height_query_resolution = azmath.Vector2(0.5, 0.5)
+ hydra.set_component_property_value(terrain_world_component, "Configuration|Height Query Resolution (m)", height_query_resolution)
+ general.idle_wait_frames(1)
+ testpoint2 = terrain.TerrainDataRequestBus(bus.Broadcast, 'GetHeightFromFloats', 10.5, 10.5, CLAMP)
+ Report.result(Tests.values_not_the_same, not math.isclose(testpoint, testpoint2, abs_tol = 0.000000001))
+
+ helper.wait_for_condition(lambda: section_tracer.has_errors or section_tracer.has_asserts, 1.0)
+ for error_info in section_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in section_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
+
+
+if __name__ == "__main__":
+
+ from editor_python_test_tools.utils import Report
+ Report.start_test(Terrain_World_ConfigurationWorks)
+
diff --git a/AutomatedTesting/Gem/PythonTests/Terrain/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Terrain/TestSuite_Main.py
index fc9a917f47..98c4f8a660 100644
--- a/AutomatedTesting/Gem/PythonTests/Terrain/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/Terrain/TestSuite_Main.py
@@ -27,6 +27,15 @@ class TestAutomation(EditorTestSuite):
class test_Terrain_SupportsPhysics(EditorSharedTest):
from .EditorScripts import Terrain_SupportsPhysics as test_module
-
+
class test_TerrainHeightGradientList_AddRemoveGradientWorks(EditorSharedTest):
from .EditorScripts import TerrainHeightGradientList_AddRemoveGradientWorks as test_module
+
+ class test_TerrainSystem_VegetationSpawnsOnTerrainSurfaces(EditorSharedTest):
+ from .EditorScripts import TerrainSystem_VegetationSpawnsOnTerrainSurfaces as test_module
+
+ class test_TerrainMacroMaterialComponent_MacroMaterialActivates(EditorSharedTest):
+ from .EditorScripts import TerrainMacroMaterialComponent_MacroMaterialActivates as test_module
+
+ class test_TerrainWorld_ConfigurationWorks(EditorSharedTest):
+ from .EditorScripts import Terrain_World_ConfigurationWorks as test_module
diff --git a/AutomatedTesting/Gem/Sponza/.gitignore b/AutomatedTesting/Gem/Sponza/.gitignore
new file mode 100644
index 0000000000..8bbb0be455
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/.gitignore
@@ -0,0 +1,4 @@
+/.maya_data/*
+/.mayaSwatches/*
+*.swatch
+[Uu]ser_env.bat
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/.src/objects/sponza.ma b/AutomatedTesting/Gem/Sponza/.src/objects/sponza.ma
new file mode 100644
index 0000000000..1c137a50b7
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/.src/objects/sponza.ma
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:57848334af0220b7348a8f2583080acf1d9c139a78c9fb1a93a7d2bce61f3c40
+size 41335413
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Prefabs/test_sponza_material_conversion.prefab b/AutomatedTesting/Gem/Sponza/Assets/Prefabs/test_sponza_material_conversion.prefab
new file mode 100644
index 0000000000..92874574e4
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Prefabs/test_sponza_material_conversion.prefab
@@ -0,0 +1,1240 @@
+{
+ "Source": "Prefabs/test_sponza_material_conversion.prefab",
+ "ContainerEntity": {
+ "Id": "ContainerEntity",
+ "Name": "test_sponza_material_conversion",
+ "Components": {
+ "Component_[11355906858588942318]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 11355906858588942318
+ },
+ "Component_[12303631836799763574]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 12303631836799763574
+ },
+ "Component_[13884330903538620487]": {
+ "$type": "SelectionComponent",
+ "Id": 13884330903538620487
+ },
+ "Component_[14017626015546393905]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14017626015546393905
+ },
+ "Component_[15706249274315432595]": {
+ "$type": "EditorLockComponent",
+ "Id": 15706249274315432595
+ },
+ "Component_[17662098699702294917]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 17662098699702294917
+ },
+ "Component_[1984406083399463185]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1984406083399463185
+ },
+ "Component_[3645983967515381372]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 3645983967515381372
+ },
+ "Component_[7000715958539023355]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 7000715958539023355
+ },
+ "Component_[7182760741886065388]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7182760741886065388,
+ "Parent Entity": "",
+ "Cached World Transform Parent": ""
+ },
+ "Component_[7314978375961307600]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7314978375961307600
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entities": {
+ "Entity_[1220355829629]": {
+ "Id": "Entity_[1220355829629]",
+ "Name": "GiTestProbe",
+ "Components": {
+ "Component_[12581383605035992405]": {
+ "$type": "SelectionComponent",
+ "Id": 12581383605035992405
+ },
+ "Component_[14182862666898786767]": {
+ "$type": "AZ::Render::EditorReflectionProbeComponent",
+ "Id": 14182862666898786767,
+ "Controller": {
+ "Configuration": {
+ "OuterHeight": 8.0,
+ "OuterLength": 8.0,
+ "OuterWidth": 8.0,
+ "InnerHeight": 8.0,
+ "InnerLength": 8.0,
+ "InnerWidth": 8.0,
+ "BakedCubeMapRelativePath": "ReflectionProbes/GiTestProbe__0564394E-2435-488E-A30C-E999F79FB049__iblspecularcm256.dds",
+ "BakedCubeMapAsset": {
+ "assetId": {
+ "guid": "{B05482A4-7D4D-5C6D-96DD-54CB9A227307}",
+ "subId": 2000
+ },
+ "loadBehavior": "PreLoad",
+ "assetHint": "reflectionprobes/gitestprobe__0564394e-2435-488e-a30c-e999f79fb049__iblspecularcm256.dds.streamingimage"
+ },
+ "EntityId": 12080580926711778904
+ }
+ },
+ "bakedCubeMapRelativePath": "ReflectionProbes/GiTestProbe__0564394E-2435-488E-A30C-E999F79FB049__iblspecularcm256.dds"
+ },
+ "Component_[16557111097824744403]": {
+ "$type": "EditorBoxShapeComponent",
+ "Id": 16557111097824744403,
+ "BoxShape": {
+ "Configuration": {
+ "Dimensions": [
+ 8.0,
+ 8.0,
+ 8.0
+ ]
+ }
+ }
+ },
+ "Component_[16623349159368925155]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 16623349159368925155
+ },
+ "Component_[17588593493138070858]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 17588593493138070858
+ },
+ "Component_[18332655128892032441]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 18332655128892032441
+ },
+ "Component_[344586797989012598]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 344586797989012598,
+ "Parent Entity": "Entity_[1250420600701]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ 4.0
+ ]
+ },
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 4.099999904632568
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1250420600701]"
+ },
+ "Component_[5703653759245493769]": {
+ "$type": "EditorLockComponent",
+ "Id": 5703653759245493769
+ },
+ "Component_[7030857297912025340]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7030857297912025340,
+ "DisabledComponents": [
+ {
+ "$type": "AZ::Render::EditorDiffuseProbeGridComponent",
+ "Id": 1614505811629141904,
+ "Controller": {
+ "Configuration": {
+ "ProbeSpacing": [
+ 0.5,
+ 0.5,
+ 0.5
+ ],
+ "Extents": [
+ 8.0,
+ 8.0,
+ 8.0
+ ]
+ }
+ },
+ "probeSpacingX": 0.5,
+ "probeSpacingY": 0.5,
+ "probeSpacingZ": 0.5
+ }
+ ]
+ },
+ "Component_[7984183259827618750]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 7984183259827618750
+ },
+ "Component_[827806435204448771]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 827806435204448771
+ },
+ "Component_[8673278437899912468]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 8673278437899912468
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1224650796925]": {
+ "Id": "Entity_[1224650796925]",
+ "Name": "Camera",
+ "Components": {
+ "Component_[10395754987446042279]": {
+ "$type": "AZ::Render::EditorPostFxLayerComponent",
+ "Id": 10395754987446042279
+ },
+ "Component_[11895140916889160460]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11895140916889160460
+ },
+ "Component_[16880285896855930892]": {
+ "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+ "Id": 16880285896855930892,
+ "Controller": {
+ "Configuration": {
+ "Field of View": 55.0,
+ "EditorEntityId": 8929576024571800510
+ }
+ }
+ },
+ "Component_[17187464423780271193]": {
+ "$type": "EditorLockComponent",
+ "Id": 17187464423780271193
+ },
+ "Component_[17495696818315413311]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 17495696818315413311
+ },
+ "Component_[1798550073623453489]": {
+ "$type": "AZ::Render::EditorExposureControlComponent",
+ "Id": 1798550073623453489,
+ "Controller": {
+ "Configuration": {
+ "ExposureControlType": 1
+ }
+ }
+ },
+ "Component_[18086214374043522055]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 18086214374043522055,
+ "Parent Entity": "Entity_[1250420600701]",
+ "Transform Data": {
+ "Translate": [
+ 1.7387686967849732,
+ 1.752368450164795,
+ 5.225453853607178
+ ],
+ "Rotate": [
+ 34.95081329345703,
+ -29.21880340576172,
+ 145.06878662109376
+ ]
+ },
+ "Cached World Transform": {
+ "Translation": [
+ 1.7387685775756837,
+ 1.7523683309555054,
+ 5.325453281402588
+ ],
+ "Rotation": [
+ -0.14265206456184388,
+ -0.3503122329711914,
+ 0.8573471903800964,
+ 0.3491239547729492
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1250420600701]"
+ },
+ "Component_[18387556550380114975]": {
+ "$type": "SelectionComponent",
+ "Id": 18387556550380114975
+ },
+ "Component_[2654521436129313160]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 2654521436129313160
+ },
+ "Component_[5265045084611556958]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5265045084611556958
+ },
+ "Component_[7169798125182238623]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7169798125182238623
+ },
+ "Component_[8866210352157164042]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 8866210352157164042
+ },
+ "Component_[9129253381063760879]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 9129253381063760879
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1228945764221]": {
+ "Id": "Entity_[1228945764221]",
+ "Name": "Global Sky",
+ "Components": {
+ "Component_[11231930600558681245]": {
+ "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+ "Id": 11231930600558681245,
+ "Controller": {
+ "Configuration": {
+ "CubemapAsset": {
+ "assetId": {
+ "guid": "{874DA395-146F-5198-90AD-532F18954407}",
+ "subId": 1000
+ },
+ "assetHint": "testdata/white_latlong_iblskyboxcm.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[11980494120202836095]": {
+ "$type": "SelectionComponent",
+ "Id": 11980494120202836095
+ },
+ "Component_[1428633914413949476]": {
+ "$type": "EditorLockComponent",
+ "Id": 1428633914413949476
+ },
+ "Component_[14936200426671614999]": {
+ "$type": "AZ::Render::EditorImageBasedLightComponent",
+ "Id": 14936200426671614999,
+ "Controller": {
+ "Configuration": {
+ "diffuseImageAsset": {
+ "assetId": {
+ "guid": "{874DA395-146F-5198-90AD-532F18954407}",
+ "subId": 3000
+ },
+ "assetHint": "testdata/white_latlong_iblskyboxcm_ibldiffuse.exr.streamingimage"
+ },
+ "specularImageAsset": {
+ "assetId": {
+ "guid": "{874DA395-146F-5198-90AD-532F18954407}",
+ "subId": 2000
+ },
+ "assetHint": "testdata/white_latlong_iblskyboxcm_iblspecular.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[14994774102579326069]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 14994774102579326069
+ },
+ "Component_[15417479889044493340]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 15417479889044493340
+ },
+ "Component_[15826613364991382688]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 15826613364991382688
+ },
+ "Component_[1665003113283562343]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1665003113283562343
+ },
+ "Component_[3704934735944502280]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 3704934735944502280
+ },
+ "Component_[5698542331457326479]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 5698542331457326479
+ },
+ "Component_[6644513399057217122]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6644513399057217122,
+ "Parent Entity": "Entity_[1250420600701]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ -0.10000000149011612
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1250420600701]"
+ },
+ "Component_[931091830724002070]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 931091830724002070
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1233240731517]": {
+ "Id": "Entity_[1233240731517]",
+ "Name": "Shader Ball",
+ "Components": {
+ "Component_[10789351944715265527]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 10789351944715265527
+ },
+ "Component_[12037033284781049225]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 12037033284781049225
+ },
+ "Component_[13759153306105970079]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13759153306105970079
+ },
+ "Component_[14135560884830586279]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14135560884830586279
+ },
+ "Component_[16247165675903986673]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 16247165675903986673
+ },
+ "Component_[18082433625958885247]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 18082433625958885247
+ },
+ "Component_[6472623349872972660]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6472623349872972660,
+ "Parent Entity": "Entity_[1250420600701]",
+ "Transform Data": {
+ "Rotate": [
+ 0.0,
+ 0.10000000149011612,
+ 180.0
+ ]
+ },
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 0.10000000149011612
+ ],
+ "Rotation": [
+ 0.0008726645028218627,
+ 0.0,
+ 0.9999996423721314,
+ 0.0
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1250420600701]"
+ },
+ "Component_[6495255223970673916]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 6495255223970673916,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
+ "subId": 281415304
+ },
+ "assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[8056625192494070973]": {
+ "$type": "SelectionComponent",
+ "Id": 8056625192494070973
+ },
+ "Component_[8550141614185782969]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 8550141614185782969
+ },
+ "Component_[9439770997198325425]": {
+ "$type": "EditorLockComponent",
+ "Id": 9439770997198325425
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1237535698813]": {
+ "Id": "Entity_[1237535698813]",
+ "Name": "Sun",
+ "Components": {
+ "Component_[10440557478882592717]": {
+ "$type": "SelectionComponent",
+ "Id": 10440557478882592717
+ },
+ "Component_[13620450453324765907]": {
+ "$type": "EditorLockComponent",
+ "Id": 13620450453324765907
+ },
+ "Component_[2134313378593666258]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 2134313378593666258
+ },
+ "Component_[234010807770404186]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 234010807770404186
+ },
+ "Component_[2970359110423865725]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 2970359110423865725
+ },
+ "Component_[3722854130373041803]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3722854130373041803
+ },
+ "Component_[5992533738676323195]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5992533738676323195
+ },
+ "Component_[7378860763541895402]": {
+ "$type": "AZ::Render::EditorDirectionalLightComponent",
+ "Id": 7378860763541895402,
+ "Controller": {
+ "Configuration": {
+ "Intensity": 0.0,
+ "CameraEntityId": "",
+ "ShadowFilterMethod": 1
+ }
+ }
+ },
+ "Component_[7892834440890947578]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7892834440890947578,
+ "Parent Entity": "Entity_[1250420600701]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ 13.38704299926758
+ ],
+ "Rotate": [
+ -76.1310043334961,
+ -0.8469989895820618,
+ -15.8100004196167
+ ]
+ },
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 13.487043380737305
+ ],
+ "Rotation": [
+ -0.609886109828949,
+ -0.09055805951356888,
+ -0.10376212745904924,
+ 0.7804304361343384
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1250420600701]"
+ },
+ "Component_[8599729549570828259]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 8599729549570828259
+ },
+ "Component_[952797371922080273]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 952797371922080273
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1241830666109]": {
+ "Id": "Entity_[1241830666109]",
+ "Name": "Ground",
+ "Components": {
+ "Component_[11701138785793981042]": {
+ "$type": "SelectionComponent",
+ "Id": 11701138785793981042
+ },
+ "Component_[12260880513256986252]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 12260880513256986252
+ },
+ "Component_[13711420870643673468]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 13711420870643673468
+ },
+ "Component_[138002849734991713]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 138002849734991713
+ },
+ "Component_[16578565737331764849]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 16578565737331764849,
+ "Parent Entity": "Entity_[1250420600701]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ -0.10000000149011612
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1250420600701]"
+ },
+ "Component_[16919232076966545697]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 16919232076966545697
+ },
+ "Component_[5182430712893438093]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 5182430712893438093,
+ "materialSlots": [
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
+ "subId": 803645540
+ }
+ }
+ }
+ ],
+ "materialSlotsByLod": [
+ [
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
+ "subId": 803645540
+ }
+ }
+ }
+ ]
+ ]
+ },
+ "Component_[5675108321710651991]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 5675108321710651991,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
+ "subId": 277889906
+ },
+ "assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[5681893399601237518]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 5681893399601237518
+ },
+ "Component_[592692962543397545]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 592692962543397545
+ },
+ "Component_[7090012899106946164]": {
+ "$type": "EditorLockComponent",
+ "Id": 7090012899106946164
+ },
+ "Component_[9410832619875640998]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 9410832619875640998
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1246125633405]": {
+ "Id": "Entity_[1246125633405]",
+ "Name": "Grid",
+ "Components": {
+ "Component_[11443347433215807130]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11443347433215807130
+ },
+ "Component_[11779275529534764488]": {
+ "$type": "SelectionComponent",
+ "Id": 11779275529534764488
+ },
+ "Component_[14249419413039427459]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14249419413039427459
+ },
+ "Component_[15448581635946161318]": {
+ "$type": "AZ::Render::EditorGridComponent",
+ "Id": 15448581635946161318,
+ "Controller": {
+ "Configuration": {
+ "primarySpacing": 4.0,
+ "primaryColor": [
+ 0.501960813999176,
+ 0.501960813999176,
+ 0.501960813999176
+ ],
+ "secondarySpacing": 0.5,
+ "secondaryColor": [
+ 0.250980406999588,
+ 0.250980406999588,
+ 0.250980406999588
+ ]
+ }
+ }
+ },
+ "Component_[1843303322527297409]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 1843303322527297409
+ },
+ "Component_[380249072065273654]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 380249072065273654,
+ "Parent Entity": "Entity_[1250420600701]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ -0.10000000149011612
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1250420600701]"
+ },
+ "Component_[7476660583684339787]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7476660583684339787
+ },
+ "Component_[7557626501215118375]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 7557626501215118375
+ },
+ "Component_[7984048488947365511]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 7984048488947365511
+ },
+ "Component_[8118181039276487398]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 8118181039276487398
+ },
+ "Component_[9189909764215270515]": {
+ "$type": "EditorLockComponent",
+ "Id": 9189909764215270515
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1250420600701]": {
+ "Id": "Entity_[1250420600701]",
+ "Name": "test_sponza_material_conversion",
+ "Components": {
+ "Component_[11342679732910125733]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 11342679732910125733,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 273579101
+ },
+ "assetHint": "testdata/test_sponza_material_conversion.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[11482250315251448254]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11482250315251448254
+ },
+ "Component_[12520362418832404237]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12520362418832404237
+ },
+ "Component_[13922696236864086628]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 13922696236864086628,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 9795135998007712828
+ },
+ {
+ "ComponentId": 11342679732910125733,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 14504829236779989058,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[14504829236779989058]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 14504829236779989058,
+ "Controller": {
+ "Configuration": {
+ "materials": [
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 40852248
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{1D8B391C-DEB3-549E-9A30-14A6989B1B50}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_floor.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 842740826
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{F3C97FF0-8FC7-5207-9E97-21D680962068}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 1262202891
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{AF16DFCF-E1E9-57B9-8F01-A49AAC1962AE}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 2438226774
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{4310E0FE-532D-5436-A946-49B2E14B0375}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 2816279700
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{6339FEBB-4293-5CEF-809A-2BE072AC94D6}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_bricks.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3157644117
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{3EF8BEDB-8DE0-5550-A994-D542086622B7}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_arch.azmaterial"
+ },
+ "PropertyOverrides": {
+ "general.applySpecularAA": {
+ "$type": "bool",
+ "Value": true
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3208782114
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{CCA05CBE-2606-59A3-91A9-E46F97980A38}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3591631827
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{B45DCFD4-6B12-5212-AB92-B64E064155CE}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3888291602
+ }
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{E6A159AA-989D-5534-8550-1E002148AC84}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_roof.azmaterial"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "materialSlots": [
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 842740826
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{F3C97FF0-8FC7-5207-9E97-21D680962068}"
+ }
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3208782114
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{CCA05CBE-2606-59A3-91A9-E46F97980A38}"
+ }
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3157644117
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{3EF8BEDB-8DE0-5550-A994-D542086622B7}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_arch.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 2816279700
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{6339FEBB-4293-5CEF-809A-2BE072AC94D6}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_bricks.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 40852248
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{1D8B391C-DEB3-549E-9A30-14A6989B1B50}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_floor.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3888291602
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{E6A159AA-989D-5534-8550-1E002148AC84}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_roof.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 2438226774
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{4310E0FE-532D-5436-A946-49B2E14B0375}"
+ }
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 1262202891
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{AF16DFCF-E1E9-57B9-8F01-A49AAC1962AE}"
+ }
+ }
+ },
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3591631827
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{B45DCFD4-6B12-5212-AB92-B64E064155CE}"
+ }
+ }
+ }
+ ],
+ "materialSlotsByLod": [
+ [
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 842740826
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{F3C97FF0-8FC7-5207-9E97-21D680962068}"
+ }
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3208782114
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{CCA05CBE-2606-59A3-91A9-E46F97980A38}"
+ }
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3157644117
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{3EF8BEDB-8DE0-5550-A994-D542086622B7}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_arch.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 2816279700
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{6339FEBB-4293-5CEF-809A-2BE072AC94D6}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_bricks.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 40852248
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{1D8B391C-DEB3-549E-9A30-14A6989B1B50}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_floor.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3888291602
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{E6A159AA-989D-5534-8550-1E002148AC84}"
+ },
+ "assetHint": "testdata/test_sponza_material_conversion_mat_roof.azmaterial"
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 2438226774
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{4310E0FE-532D-5436-A946-49B2E14B0375}"
+ }
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 1262202891
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{AF16DFCF-E1E9-57B9-8F01-A49AAC1962AE}"
+ }
+ }
+ },
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}",
+ "subId": 3591631827
+ }
+ },
+ "materialAsset": {
+ "assetId": {
+ "guid": "{B45DCFD4-6B12-5212-AB92-B64E064155CE}"
+ }
+ }
+ }
+ ]
+ ]
+ },
+ "Component_[16137637180608547307]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 16137637180608547307
+ },
+ "Component_[17072211258387308642]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 17072211258387308642
+ },
+ "Component_[2587501640342227295]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 2587501640342227295
+ },
+ "Component_[4820742733748380832]": {
+ "$type": "SelectionComponent",
+ "Id": 4820742733748380832
+ },
+ "Component_[5027382790057670521]": {
+ "$type": "EditorLockComponent",
+ "Id": 5027382790057670521
+ },
+ "Component_[7651519254420083868]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 7651519254420083868,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[1246125633405]"
+ },
+ {
+ "EntityId": "Entity_[1228945764221]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[1220355829629]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[1224650796925]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[1233240731517]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[1237535698813]",
+ "SortIndex": 5
+ },
+ {
+ "EntityId": "Entity_[1241830666109]",
+ "SortIndex": 6
+ }
+ ]
+ },
+ "Component_[9795135998007712828]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 9795135998007712828,
+ "Parent Entity": "ContainerEntity",
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 0.10000000149011612
+ ]
+ },
+ "Cached World Transform Parent": "ContainerEntity"
+ }
+ },
+ "IsDependencyReady": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion.fbx b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion.fbx
new file mode 100644
index 0000000000..638828984a
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9b936b72b5b45b52c188bf9f930d6066af65f0d79ff8abf5dc08927d97ac465e
+size 55264
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material
new file mode 100644
index 0000000000..cc2c9e785b
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material
@@ -0,0 +1,35 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "irradiance": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "opacity": {
+ "factor": 1.0
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material
new file mode 100644
index 0000000000..a4bfb73d12
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material
@@ -0,0 +1,35 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.0,
+ 1.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "irradiance": {
+ "color": [
+ 0.0,
+ 1.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "opacity": {
+ "factor": 1.0
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material
new file mode 100644
index 0000000000..fe9c54bc02
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material
@@ -0,0 +1,49 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.800000011920929,
+ 0.800000011920929,
+ 0.800000011920929,
+ 1.0
+ ],
+ "textureMap": "Textures/arch_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.885053813457489,
+ 0.801281750202179,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "Textures/arch_1k_metallic.png"
+ },
+ "normal": {
+ "textureMap": "Textures/arch_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "Textures/arch_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.050999999046325687,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "Textures/arch_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material
new file mode 100644
index 0000000000..a19afa33e2
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material
@@ -0,0 +1,54 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.800000011920929,
+ 0.800000011920929,
+ 0.800000011920929,
+ 1.0
+ ],
+ "textureMap": "Textures/bricks_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "normalMap": "Textures/bricks_1k_normal.jpg",
+ "roughness": 0.5
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.9703211784362793,
+ 0.9703211784362793,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "Textures/bricks_1k_metallic.png"
+ },
+ "normal": {
+ "textureMap": "Textures/bricks_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "Textures/bricks_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "algorithm": "ContactRefinement",
+ "factor": 0.03500000014901161,
+ "quality": "Medium",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "Textures/bricks_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material
new file mode 100644
index 0000000000..0c1208d8fb
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material
@@ -0,0 +1,51 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.800000011920929,
+ 0.800000011920929,
+ 0.800000011920929,
+ 1.0
+ ],
+ "textureMap": "Textures/floor_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "enable": true,
+ "influenceMap": "Textures/floor_1k_ao.png",
+ "normalMap": "Textures/floor_1k_normal.png",
+ "roughness": 0.25
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.9404135346412659,
+ 0.8688944578170776,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "Textures/floor_1k_normal.png"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "Textures/floor_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.012000000104308129,
+ "pdo": true,
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "Textures/floor_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material
new file mode 100644
index 0000000000..6aad4d644a
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material
@@ -0,0 +1,44 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.800000011920929,
+ 0.800000011920929,
+ 0.800000011920929,
+ 1.0
+ ],
+ "textureBlendMode": "Lerp",
+ "textureMap": "Textures/roof_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "metallic": {
+ "useTexture": false
+ },
+ "normal": {
+ "factor": 0.5,
+ "flipY": true,
+ "textureMap": "Textures/roof_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "Textures/roof_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "algorithm": "ContactRefinement",
+ "factor": 0.019999999552965165,
+ "quality": "Medium",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "Textures/roof_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material
new file mode 100644
index 0000000000..302589dc85
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material
@@ -0,0 +1,35 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.0,
+ 0.0,
+ 1.0,
+ 1.0
+ ]
+ },
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "irradiance": {
+ "color": [
+ 0.0,
+ 0.0,
+ 1.0,
+ 1.0
+ ]
+ },
+ "opacity": {
+ "factor": 1.0
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material
new file mode 100644
index 0000000000..5217a4e4be
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material
@@ -0,0 +1,35 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.800000011920929,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "opacity": {
+ "factor": 1.0
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material
new file mode 100644
index 0000000000..dba44f7b49
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material
@@ -0,0 +1,19 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "opacity": {
+ "factor": 1.0
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/TestData/white_latlong_iblskyboxcm.exr b/AutomatedTesting/Gem/Sponza/Assets/TestData/white_latlong_iblskyboxcm.exr
new file mode 100644
index 0000000000..56d66de7fc
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/TestData/white_latlong_iblskyboxcm.exr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d9c14dc81887be7647d9afa9e5481634eded0b1d0285b59bb76bb2a91326ca8a
+size 3369
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_ao.png
new file mode 100644
index 0000000000..8bc54f1e55
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9f21e251c50a657956ba8b401f102b8a3237a0c9c78eab0427332eb3ad8f5952
+size 281259
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_basecolor.png
new file mode 100644
index 0000000000..c8c21bbfea
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1b37ec99d6f8d26b8313315d801b9c378456ed9ec31cc2e0566c17ea3287b4fa
+size 1643629
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_height.png
new file mode 100644
index 0000000000..425f2f4a74
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:57657925d24ceb83881e614b3056b82dfc7197a3eebbb707a47f6721249d47c3
+size 108869
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_normal.jpg
new file mode 100644
index 0000000000..511d4412f8
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fc5a747fef8c4d830b72e250645925f41125ea75c18b6fb094cafe7b19850ca5
+size 70950
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_roughness.png
new file mode 100644
index 0000000000..eb9ddee5f2
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/arch_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8438ee2f06842f54e493fe1eda34b6ca39e6db19d2e0f21342f0f4e52fc3f1e3
+size 689118
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_ao.png
new file mode 100644
index 0000000000..6ca9f441b1
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0e59f003d7c8d26e7ec8460acec442f31cf7a06eb76008989c1ae6fccd8e2f15
+size 537441
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_basecolor.png
new file mode 100644
index 0000000000..a1684d404f
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b1c69c97ffc402d63130b680af75128b431504c4dedcbd15a5fbb41c142317fe
+size 1305835
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_height.png
new file mode 100644
index 0000000000..e03e062c98
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6650f449128dee04f513961b9d65d81105f2bd4fa580f4dbd9d6fb7b0af932bc
+size 275302
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_metallic.png
new file mode 100644
index 0000000000..c7bceabff2
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f482b7b57d180c6df76b750d05547151731fc6c61d2b9674f3b9daa5ab0ac225
+size 440844
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_normal.jpg
new file mode 100644
index 0000000000..29f27d2bd5
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:955f60ebbe10948e9d47cb90e0e0359c4ee26bd8e76d95292a673a2adb68f410
+size 82102
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_roughness.png
new file mode 100644
index 0000000000..689da83af7
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/background_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d5d0f40ab7b5153a44b87ee0c83c65ddc69cf845d16c8c9c3c2c043f85c1f04f
+size 542782
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_ao.png
new file mode 100644
index 0000000000..4b608a456f
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e3d169b73a2852e404eaa113e91d32b66e0d45a1b55598cc58f64e16c9565bf9
+size 729137
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_basecolor.png
new file mode 100644
index 0000000000..cf78cde324
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f34b38f6e205b6bffec72ddfd1305a66d0146d61bcc2ef901fd146a0ec2708de
+size 1934899
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_height.png
new file mode 100644
index 0000000000..b4f639e01d
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9745b60c53a4b9fa33a6a3713b9b06ec7679883524533de44628cfe0d26ae038
+size 377230
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_normal.jpg
new file mode 100644
index 0000000000..e097988246
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:03eba2d92ed70e04d5278152e945cf3a170750b71a04fd0f835fd6030b731720
+size 166767
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_roughness.png
new file mode 100644
index 0000000000..9573d6ca3e
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/bricks_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e35858a269d42405702102e7f7972a6330c3eaacfe637148c676e14d5c901c29
+size 784675
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_ao.png
new file mode 100644
index 0000000000..fd87eefdbd
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:22b80bfc1226fb587b230c51e9dac7fce6e295a4f0674326e96dc1232f40548b
+size 901463
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_basecolor.png
new file mode 100644
index 0000000000..161272e604
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b6743770a3428721a42a25a331fdb1e9895f71848c8215377e690b7cf9b7397f
+size 1756093
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_height.png
new file mode 100644
index 0000000000..36b0f61834
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:756105faa27e722d6cc5915f33f8bcf9fd7afc022c41276a8c0e3b1f122303a3
+size 501917
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_normal.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_normal.png
new file mode 100644
index 0000000000..870d38abe9
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_normal.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:08fa78ce8e7840189d22442ed46863b4eaf5a4a99c0655690a2c47b1b0ebd9ce
+size 1399902
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_roughness.png
new file mode 100644
index 0000000000..c5ce447017
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/ceiling_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4c24b269cd413b86da8cdd44bb639f3b95cfd1a8c53a3a941cb5a22a1042f85d
+size 689214
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_alpha.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_alpha.png
new file mode 100644
index 0000000000..13f145b733
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_alpha.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:30a1308326a5b0288147d0fb92230ebd1cef107180e38f7d5795bdc13a62e368
+size 3389
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_basecolor.png
new file mode 100644
index 0000000000..8c6384ed12
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:51c661aa2ee3fb4b4735005a71e734eb25e433ef73ded5131b110e4df2e94acf
+size 384316
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_normal.jpg
new file mode 100644
index 0000000000..4a5575731f
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/chain_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4619ec32e2de143db42639e0a4e0dfb174eb85057eb20f9e0d0af59e40977d9a
+size 11229
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_ao.png
new file mode 100644
index 0000000000..ec340ea1a0
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a505d441c79f3ab674fd5a6b879a430970400fb9f56b379dde00900da296a47e
+size 599094
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_basecolor.png
new file mode 100644
index 0000000000..b6f499c922
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:552608851205bde18e2bc2f7cbf475ccefbb182c7bfcb9430fa931da22363c80
+size 1836310
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_height.png
new file mode 100644
index 0000000000..704638918a
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:79f1c3430a193ee78c72b84a461612ffd79aa23374949af13a200ec9a301ba2d
+size 274678
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_normal.jpg
new file mode 100644
index 0000000000..dc90933767
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d280d5676ccfd6e4b6efdc53e828cc6823f44339a87ec9cee8a79d989ad46175
+size 127305
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_roughness.png
new file mode 100644
index 0000000000..a7221fc001
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnA_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5c4fb7c8012891c7af4ff371c8e6a8ef85ef1160a5b93012b964158ab48b8e4a
+size 760602
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_ao.png
new file mode 100644
index 0000000000..9cf3966fba
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a9fe904a58b248937adde2b48ba320da5139700d03e3183fbadfaaa0ac8bb6f5
+size 651508
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_basecolor.png
new file mode 100644
index 0000000000..8315166b41
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:37d461594dca7eb3da8f6f135511d38efc7c1f333afb98d286fb36a0034f3100
+size 2158620
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_height.png
new file mode 100644
index 0000000000..30bd2b0585
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8e95e08eed20fb4d44a6461f38f27f21fd3ae3f024550afed95ecf3bc30929b1
+size 297329
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_normal.jpg
new file mode 100644
index 0000000000..9299417a78
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1b00b684b53854ec24e86441e59220e6c49948429bd6fb7edab7058a11e8f92e
+size 139998
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_roughness.png
new file mode 100644
index 0000000000..4f4c674c6e
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnB_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5a6d428bf17ecee32d47c3feab27567a882b97dfa733dcf6ca8bf1b0bd0a025a
+size 908698
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_ao.png
new file mode 100644
index 0000000000..763aaedc50
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ab2c93badd7b72f45990c3859d6ddc7f2436a4aa5e93c0de65a139ea99120a97
+size 628789
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_basecolor.png
new file mode 100644
index 0000000000..f8f34d9232
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:97ec8bd597b0805a8a36bcd90ccdba2ae9430ed3a8631b0f7f87796fb2ceefc5
+size 2128105
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_height.png
new file mode 100644
index 0000000000..46a96abc24
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f8bbbc46f0f1ccfefec202b1e26ecbd418d3283037746bd63a892d1a930fb36d
+size 282637
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_normal.jpg
new file mode 100644
index 0000000000..270b9d12d1
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:44db84371fb81e1712b5f6aa9777fcfe76728dc25a51f0423e07c294b062c724
+size 137528
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_roughness.png
new file mode 100644
index 0000000000..8682bae62c
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/columnC_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c07d4a1af570a6b3817e97c92daa17f2593ea2b88e0e167ed43f7869b77971ab
+size 881064
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainBlue_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainBlue_1k_basecolor.png
new file mode 100644
index 0000000000..b6b394e860
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainBlue_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4310237ce83738635b3880ccd896f78ea2c70bebadd620cb6ffaaccc78ba7cbf
+size 9231896
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainGreen_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainGreen_1k_basecolor.png
new file mode 100644
index 0000000000..59e47b4e75
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainGreen_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e093cf9538bb40615d32bec6fa9c60d4308bc017c5ab02a7c388310159bc87fe
+size 8342440
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainRed_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainRed_1k_basecolor.png
new file mode 100644
index 0000000000..dc708deba0
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtainRed_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:465efab4da8d2b6698c83844d2fbe662e38a92f278aa27d356bbc1bca1e23f8b
+size 8879938
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_ao.png
new file mode 100644
index 0000000000..fcce123429
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b4faebdc849479a6b5d10db4cac8b6e9823bf447aeb4b45945f6acd43333def8
+size 4557863
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_height.png
new file mode 100644
index 0000000000..c983ec6ca8
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:064fbdba14e1ca04e438f4ec85d3f9a0fe3203620ee2a014113ec99454fbee65
+size 2709058
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_metallic.png
new file mode 100644
index 0000000000..cf63b48d04
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2c8159b1ad888143ec3cbf5e2535f87abbe238a1474619696355d11bc4e4bb49
+size 812014
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_normal.jpg
new file mode 100644
index 0000000000..d677f3650b
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0da92f21f46502a7c58c1a7ce7280354b4b41e553a5bf181d9962cacf8ed2191
+size 2327816
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_roughness.png
new file mode 100644
index 0000000000..60e2328213
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/curtain_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2a701afeb01e19efdff72393370c86ee148f6d81c1551bcbd211937df503be9b
+size 3694284
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_ao.png
new file mode 100644
index 0000000000..ed4d761fdb
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:368262bb832ab61b4649aadffe4158b64d46b70985e99106300fa0c7a7989c35
+size 666377
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_basecolor.png
new file mode 100644
index 0000000000..090f5eaef8
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2021b64706bc328959d521f056dcb9b9acf3062a5f9ad35da9e93b2351dcab97
+size 1371185
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_height.png
new file mode 100644
index 0000000000..8cfe37da45
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fdbb251cf483ffccc6cb1b344eba1b3262fa8087c37a36aa843f0c0e9d222f8f
+size 403018
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_metallic.png
new file mode 100644
index 0000000000..fe1ced8718
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8b67d6bea4c9fbc8412944b261a0c0f2dc1dc2e4103a6742bfb57d3c2d36429c
+size 499028
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_normal.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_normal.png
new file mode 100644
index 0000000000..be8a9932e9
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_normal.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae4c4d95bb92dfe25f5fba8564780c10ee663268360fccf1aa707b6c7c6a079c
+size 1121073
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_roughness.png
new file mode 100644
index 0000000000..dc633ad668
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/details_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5429087af4e8c33d19b2f13bd194c983bcdbe0c43165bea3dc0711874c2e50b9
+size 523398
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricBlue_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricBlue_1k_basecolor.png
new file mode 100644
index 0000000000..54373a9f98
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricBlue_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a1b6588cfdaa69b671ba879aa56712e88d6fcd74c160a751440441c9f18c727b
+size 2102967
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricGreen_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricGreen_1k_basecolor.png
new file mode 100644
index 0000000000..c77a44eca9
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricGreen_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:09c5ff45b66e5a65746c9bef6cbad8a897f58552b896ca6692e5498d91da71ab
+size 2166239
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricPurple_2k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricPurple_2k_basecolor.png
new file mode 100644
index 0000000000..c6ef949040
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricPurple_2k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:abd3b68e5c2982ef558593017bd4c7a6e3f23681827aa8b8e19dbe21564493e2
+size 1158454
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricRed_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricRed_1k_basecolor.png
new file mode 100644
index 0000000000..ab603245df
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabricRed_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:27ee68e81cb549f65e437debaf97f8eaa57a0f6975a15adee7f395a8bb6f0028
+size 2211896
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_ao.png
new file mode 100644
index 0000000000..f4ae398a33
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d3ddbc3833531aba81f9e16fcc1e9c88af1c8b329a8e8a4dfb6a9df08913085a
+size 977058
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_height.png
new file mode 100644
index 0000000000..f891a127a4
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f44f224b5a162f56ad0e8b931f781eed5fdbfd5a8b9b143aedb5ab69f5c3ca29
+size 564113
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_metallic.png
new file mode 100644
index 0000000000..7de5d2d8ce
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c456fec0df8f7c72680b855a2c8dd183014429e93bce68a4b2c38059a765c5b6
+size 126769
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_normal.jpg
new file mode 100644
index 0000000000..928bd38b87
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ee04cb3dc6a718510f662ae06e04fe8fe52230472f4a504a4a513ab3ab344790
+size 479191
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_roughness.png
new file mode 100644
index 0000000000..63fe4a8b2f
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/fabric_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4097ae87d2d55653c44efa6c607da9513f35057a2556f2f41cd412e1ef447dc4
+size 755476
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_ao.png
new file mode 100644
index 0000000000..ee5613ebcb
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9ce7d28833be640b1b4809040580b25bc5ed0caa10f9fcb8b7f28c5b952102d5
+size 689711
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_basecolor.png
new file mode 100644
index 0000000000..431210e5ee
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cd515352a030a1a8cf766dfbf9ff78ce27608349e7b661e48d5ec0b59c6d5a93
+size 1376341
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_height.png
new file mode 100644
index 0000000000..2dd9284a27
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:883499e06b12d8f25d3381954d56c34aefc9346a972c3a6a21ec5bb34029160c
+size 427516
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_metallic.png
new file mode 100644
index 0000000000..4ed2320ab8
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5291109e90b65a1581ea05046d01c6918c10c87805790af915d62e57acd2d29a
+size 1148004
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_normal.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_normal.png
new file mode 100644
index 0000000000..4913bf9352
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_normal.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:40b175859bf806237bee5ea72efc935b2dd28e3f6198d0604d5e474aea3725c7
+size 1215323
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_roughness.png
new file mode 100644
index 0000000000..f7ea0b06f0
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/flagpole_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:24fdf0849349745e7abdd0c42baa82ec2cc2d5b5a9c1a683bbf677a156251316
+size 1316334
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_ao.png
new file mode 100644
index 0000000000..2a3e9ac3db
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:04fba251cdae222d9f82b6cf6d1e8135ee1e066911967489f8c07ba20d076b14
+size 436348
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_basecolor.png
new file mode 100644
index 0000000000..3a79998f5b
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:80d91120f7213e835e342c150386e468865c5b68994915e9febf54c5cc83cf5a
+size 1883340
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_height.png
new file mode 100644
index 0000000000..f4fa9f2604
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bf6fd8259710d106daab4c459172ed3e98f29640d655b238a462cd36039be40a
+size 543386
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_metallic.png
new file mode 100644
index 0000000000..fdb6071b7c
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:89ef6e57efdf8c232b771a4ff988799f9f4ae5aefe2149578c9fa661b8f66cd9
+size 1062809
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_normal.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_normal.png
new file mode 100644
index 0000000000..2e24080b5c
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_normal.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9d1dd751aaed6dce2085e1a886be1d72845dd68df34d33cc8401618b03aed991
+size 1509938
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_roughness.png
new file mode 100644
index 0000000000..083cda1634
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/floor_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fb0a952c7976e646a5c14b222e23a8fde2510425567e12c73c6f6dc957108d0b
+size 1326209
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_ao.png
new file mode 100644
index 0000000000..9cc32ad4b4
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:686bb3c1274e5f48f9b390a67a6ce1e28b127546e1ae7a0d5d01152a2a7c537b
+size 519499
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_basecolor.png
new file mode 100644
index 0000000000..64092a39d1
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4c919b25301c084a2f4f03e5e80142d1ff72747bfb9cacb5332cdf80c4f62109
+size 1691028
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_height.png
new file mode 100644
index 0000000000..ad711b9144
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aedb902b3256c3741fc4fe176608b8b033a22b52c689bc87fe4796f1720d9d54
+size 605847
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_metallic.png
new file mode 100644
index 0000000000..7617fd3cae
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7f2564801b00ffa0ef05ca18ae2222abc257c2b940720b0a73c1c95bccf61c73
+size 1008929
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_normal.jpg
new file mode 100644
index 0000000000..648c37d670
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3ac327e8140639b4ef77a22f0ab1ecbc9738f84d6f0513b85a0fa2c18991ce5a
+size 117602
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_roughness.png
new file mode 100644
index 0000000000..faafa83d28
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/lion_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dee59798e56c34d7c014c6e608ba0090dea0a160c44a57b4c61ca587c69950d0
+size 1336005
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_ao.png
new file mode 100644
index 0000000000..58ec3d1bae
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:112bf756fab862ecf71c47dabbf601330e406ed9486500566a5fb012774af7a1
+size 845332
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_basecolor.png
new file mode 100644
index 0000000000..dd93a2c546
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:31c065bfd67e0b0ea459d81f134e9c1545f7601764c84544099d8c8f800f583c
+size 2403959
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_height.png
new file mode 100644
index 0000000000..b9b65fc1d2
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:77830ec6672f68124d974657537abce461519f9a0ae705bd79d60ebcf18f4f99
+size 765576
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_metallic.png
new file mode 100644
index 0000000000..a82a51c778
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bc4d854ae199fe8285c51b115005de50f35ddd5553c72867ff6a29e65454fc57
+size 1451908
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_normal.jpg
new file mode 100644
index 0000000000..ead40b8bd9
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:68b7477af3006f68f882ff0160f85b4e4b880737281b80f82de36a317c177f58
+size 557594
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_roughness.png
new file mode 100644
index 0000000000..b666c149ed
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/roof_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7b8af2651ce3a8a57244e174231b8ae954dff3bf7a70c024a8acfa9371768eac
+size 1820103
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_alpha.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_alpha.png
new file mode 100644
index 0000000000..c6c678849f
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_alpha.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1128834ae704583af703df8c63d1671f846d4a89927f90033573b9d8cd495bbd
+size 76001
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_basecolor.png
new file mode 100644
index 0000000000..dad1c18f0c
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae57e9e7fc478ee9ad28821af35c3266174795eb10293eb598353efe72c85cc7
+size 430161
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_height.png
new file mode 100644
index 0000000000..156e5e6d44
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3f6727b858621faaa5930a974e7d60aa66cf3f694234ccfec4e80aeed033b2f1
+size 149055
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_metallic.png
new file mode 100644
index 0000000000..8b6340bcdd
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c67dadbce8c39c43e12137a48b662e2f71def0a1bcdc197a6ba87ecc391c0334
+size 244023
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_normal.jpg
new file mode 100644
index 0000000000..e928f2bb36
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f3e0f3396a78712d283247a9c0fc539a671fc8ec01c60f98d48d9a129cfad58f
+size 10762
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_roughness.png
new file mode 100644
index 0000000000..8f319021a4
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/thorn_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:00295c69a981a7b0af074267062693ae9c5f698d295b96f884729fb9af109385
+size 295295
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_ao.png
new file mode 100644
index 0000000000..42330f43fc
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:342c4b0811833ae0826b7c10e4987f43ff10df38ee7df1719e540f35d2d3499e
+size 345240
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_basecolor.png
new file mode 100644
index 0000000000..d6fbff7d0e
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6b5fb7c0472b9643cfd619d9e6c5527899492e7746147a2d975406d25374be78
+size 1314027
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_height.png
new file mode 100644
index 0000000000..ac9285bca7
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:caaa5ec46d6059ae3b245e9f7eadf886c4290c89958a13583dc4bc9293495cb0
+size 398025
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_metallic.png
new file mode 100644
index 0000000000..ede79d9158
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:62832e5e067086c97c46fee31baab1cb6dd2c807af685574a90c0afa8088ee43
+size 1401314
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_normal.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_normal.png
new file mode 100644
index 0000000000..4645b54d64
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_normal.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f5d23737cc43a2e445dffd4221f8236e61dc553184c2a63b9d5c71d066d84573
+size 1147257
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_roughness.png
new file mode 100644
index 0000000000..235780d752
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseHanging_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:72ff5ec3b6a469d86f34e93d9fb143fe4846588e44f0e851e509be88745a25aa
+size 1365617
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vasePlant_1k_alpha.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vasePlant_1k_alpha.png
new file mode 100644
index 0000000000..8556f67471
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vasePlant_1k_alpha.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:85ee26dcfdf8cb3ddcd378e92fd52e313ee23a58f7cc5a37556d96556986ba0b
+size 62658
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vasePlant_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vasePlant_1k_basecolor.png
new file mode 100644
index 0000000000..5f6cd0377f
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vasePlant_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05d7a544ccf6b04dcfb37411927a79e8f4b2e6224b09651f92885604d825dc9c
+size 860074
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_ao.png
new file mode 100644
index 0000000000..c865df4c29
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a63c38ed593010cd495256c1b2b5f2d39659e0d4e9c699dd97a2d0a5582a65d7
+size 255623
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_basecolor.png
new file mode 100644
index 0000000000..942b1a859a
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f438726b2dd4107d85b2542476243bc6977362a4865a5c21916d186fdf0eb5f4
+size 1846782
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_height.png
new file mode 100644
index 0000000000..d0aaaa46c1
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6ddea2c560e2c86d58722b3728e0018c41b20fb64d543bd5241bc7de482bfcae
+size 584961
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_metallic.png
new file mode 100644
index 0000000000..b040d20cd6
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:12e3d690707f3fad9c26c402329ba1c1c7e751b6c38e11d965a1cfd8f67f61c3
+size 1143341
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_normal.jpg
new file mode 100644
index 0000000000..866c9e0907
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3cd9f31741ebd52c9ddcc65b3d33b875b39af16379fcaed35fcb662a12c382cf
+size 81207
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_roughness.png
new file mode 100644
index 0000000000..05e201d968
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vaseRound_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f7a398b8c249c20d199d53f203df79826a63d1f56d62c28403ce9e52065fb49f
+size 1397051
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_ao.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_ao.png
new file mode 100644
index 0000000000..53e7968cbf
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_ao.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3740f6f1cac7251ee455c24498e0026da033d0c4994960a99cad4c78f0edcccb
+size 639510
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_basecolor.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_basecolor.png
new file mode 100644
index 0000000000..76c61bfe2e
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3b6b3d8fe5c470adbff0f9d9063c7efa1921491693a34b1fb383a9a60d7d7a9c
+size 1838562
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_height.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_height.png
new file mode 100644
index 0000000000..50a9cab822
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_height.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bc63680f8772effdad47e0a04def2bd8b6ec1dae8e8e7bfce2a11409a0c767a8
+size 572074
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_metallic.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_metallic.png
new file mode 100644
index 0000000000..d847f3d4a3
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_metallic.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4d90cac110f7f129df7bd37d9c5e735be8f253be9e3798c3e2932ba351b8d7b5
+size 1044158
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_normal.jpg b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_normal.jpg
new file mode 100644
index 0000000000..559222c38c
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_normal.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:387a9873c1ec3ebda366c19b94ca0c553f8015f7b48dd4adf8a53d3d83f3ad3d
+size 217939
diff --git a/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_roughness.png b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_roughness.png
new file mode 100644
index 0000000000..999fdab25e
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/Textures/vase_1k_roughness.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5e5b7e0a1b62aa2b3f270e2fd4be4acb6a9b5c1c45f6eb83fa177c777e9f14b8
+size 1317066
diff --git a/AutomatedTesting/Gem/Sponza/Assets/license.txt b/AutomatedTesting/Gem/Sponza/Assets/license.txt
new file mode 100644
index 0000000000..e303d8c767
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/license.txt
@@ -0,0 +1,8 @@
+The content in this gem "O3DE\Gems\AtomContent\Sponza" is ported
+from the original source, and modified for the O3DE Engine and Atom Renderer.
+
+The original "Crytek Sponza" scene data can be downloaded from the
+"McGuire Computer Graphics Archive": https://casual-effects.com/data/
+
+The original content is under the "CC BY 3.0" License:
+https://creativecommons.org/licenses/by/3.0/
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker.fbx b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker.fbx
new file mode 100644
index 0000000000..8064e80546
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4284aa2655fefad45723d899824b99a732f8b1d5b231bb8b26734cae251e15d0
+size 23216
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material
new file mode 100644
index 0000000000..c8e9f1f8f7
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/lightBlocker_lambert1.material
@@ -0,0 +1,19 @@
+{
+ "description": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "parentMaterial": "",
+ "propertyLayoutVersion": 3,
+ "properties": {
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "opacity": {
+ "factor": 1.0
+ }
+ }
+}
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sphere.fbx b/AutomatedTesting/Gem/Sponza/Assets/objects/sphere.fbx
new file mode 100644
index 0000000000..734dbb2843
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sphere.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67a3f676de88eb967df30d526a810e1c569a611904ff1a85628b66e75c4181f0
+size 47168
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sphereTwo.fbx b/AutomatedTesting/Gem/Sponza/Assets/objects/sphereTwo.fbx
new file mode 100644
index 0000000000..99c96e832a
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sphereTwo.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a3abce1aadb4f505bf2eebbf8256598f9dab4cd5e9239e9a1523a70b4302912d
+size 47184
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza.fbx b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza.fbx
new file mode 100644
index 0000000000..a38f51750a
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6a8e686bd64cda37e8b27adcb691a846e62bcea6491547d53334ef4ed5424493
+size 21247456
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_arch.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_arch.material
new file mode 100644
index 0000000000..6518091265
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_arch.material
@@ -0,0 +1,40 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/arch_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.2663614749908447,
+ 0.2383916974067688,
+ 0.18117037415504456,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/arch_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/arch_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.050999999046325684,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/arch_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_background.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_background.material
new file mode 100644
index 0000000000..2fd7ed39cc
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_background.material
@@ -0,0 +1,45 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/background_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "normalMap": "../Textures/background_1k_normal.jpg",
+ "roughness": 0.4000000059604645
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.19806210696697235,
+ 0.1746547669172287,
+ 0.16513313353061676,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/background_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/background_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.03099999949336052,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/background_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_bricks.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_bricks.material
new file mode 100644
index 0000000000..52fdf9e3a2
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_bricks.material
@@ -0,0 +1,45 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/bricks_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "normalMap": "../Textures/bricks_1k_normal.jpg",
+ "roughness": 0.5
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.27467766404151917,
+ 0.27467766404151917,
+ 0.270496666431427,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/bricks_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/bricks_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "algorithm": "ContactRefinement",
+ "factor": 0.03500000014901161,
+ "quality": "Medium",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/bricks_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_ceiling.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_ceiling.material
new file mode 100644
index 0000000000..10f5a01a8e
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_ceiling.material
@@ -0,0 +1,36 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/ceiling_1k_basecolor.png"
+ },
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "irradiance": {
+ "color": [
+ 0.29176774621009827,
+ 0.27888914942741394,
+ 0.2501564025878906,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/ceiling_1k_normal.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "roughness": {
+ "textureMap": "../Textures/ceiling_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_chain.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_chain.material
new file mode 100644
index 0000000000..caf03bd3ce
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_chain.material
@@ -0,0 +1,35 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureBlendMode": "Lerp",
+ "textureMap": "../Textures/chain_basecolor.png"
+ },
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "general": {
+ "doubleSided": true
+ },
+ "metallic": {
+ "factor": 0.8899999856948853
+ },
+ "normal": {
+ "textureMap": "../Textures/chain_normal.jpg"
+ },
+ "opacity": {
+ "alphaSource": "Split",
+ "factor": 1.0,
+ "mode": "Cutout",
+ "textureMap": "../Textures/chain_alpha.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columna.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columna.material
new file mode 100644
index 0000000000..15c3fec349
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columna.material
@@ -0,0 +1,45 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/columnA_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "normalMap": "../Textures/columnA_1k_normal.jpg",
+ "roughness": 0.30000001192092896
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.8964369893074036,
+ 0.8264744281768799,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/columnA_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/columnA_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.017000000923871994,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/columnA_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnb.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnb.material
new file mode 100644
index 0000000000..e13f96b2bb
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnb.material
@@ -0,0 +1,45 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/columnB_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "normalMap": "../Textures/columnB_1k_normal.jpg",
+ "roughness": 0.30000001192092896
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.41788357496261597,
+ 0.40723279118537903,
+ 0.4286869466304779,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/columnB_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/columnB_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.020999999716877937,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/columnB_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnc.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnc.material
new file mode 100644
index 0000000000..479692848a
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_columnc.material
@@ -0,0 +1,45 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/columnC_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "normalMap": "../Textures/columnC_1k_normal.jpg",
+ "roughness": 0.30000001192092896
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.32314029335975647,
+ 0.29176774621009827,
+ 0.24228274822235107,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/columnC_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/columnC_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.014000000432133675,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/columnC_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainblue.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainblue.material
new file mode 100644
index 0000000000..50fd968956
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainblue.material
@@ -0,0 +1,52 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "textureMap": "../Textures/curtainBlue_1k_basecolor.png"
+ },
+ "emissive": {
+ "color": [
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0
+ ]
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.0,
+ 0.14901961386203766,
+ 1.0,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "../Textures/curtain_metallic.png"
+ },
+ "normal": {
+ "factor": 0.5,
+ "textureMap": "../Textures/curtain_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/curtain_ao.png"
+ },
+ "roughness": {
+ "textureMap": "../Textures/curtain_roughness.png"
+ },
+ "specularF0": {
+ "enableMultiScatterCompensation": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtaingreen.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtaingreen.material
new file mode 100644
index 0000000000..6e70a42d24
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtaingreen.material
@@ -0,0 +1,38 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/curtainGreen_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.0,
+ 0.15294118225574493,
+ 0.0,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "../Textures/curtain_metallic.png"
+ },
+ "normal": {
+ "factor": 0.5,
+ "textureMap": "../Textures/curtain_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/curtain_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "roughness": {
+ "textureMap": "../Textures/curtain_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainred.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainred.material
new file mode 100644
index 0000000000..8233633310
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_curtainred.material
@@ -0,0 +1,43 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/curtainRed_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.41960784792900085,
+ 0.003921568859368563,
+ 0.003921568859368563,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "../Textures/curtain_metallic.png"
+ },
+ "normal": {
+ "textureMap": "../Textures/curtain_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/curtain_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "roughness": {
+ "textureMap": "../Textures/curtain_roughness.png"
+ },
+ "uv": {
+ "center": [
+ 16.0,
+ 0.0
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_details.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_details.material
new file mode 100644
index 0000000000..b66d8fa679
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_details.material
@@ -0,0 +1,39 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/details_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "normalMap": "../Textures/details_1k_normal.png",
+ "roughness": 0.25
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "metallic": {
+ "textureMap": "../Textures/details_1k_metallic.png"
+ },
+ "normal": {
+ "textureMap": "../Textures/details_1k_normal.png"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/details_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.02500000037252903,
+ "pdo": true,
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/details_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricblue.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricblue.material
new file mode 100644
index 0000000000..19ce3a6839
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricblue.material
@@ -0,0 +1,39 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/fabricBlue_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.0,
+ 0.15049973130226135,
+ 1.0,
+ 1.0
+ ],
+ "factor": 0.30000001192092896
+ },
+ "metallic": {
+ "textureMap": "../Textures/fabric_metallic.png"
+ },
+ "normal": {
+ "factor": 0.5,
+ "textureMap": "../Textures/fabric_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/fabric_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "roughness": {
+ "textureMap": "../Textures/fabric_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricgreen.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricgreen.material
new file mode 100644
index 0000000000..94b8270fef
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricgreen.material
@@ -0,0 +1,39 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/fabricGreen_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.0,
+ 0.15292592346668243,
+ 0.0012207217514514923,
+ 1.0
+ ],
+ "factor": 0.30000001192092896
+ },
+ "metallic": {
+ "textureMap": "../Textures/fabric_metallic.png"
+ },
+ "normal": {
+ "factor": 0.5,
+ "textureMap": "../Textures/fabric_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/fabric_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "roughness": {
+ "textureMap": "../Textures/fabric_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricred.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricred.material
new file mode 100644
index 0000000000..7bd2ecddd0
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_fabricred.material
@@ -0,0 +1,39 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/fabricRed_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.42040130496025085,
+ 0.004654001910239458,
+ 0.0037232013419270515,
+ 1.0
+ ],
+ "factor": 0.30000001192092896
+ },
+ "metallic": {
+ "textureMap": "../Textures/fabric_metallic.png"
+ },
+ "normal": {
+ "factor": 0.5,
+ "textureMap": "../Textures/fabric_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/fabric_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "roughness": {
+ "textureMap": "../Textures/fabric_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_flagpole.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_flagpole.material
new file mode 100644
index 0000000000..aca6c05d29
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_flagpole.material
@@ -0,0 +1,46 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/flagpole_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.6520485281944275,
+ 0.7122911214828491,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "../Textures/flagpole_1k_metallic.png"
+ },
+ "normal": {
+ "textureMap": "../Textures/flagpole_1k_normal.png"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/flagpole_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.014000000432133675,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/flagpole_1k_roughness.png"
+ },
+ "specularF0": {
+ "enableMultiScatterCompensation": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_floor.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_floor.material
new file mode 100644
index 0000000000..b75143326d
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_floor.material
@@ -0,0 +1,44 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/floor_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "influenceMap": "../Textures/floor_1k_ao.png",
+ "normalMap": "../Textures/floor_1k_normal.png",
+ "roughness": 0.25
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.9404135346412659,
+ 0.8688944578170776,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/floor_1k_normal.png"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/floor_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.012000000104308128,
+ "pdo": true,
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/floor_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_leaf.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_leaf.material
new file mode 100644
index 0000000000..51638d6d94
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_leaf.material
@@ -0,0 +1,43 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/thorn_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.05000000074505806,
+ "normalMap": "../Textures/thorn_normal.jpg",
+ "roughness": 0.10000000149011612
+ },
+ "general": {
+ "applySpecularAA": true,
+ "doubleSided": true
+ },
+ "irradiance": {
+ "color": [
+ 0.46506446599960327,
+ 1.0,
+ 0.3944609761238098,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/thorn_normal.jpg"
+ },
+ "opacity": {
+ "alphaSource": "Split",
+ "factor": 0.20000000298023224,
+ "mode": "Cutout",
+ "textureMap": "../Textures/thorn_alpha.png"
+ },
+ "parallax": {
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/thorn_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_lion.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_lion.material
new file mode 100644
index 0000000000..eee41e9c13
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_lion.material
@@ -0,0 +1,36 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/lion_1k_basecolor.png"
+ },
+ "emissive": {
+ "color": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ "irradiance": {
+ "color": [
+ 0.5583428740501404,
+ 0.496940553188324,
+ 0.4125429093837738,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/lion_1k_normal.jpg"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "roughness": {
+ "textureMap": "../Textures/lion_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_roof.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_roof.material
new file mode 100644
index 0000000000..fec7bb1e34
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_roof.material
@@ -0,0 +1,47 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureBlendMode": "Lerp",
+ "textureMap": "../Textures/roof_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.29613184928894043,
+ 0.3324483036994934,
+ 0.45078203082084656,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "../Textures/roof_1k_metallic.png",
+ "useTexture": false
+ },
+ "normal": {
+ "factor": 0.5,
+ "flipY": true,
+ "textureMap": "../Textures/roof_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/roof_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "algorithm": "ContactRefinement",
+ "factor": 0.019999999552965164,
+ "quality": "Medium",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/roof_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vase.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vase.material
new file mode 100644
index 0000000000..da7a9de3a8
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vase.material
@@ -0,0 +1,46 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/vase_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 1.0,
+ 0.8713664412498474,
+ 0.6021667718887329,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "../Textures/vase_1k_metallic.png"
+ },
+ "normal": {
+ "textureMap": "../Textures/vase_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/vase_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.027000000700354576,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/vase_1k_roughness.png"
+ },
+ "specularF0": {
+ "enableMultiScatterCompensation": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vasehanging.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vasehanging.material
new file mode 100644
index 0000000000..bda7aad38c
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vasehanging.material
@@ -0,0 +1,43 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/vaseHanging_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.765606164932251,
+ 1.0,
+ 0.7052567601203918,
+ 1.0
+ ]
+ },
+ "metallic": {
+ "textureMap": "../Textures/vaseHanging_1k_metallic.png"
+ },
+ "normal": {
+ "textureMap": "../Textures/vaseHanging_1k_normal.png"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/vaseHanging_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.04600000008940697,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/vaseHanging_1k_roughness.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseplant.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseplant.material
new file mode 100644
index 0000000000..5546daa0e0
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseplant.material
@@ -0,0 +1,36 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "color": [
+ 0.800000011920929,
+ 0.800000011920929,
+ 0.800000011920929,
+ 1.0
+ ],
+ "textureBlendMode": "Lerp",
+ "textureMap": "../Textures/vasePlant_1k_basecolor.png"
+ },
+ "general": {
+ "applySpecularAA": true,
+ "doubleSided": true
+ },
+ "irradiance": {
+ "color": [
+ 0.09086747467517853,
+ 0.4111391007900238,
+ 0.0474097803235054,
+ 1.0
+ ]
+ },
+ "opacity": {
+ "alphaSource": "Split",
+ "factor": 0.23999999463558197,
+ "mode": "Cutout",
+ "textureMap": "../Textures/vasePlant_1k_alpha.png"
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseround.material b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseround.material
new file mode 100644
index 0000000000..268e3ab613
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/objects/sponza_mat_vaseround.material
@@ -0,0 +1,49 @@
+{
+ "description": "",
+ "parentMaterial": "",
+ "materialType": "Materials/Types/StandardPBR.materialtype",
+ "materialTypeVersion": 4,
+ "properties": {
+ "baseColor": {
+ "textureMap": "../Textures/vaseRound_1k_basecolor.png"
+ },
+ "clearCoat": {
+ "factor": 0.5,
+ "influenceMap": "../Textures/vaseRound_1k_ao.png",
+ "normalMap": "../Textures/vaseRound_1k_normal.jpg",
+ "roughness": 0.25
+ },
+ "general": {
+ "applySpecularAA": true
+ },
+ "irradiance": {
+ "color": [
+ 0.46933698654174805,
+ 0.3824063539505005,
+ 0.47861447930336,
+ 1.0
+ ]
+ },
+ "normal": {
+ "textureMap": "../Textures/vaseRound_1k_normal.jpg"
+ },
+ "occlusion": {
+ "diffuseTextureMap": "../Textures/vaseRound_1k_ao.png"
+ },
+ "opacity": {
+ "factor": 1.0
+ },
+ "parallax": {
+ "factor": 0.019999999552965164,
+ "pdo": true,
+ "quality": "High",
+ "useTexture": false
+ },
+ "roughness": {
+ "textureMap": "../Textures/vaseRound_1k_roughness.png"
+ },
+ "specularF0": {
+ "enableMultiScatterCompensation": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Assets/slices/lightingGRP.slice b/AutomatedTesting/Gem/Sponza/Assets/slices/lightingGRP.slice
new file mode 100644
index 0000000000..97f3b3bb55
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Assets/slices/lightingGRP.slice
@@ -0,0 +1,962 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Gems/AssetMemoryAnalyzer/CMakeLists.txt b/AutomatedTesting/Gem/Sponza/CMakeLists.txt
similarity index 50%
rename from Gems/AssetMemoryAnalyzer/CMakeLists.txt
rename to AutomatedTesting/Gem/Sponza/CMakeLists.txt
index 2bb380fae3..2d625a71b6 100644
--- a/Gems/AssetMemoryAnalyzer/CMakeLists.txt
+++ b/AutomatedTesting/Gem/Sponza/CMakeLists.txt
@@ -5,5 +5,7 @@
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
-
-add_subdirectory(Code)
+# This will export its "SourcePaths" to the generated "cmake_dependencies..assetbuilder.setreg"
+if(PAL_TRAIT_BUILD_HOST_TOOLS)
+ ly_create_alias(NAME AtomContent_Sponza.Builders NAMESPACE Gem)
+endif()
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Registry/AssetProcessorPlatformConfig.setreg b/AutomatedTesting/Gem/Sponza/Registry/AssetProcessorPlatformConfig.setreg
new file mode 100644
index 0000000000..206a0a2a87
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Registry/AssetProcessorPlatformConfig.setreg
@@ -0,0 +1,14 @@
+{
+ "Amazon": {
+ "AssetProcessor": {
+ "Settings": {
+ // ------------------------------------------------------------------------------
+ // Sample Gems, Block source folders
+ // ------------------------------------------------------------------------------
+ "Exclude Work In Progress Folders": {
+ "pattern": "(^|.+/).[Ss]rc(/.*)?$"
+ }
+ }
+ }
+ }
+}
diff --git a/AutomatedTesting/Gem/Sponza/Tools/Launch_Cmd.bat b/AutomatedTesting/Gem/Sponza/Tools/Launch_Cmd.bat
new file mode 100644
index 0000000000..0b94be5bea
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Tools/Launch_Cmd.bat
@@ -0,0 +1,43 @@
+@echo off
+:: Keep changes local
+SETLOCAL enableDelayedExpansion
+
+REM
+REM Copyright (c) Contributors to the Open 3D Engine Project
+REM
+REM SPDX-License-Identifier: Apache-2.0 OR MIT
+REM For complete copyright and license terms please see the LICENSE at the root of this distribution.
+REM
+REM
+
+:: Set up and start a O3DE CMD prompt
+:: Sets up the current (DCC) Project_Env,
+:: Puts you in the CMD within the dev environment
+
+:: Set up window
+TITLE O3DE DCC Scripting Interface Cmd
+:: Use obvious color to prevent confusion (Grey with Yellow Text)
+COLOR 8E
+
+%~d0
+cd %~dp0
+PUSHD %~dp0
+
+CALL %~dp0\Project_Env.bat
+
+echo.
+echo _____________________________________________________________________
+echo.
+echo ~ O3DE %O3DE_PROJECT% Asset Gem CMD ...
+echo _____________________________________________________________________
+echo.
+
+:: Create command prompt with environment
+CALL %windir%\system32\cmd.exe
+
+ENDLOCAL
+
+:: Return to starting directory
+POPD
+
+:END_OF_FILE
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/Tools/Launch_Maya.bat b/AutomatedTesting/Gem/Sponza/Tools/Launch_Maya.bat
new file mode 100644
index 0000000000..0af25905a0
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Tools/Launch_Maya.bat
@@ -0,0 +1,66 @@
+@echo off
+
+REM
+REM Copyright (c) Contributors to the Open 3D Engine Project.
+REM For complete copyright and license terms please see the LICENSE at the root of this distribution.
+REM
+REM SPDX-License-Identifier: Apache-2.0 OR MIT
+REM
+REM
+
+%~d0
+cd %~dp0
+PUSHD %~dp0
+
+echo ________________________________
+echo ~ calling PROJ_Env.bat
+
+:: Keep changes local
+SETLOCAL enableDelayedExpansion
+
+:: PY version Major
+IF "%DCCSI_PY_VERSION_MAJOR%"=="" (set DCCSI_PY_VERSION_MAJOR=2)
+echo DCCSI_PY_VERSION_MAJOR = %DCCSI_PY_VERSION_MAJOR%
+
+:: PY version Major
+IF "%DCCSI_PY_VERSION_MINOR%"=="" (set DCCSI_PY_VERSION_MINOR=7)
+echo DCCSI_PY_VERSION_MINOR = %DCCSI_PY_VERSION_MINOR%
+
+:: Maya Version
+IF "%DCCSI_MAYA_VERSION%"=="" (set DCCSI_MAYA_VERSION=2020)
+echo DCCSI_MAYA_VERSION = %DCCSI_MAYA_VERSION%
+
+:: if a local customEnv.bat exists, run it
+IF EXIST "%~dp0Project_Env.bat" CALL %~dp0Project_Env.bat
+
+echo ________________________________
+echo Launching Maya %DCCSI_MAYA_VERSION% for O3DE: %O3DE_PROJECT%...
+
+:::: Set Maya native project acess to this project
+::set MAYA_PROJECT=%LY_PROJECT%
+::echo MAYA_PROJECT = %MAYA_PROJECT%
+
+:: DX11 Viewport
+Set MAYA_VP2_DEVICE_OVERRIDE = VirtualDeviceDx11
+
+:: Default to the right version of Maya if we can detect it... and launch
+echo MAYA_BIN_PATH = %MAYA_BIN_PATH%
+
+IF EXIST "%MAYA_BIN_PATH%\Maya.exe" (
+ start "" "%MAYA_BIN_PATH%\Maya.exe" %*
+) ELSE (
+ Where maya.exe 2> NUL
+ IF ERRORLEVEL 1 (
+ echo Maya.exe could not be found
+ pause
+ ) ELSE (
+ start "" Maya.exe %*
+ )
+)
+
+:: Return to starting directory
+POPD
+
+:END_OF_FILE
+
+exit /b 0
diff --git a/AutomatedTesting/Gem/Sponza/Tools/Project_Env.bat b/AutomatedTesting/Gem/Sponza/Tools/Project_Env.bat
new file mode 100644
index 0000000000..ddf934d206
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Tools/Project_Env.bat
@@ -0,0 +1,107 @@
+@echo off
+
+REM
+REM Copyright (c) Contributors to the Open 3D Engine Project
+REM
+REM SPDX-License-Identifier: Apache-2.0 OR MIT
+REM For complete copyright and license terms please see the LICENSE at the root of this distribution.
+REM
+REM
+
+:: Sets up environment for O3DE DCC tools and code access
+
+:: Set up window
+TITLE O3DE Asset Gem
+:: Use obvious color to prevent confusion (Grey with Yellow Text)
+COLOR 8E
+
+:: Skip initialization if already completed
+IF "%O3DE_PROJ_ENV_INIT%"=="1" GOTO :END_OF_FILE
+
+:: Store current dir
+%~d0
+cd %~dp0
+PUSHD %~dp0
+
+:: Put you project env vars and overrides in this file
+
+:: chanhe the relative path up to dev
+set ABS_PATH=%~dp0
+
+:: project name as a str tag
+IF "%O3DE_PROJECT%"=="" (
+ for %%I in ("%~dp0.") do for %%J in ("%%~dpI.") do set O3DE_PROJECT=%%~nxJ
+ )
+
+echo.
+echo _____________________________________________________________________
+echo.
+echo ~ Setting up O3DE %O3DE_PROJECT% Environment ...
+echo _____________________________________________________________________
+echo.
+echo O3DE_PROJECT = %O3DE_PROJECT%
+
+:: if the user has set up a custom env call it
+:: this should allow the user to locally
+:: set env hooks like O3DE_DEV or O3DE_PROJECT_PATH
+IF EXIST "%~dp0User_Env.bat" CALL %~dp0User_Env.bat
+echo O3DE_DEV = %O3DE_DEV%
+
+:: Constant Vars (Global)
+:: global debug flag (propogates)
+:: The intent here is to set and globally enter a debug mode
+IF "%DCCSI_GDEBUG%"=="" (set DCCSI_GDEBUG=false)
+echo DCCSI_GDEBUG = %DCCSI_GDEBUG%
+:: initiates earliest debugger connection
+:: we support attaching to WingIDE... PyCharm and VScode in the future
+IF "%DCCSI_DEV_MODE%"=="" (set DCCSI_DEV_MODE=false)
+echo DCCSI_DEV_MODE = %DCCSI_DEV_MODE%
+:: sets debugger, options: WING, PYCHARM
+IF "%DCCSI_GDEBUGGER%"=="" (set DCCSI_GDEBUGGER=WING)
+echo DCCSI_GDEBUGGER = %DCCSI_GDEBUGGER%
+:: Default level logger will handle
+:: Override this to control the setting
+:: CRITICAL:50
+:: ERROR:40
+:: WARNING:30
+:: INFO:20
+:: DEBUG:10
+:: NOTSET:0
+IF "%DCCSI_LOGLEVEL%"=="" (set DCCSI_LOGLEVEL=20)
+echo DCCSI_LOGLEVEL = %DCCSI_LOGLEVEL%
+
+:: Override the default maya version
+IF "%DCCSI_MAYA_VERSION%"=="" (set DCCSI_MAYA_VERSION=2020)
+echo DCCSI_MAYA_VERSION = %DCCSI_MAYA_VERSION%
+
+:: O3DE_PROJECT_PATH is ideally treated as a full path in the env launchers
+:: do to changes in o3de, external engine/project/gem folder structures, etc.
+IF "%O3DE_PROJECT_PATH%"=="" (
+ for %%i in ("%~dp0..") do set "O3DE_PROJECT_PATH=%%~fi"
+ )
+echo O3DE_PROJECT_PATH = %O3DE_PROJECT_PATH%
+
+:: Change to root O3DE dev dir
+IF "%O3DE_DEV%"=="" echo ~ You must set O3DE_DEV in a User_Env.bat to match your local engine repo!
+IF "%O3DE_DEV%"=="" echo ~ Using default O3DE_DEV=C:\Depot\o3de-engine
+IF "%O3DE_DEV%"=="" (set O3DE_DEV=C:\Depot\o3de-engine)
+echo O3DE_DEV = %O3DE_DEV%
+
+CALL %O3DE_DEV%\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface\Tools\Dev\Windows\Env_Maya.bat
+
+:: Restore original directory
+popd
+
+:: Change to root dir
+CD /D %ABS_PATH%
+
+::ENDLOCAL
+
+:: Set flag so we don't initialize dccsi environment twice
+SET O3DE_PROJ_ENV_INIT=1
+GOTO END_OF_FILE
+
+:: Return to starting directory
+POPD
+
+:END_OF_FILE
diff --git a/AutomatedTesting/Gem/Sponza/Tools/User_Env.bat.template b/AutomatedTesting/Gem/Sponza/Tools/User_Env.bat.template
new file mode 100644
index 0000000000..d108f30a5b
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/Tools/User_Env.bat.template
@@ -0,0 +1,42 @@
+@echo off
+
+REM
+REM Copyright (c) Contributors to the Open 3D Engine Project
+REM
+REM SPDX-License-Identifier: Apache-2.0 OR MIT
+REM For complete copyright and license terms please see the LICENSE at the root of this distribution.
+REM
+REM
+
+:: copy this file, rename to User_Env.bat (remove .template)
+:: use this file to override any local properties that differ from base
+
+:: Skip initialization if already completed
+IF "%O3DE_USER_ENV_INIT%"=="1" GOTO :END_OF_FILE
+
+:: Store current dir
+%~d0
+cd %~dp0
+PUSHD %~dp0
+
+SET O3DE_DEV=C:\Depot\o3de-engine
+::SET OCIO_APPS=C:\Depot\o3de-engine\Tools\ColorGrading\ocio\build\src\apps
+SET TAG_LY_BUILD_PATH=build
+SET DCCSI_GDEBUG=True
+SET DCCSI_DEV_MODE=True
+
+set DCCSI_MAYA_VERSION=2020
+
+:: set the your user name here for windows path
+SET TAG_USERNAME=NOT_SET
+SET DCCSI_PY_REV=rev1
+SET DCCSI_PY_PLATFORM=windows
+
+:: Set flag so we don't initialize dccsi environment twice
+SET O3DE_USER_ENV_INIT=1
+GOTO END_OF_FILE
+
+:: Return to starting directory
+POPD
+
+:END_OF_FILE
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Sponza/gem.json b/AutomatedTesting/Gem/Sponza/gem.json
new file mode 100644
index 0000000000..68749cd5f4
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/gem.json
@@ -0,0 +1,17 @@
+{
+ "gem_name": "Sponza",
+ "display_name": "Sponza",
+ "license": "Apache-2.0 Or MIT",
+ "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
+ "origin": "Open 3D Engine - o3de.org",
+ "type": "Asset",
+ "summary": "A standard test scene for Global Illumination (forked from crytek sponza scene)",
+ "canonical_tags": [
+ "Gem"
+ ],
+ "user_tags": [
+ "Assets"
+ ],
+ "requirements": "",
+ "dependencies": []
+}
diff --git a/AutomatedTesting/Gem/Sponza/workspace.mel b/AutomatedTesting/Gem/Sponza/workspace.mel
new file mode 100644
index 0000000000..b082b73ef7
--- /dev/null
+++ b/AutomatedTesting/Gem/Sponza/workspace.mel
@@ -0,0 +1,89 @@
+//Maya 2020 Project Definition
+
+workspace -fr "fluidCache" "";
+workspace -fr "JT_ATF" "";
+workspace -fr "images" ".maya_data/Images";
+workspace -fr "offlineEdit" ".maya_data/scenes/edits";
+workspace -fr "STEP_ATF Export" "";
+workspace -fr "furShadowMap" "";
+workspace -fr "SVG" "";
+workspace -fr "scripts" "ArtSource/Maya/Scripts";
+workspace -fr "DAE_FBX" "";
+workspace -fr "shaders" "ArtSource/Maya/Shaders";
+workspace -fr "NX_ATF" "";
+workspace -fr "CATIAV5_ATF Export" "";
+workspace -fr "furFiles" "";
+workspace -fr "OBJ" ".maya_data/obj";
+workspace -fr "PARASOLID_ATF Export" "";
+workspace -fr "FBX export" "Assets/Objects";
+workspace -fr "furEqualMap" "";
+workspace -fr "textures" "Assets/textures";
+workspace -fr "BIF" "";
+workspace -fr "lights" ".maya_data/renderData/shaders";
+workspace -fr "DAE_FBX export" "";
+workspace -fr "aliasWire" ".maya_data/data";
+workspace -fr "CATIAV5_ATF" "";
+workspace -fr "SAT_ATF Export" "";
+workspace -fr "movie" ".maya_data/movies";
+workspace -fr "ASS Export" "";
+workspace -fr "mayaAscii" "";
+workspace -fr "move" ".maya_data";
+workspace -fr "autoSave" ".maya_data/autoSave";
+workspace -fr "NX_ATF Export" "";
+workspace -fr "sound" ".maya_data/sound";
+workspace -fr "mayaBinary" "";
+workspace -fr "timeEditor" "";
+workspace -fr "RIBexport" ".maya_data/data";
+workspace -fr "DWG_ATF" "";
+workspace -fr "mentalray" ".maya_data/renderData/mentalray";
+workspace -fr "Arnold-USD" "";
+workspace -fr "JT_ATF Export" "";
+workspace -fr "iprImages" ".maya_data/renderData/iprImages";
+workspace -fr "FBX" "Assets/Objects";
+workspace -fr "renderData" ".maya_data/renderData";
+workspace -fr "CATIAV4_ATF" "";
+workspace -fr "fileCache" "";
+workspace -fr "Fbx" "Assets/Objects";
+workspace -fr "eps" "";
+workspace -fr "IGESexport" ".maya_data/data";
+workspace -fr "3dPaintTextures" ".maya_data/3dPaintTextures";
+workspace -fr "DXF_ATF Export" "";
+workspace -fr "mel" ".maya_data/mel";
+workspace -fr "translatorData" "";
+workspace -fr "IGES" ".maya_data/data";
+workspace -fr "particles" ".maya_data/particles";
+workspace -fr "DXFexport" ".maya_data/data";
+workspace -fr "DXF_ATF" "";
+workspace -fr "scene" "Assets/Objects";
+workspace -fr "renderScenes" ".maya_data/renderScenes";
+workspace -fr "SAT_ATF" "";
+workspace -fr "PROE_ATF" "";
+workspace -fr "WIRE_ATF Export" "";
+workspace -fr "sourceImages" "ArtSource/Images";
+workspace -fr "RIB" ".maya_data/data";
+workspace -fr "furImages" "";
+workspace -fr "clips" ".maya_data/clips";
+workspace -fr "Adobe(R) Illustrator(R)" ".maya_data/data";
+workspace -fr "animExport" ".maya_data/data";
+workspace -fr "mentalRay" ".maya_data/mentalRay";
+workspace -fr "STEP_ATF" "";
+workspace -fr "DWG_ATF Export" "";
+workspace -fr "depth" ".maya_data/renderData/depth";
+workspace -fr "sceneAssembly" "";
+workspace -fr "IGES_ATF Export" "";
+workspace -fr "teClipExports" "";
+workspace -fr "IGES_ATF" "";
+workspace -fr "PARASOLID_ATF" "";
+workspace -fr "ASS" "";
+workspace -fr "Substance" ".maya_data/data";
+workspace -fr "audio" ".maya_data/sound";
+workspace -fr "EPS" ".maya_data/data";
+workspace -fr "Alembic" "Assets/Objects";
+workspace -fr "diskCache" ".maya_data/cache";
+workspace -fr "illustrator" "";
+workspace -fr "WIRE_ATF" "";
+workspace -fr "templates" "ArtSource/SceneTemplates";
+workspace -fr "animImport" ".maya_data/data";
+workspace -fr "OBJexport" "Assets/Objects";
+workspace -fr "furAttrMap" "";
+workspace -fr "DXF" ".maya_data/data";
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/Environment.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/Environment.xml
deleted file mode 100644
index 4ba36f66ae..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/Environment.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/TerrainTexture.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/TerrainTexture.xml
deleted file mode 100644
index f43df05b22..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/TerrainTexture.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/TimeOfDay.xml
deleted file mode 100644
index 6ea168cc6b..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/TimeOfDay.xml
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/VegetationMap.dat b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/VegetationMap.dat
deleted file mode 100644
index dce5631cd0..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/LevelData/VegetationMap.dat
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9
-size 63
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/NvCloth_AddClothSimulationToActor.ly b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/NvCloth_AddClothSimulationToActor.ly
deleted file mode 100644
index 23397bf18d..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/NvCloth_AddClothSimulationToActor.ly
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b59cbe84cb77090d723d120597f9d11817aa67a267a7f495f8b012fdd8a9dd86
-size 5536
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/NvCloth_AddClothSimulationToActor.prefab b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/NvCloth_AddClothSimulationToActor.prefab
new file mode 100644
index 0000000000..de23da874f
--- /dev/null
+++ b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/NvCloth_AddClothSimulationToActor.prefab
@@ -0,0 +1,387 @@
+{
+ "ContainerEntity": {
+ "Id": "Entity_[1146574390643]",
+ "Name": "Level",
+ "Components": {
+ "Component_[10641544592923449938]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10641544592923449938
+ },
+ "Component_[12039882709170782873]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 12039882709170782873
+ },
+ "Component_[12265484671603697631]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 12265484671603697631
+ },
+ "Component_[14126657869720434043]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14126657869720434043,
+ "Child Entity Order": [
+ "Entity_[1176639161715]",
+ "Instance_[1015201222663]/ContainerEntity"
+ ]
+ },
+ "Component_[15230859088967841193]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 15230859088967841193,
+ "Parent Entity": ""
+ },
+ "Component_[16239496886950819870]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 16239496886950819870
+ },
+ "Component_[5688118765544765547]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 5688118765544765547
+ },
+ "Component_[6545738857812235305]": {
+ "$type": "SelectionComponent",
+ "Id": 6545738857812235305
+ },
+ "Component_[7247035804068349658]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 7247035804068349658
+ },
+ "Component_[9307224322037797205]": {
+ "$type": "EditorLockComponent",
+ "Id": 9307224322037797205
+ },
+ "Component_[9562516168917670048]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 9562516168917670048
+ }
+ }
+ },
+ "Entities": {
+ "Entity_[1155164325235]": {
+ "Id": "Entity_[1155164325235]",
+ "Name": "Sun",
+ "Components": {
+ "Component_[10440557478882592717]": {
+ "$type": "SelectionComponent",
+ "Id": 10440557478882592717
+ },
+ "Component_[13620450453324765907]": {
+ "$type": "EditorLockComponent",
+ "Id": 13620450453324765907
+ },
+ "Component_[2134313378593666258]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 2134313378593666258
+ },
+ "Component_[234010807770404186]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 234010807770404186
+ },
+ "Component_[2970359110423865725]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 2970359110423865725
+ },
+ "Component_[3722854130373041803]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3722854130373041803
+ },
+ "Component_[5992533738676323195]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5992533738676323195
+ },
+ "Component_[7378860763541895402]": {
+ "$type": "AZ::Render::EditorDirectionalLightComponent",
+ "Id": 7378860763541895402,
+ "Controller": {
+ "Configuration": {
+ "Intensity": 1.0,
+ "CameraEntityId": "",
+ "ShadowFilterMethod": 1
+ }
+ }
+ },
+ "Component_[7892834440890947578]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7892834440890947578,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ 13.487043380737305
+ ],
+ "Rotate": [
+ -76.13099670410156,
+ -0.847000002861023,
+ -15.8100004196167
+ ]
+ }
+ },
+ "Component_[8599729549570828259]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 8599729549570828259
+ },
+ "Component_[952797371922080273]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 952797371922080273
+ }
+ }
+ },
+ "Entity_[1163754259827]": {
+ "Id": "Entity_[1163754259827]",
+ "Name": "Camera",
+ "Components": {
+ "Component_[11895140916889160460]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11895140916889160460
+ },
+ "Component_[16880285896855930892]": {
+ "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+ "Id": 16880285896855930892,
+ "Controller": {
+ "Configuration": {
+ "Field of View": 55.0,
+ "EditorEntityId": 8929576024571800510
+ }
+ }
+ },
+ "Component_[17187464423780271193]": {
+ "$type": "EditorLockComponent",
+ "Id": 17187464423780271193
+ },
+ "Component_[17495696818315413311]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 17495696818315413311
+ },
+ "Component_[18086214374043522055]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 18086214374043522055,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ 1.511600136756897,
+ -1.3604341745376587,
+ 1.412430763244629
+ ],
+ "Rotate": [
+ -7.442450523376465,
+ -6.665996551513672,
+ 41.62498092651367
+ ]
+ }
+ },
+ "Component_[18387556550380114975]": {
+ "$type": "SelectionComponent",
+ "Id": 18387556550380114975
+ },
+ "Component_[2654521436129313160]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 2654521436129313160
+ },
+ "Component_[5265045084611556958]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5265045084611556958
+ },
+ "Component_[7169798125182238623]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7169798125182238623
+ },
+ "Component_[7255796294953281766]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 7255796294953281766,
+ "m_template": {
+ "$type": "FlyCameraInputComponent"
+ }
+ },
+ "Component_[8866210352157164042]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 8866210352157164042
+ },
+ "Component_[9129253381063760879]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 9129253381063760879
+ }
+ }
+ },
+ "Entity_[1176639161715]": {
+ "Id": "Entity_[1176639161715]",
+ "Name": "Atom Default Environment",
+ "Components": {
+ "Component_[10757302973393310045]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 10757302973393310045,
+ "Parent Entity": "Entity_[1146574390643]"
+ },
+ "Component_[14505817420424255464]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14505817420424255464,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 10757302973393310045
+ }
+ ]
+ },
+ "Component_[14988041764659020032]": {
+ "$type": "EditorLockComponent",
+ "Id": 14988041764659020032
+ },
+ "Component_[15808690248755038124]": {
+ "$type": "SelectionComponent",
+ "Id": 15808690248755038124
+ },
+ "Component_[15900837685796817138]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 15900837685796817138
+ },
+ "Component_[3298767348226484884]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3298767348226484884
+ },
+ "Component_[4076975109609220594]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 4076975109609220594
+ },
+ "Component_[5679760548946028854]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5679760548946028854
+ },
+ "Component_[5855590796136709437]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 5855590796136709437,
+ "Child Entity Order": [
+ "Entity_[1155164325235]",
+ "Entity_[1180934129011]",
+ "Entity_[1163754259827]"
+ ]
+ },
+ "Component_[9277695270015777859]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 9277695270015777859
+ }
+ }
+ },
+ "Entity_[1180934129011]": {
+ "Id": "Entity_[1180934129011]",
+ "Name": "Global Sky",
+ "Components": {
+ "Component_[11231930600558681245]": {
+ "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+ "Id": 11231930600558681245,
+ "Controller": {
+ "Configuration": {
+ "CubemapAsset": {
+ "assetId": {
+ "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
+ "subId": 1000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[11980494120202836095]": {
+ "$type": "SelectionComponent",
+ "Id": 11980494120202836095
+ },
+ "Component_[1428633914413949476]": {
+ "$type": "EditorLockComponent",
+ "Id": 1428633914413949476
+ },
+ "Component_[14936200426671614999]": {
+ "$type": "AZ::Render::EditorImageBasedLightComponent",
+ "Id": 14936200426671614999,
+ "Controller": {
+ "Configuration": {
+ "diffuseImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 3000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+ },
+ "specularImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 2000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[14994774102579326069]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 14994774102579326069
+ },
+ "Component_[15417479889044493340]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 15417479889044493340
+ },
+ "Component_[15826613364991382688]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 15826613364991382688
+ },
+ "Component_[1665003113283562343]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1665003113283562343
+ },
+ "Component_[3704934735944502280]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 3704934735944502280
+ },
+ "Component_[5698542331457326479]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 5698542331457326479
+ },
+ "Component_[6644513399057217122]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6644513399057217122,
+ "Parent Entity": "Entity_[1176639161715]"
+ },
+ "Component_[931091830724002070]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 931091830724002070
+ }
+ }
+ }
+ },
+ "Instances": {
+ "Instance_[1015201222663]": {
+ "Source": "prefabs/Cloth/Chicken_Actor.prefab",
+ "Patches": [
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Parent Entity",
+ "value": "../Entity_[1146574390643]"
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/0",
+ "value": 0.31251561641693115
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/1",
+ "value": -0.006644248962402344
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/2",
+ "value": 0.3271239995956421
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Rotate/2",
+ "value": 179.72178649902344
+ },
+ {
+ "op": "add",
+ "path": "/ContainerEntity/Components/Component_[7874177159288365422]/Child Entity Order/0",
+ "value": "Entity_[303447173544404]"
+ },
+ {
+ "op": "remove",
+ "path": "/LinkId"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/TerrainTexture.pak b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/TerrainTexture.pak
deleted file mode 100644
index fe3604a050..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/TerrainTexture.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85
-size 22
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/filelist.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/filelist.xml
deleted file mode 100644
index 20952a47ce..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/filelist.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/level.pak b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/level.pak
deleted file mode 100644
index 4259131c4f..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToActor/level.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:46051f4116003e1a2d13855bea92a1b15501166b1379a11d02c4d2239ccd2530
-size 3648
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/Environment.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/Environment.xml
deleted file mode 100644
index 4ba36f66ae..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/Environment.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/TerrainTexture.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/TerrainTexture.xml
deleted file mode 100644
index f43df05b22..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/TerrainTexture.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/TimeOfDay.xml
deleted file mode 100644
index 6ea168cc6b..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/TimeOfDay.xml
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/VegetationMap.dat b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/VegetationMap.dat
deleted file mode 100644
index dce5631cd0..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/LevelData/VegetationMap.dat
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9
-size 63
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/NvCloth_AddClothSimulationToMesh.ly b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/NvCloth_AddClothSimulationToMesh.ly
deleted file mode 100644
index 861626993e..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/NvCloth_AddClothSimulationToMesh.ly
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bedd2adc60f244a8595e64619069046d5036dd762f61b5393f9b759d69281362
-size 5276
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/NvCloth_AddClothSimulationToMesh.prefab b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/NvCloth_AddClothSimulationToMesh.prefab
new file mode 100644
index 0000000000..93d0d1e707
--- /dev/null
+++ b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/NvCloth_AddClothSimulationToMesh.prefab
@@ -0,0 +1,522 @@
+{
+ "ContainerEntity": {
+ "Id": "Entity_[1146574390643]",
+ "Name": "Level",
+ "Components": {
+ "Component_[10641544592923449938]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10641544592923449938
+ },
+ "Component_[12039882709170782873]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 12039882709170782873
+ },
+ "Component_[12265484671603697631]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 12265484671603697631
+ },
+ "Component_[14126657869720434043]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14126657869720434043,
+ "Child Entity Order": [
+ "Entity_[1176639161715]",
+ "Instance_[811083782986]/ContainerEntity",
+ "Instance_[503204883039]/ContainerEntity",
+ "Instance_[563334425183]/ContainerEntity",
+ "Instance_[640643836511]/ContainerEntity",
+ "Instance_[735133117023]/ContainerEntity"
+ ]
+ },
+ "Component_[15230859088967841193]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 15230859088967841193,
+ "Parent Entity": ""
+ },
+ "Component_[16239496886950819870]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 16239496886950819870
+ },
+ "Component_[5688118765544765547]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 5688118765544765547
+ },
+ "Component_[6545738857812235305]": {
+ "$type": "SelectionComponent",
+ "Id": 6545738857812235305
+ },
+ "Component_[7247035804068349658]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 7247035804068349658
+ },
+ "Component_[9307224322037797205]": {
+ "$type": "EditorLockComponent",
+ "Id": 9307224322037797205
+ },
+ "Component_[9562516168917670048]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 9562516168917670048
+ }
+ }
+ },
+ "Entities": {
+ "Entity_[1155164325235]": {
+ "Id": "Entity_[1155164325235]",
+ "Name": "Sun",
+ "Components": {
+ "Component_[10440557478882592717]": {
+ "$type": "SelectionComponent",
+ "Id": 10440557478882592717
+ },
+ "Component_[13620450453324765907]": {
+ "$type": "EditorLockComponent",
+ "Id": 13620450453324765907
+ },
+ "Component_[2134313378593666258]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 2134313378593666258
+ },
+ "Component_[234010807770404186]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 234010807770404186
+ },
+ "Component_[2970359110423865725]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 2970359110423865725
+ },
+ "Component_[3722854130373041803]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3722854130373041803
+ },
+ "Component_[5992533738676323195]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5992533738676323195
+ },
+ "Component_[7378860763541895402]": {
+ "$type": "AZ::Render::EditorDirectionalLightComponent",
+ "Id": 7378860763541895402,
+ "Controller": {
+ "Configuration": {
+ "Intensity": 1.0,
+ "CameraEntityId": "",
+ "ShadowFilterMethod": 1
+ }
+ }
+ },
+ "Component_[7892834440890947578]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7892834440890947578,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ 13.487043380737305
+ ],
+ "Rotate": [
+ -76.13099670410156,
+ -0.847000002861023,
+ -15.8100004196167
+ ]
+ }
+ },
+ "Component_[8599729549570828259]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 8599729549570828259
+ },
+ "Component_[952797371922080273]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 952797371922080273
+ }
+ }
+ },
+ "Entity_[1163754259827]": {
+ "Id": "Entity_[1163754259827]",
+ "Name": "Camera",
+ "Components": {
+ "Component_[11895140916889160460]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11895140916889160460
+ },
+ "Component_[16880285896855930892]": {
+ "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+ "Id": 16880285896855930892,
+ "Controller": {
+ "Configuration": {
+ "Field of View": 55.0,
+ "EditorEntityId": 8929576024571800510
+ }
+ }
+ },
+ "Component_[17187464423780271193]": {
+ "$type": "EditorLockComponent",
+ "Id": 17187464423780271193
+ },
+ "Component_[17495696818315413311]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 17495696818315413311
+ },
+ "Component_[18086214374043522055]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 18086214374043522055,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ 3.288902521133423,
+ -3.0976791381835938,
+ 1.595407247543335
+ ],
+ "Rotate": [
+ -6.36656379699707,
+ -6.542551040649414,
+ 45.600582122802734
+ ]
+ }
+ },
+ "Component_[18387556550380114975]": {
+ "$type": "SelectionComponent",
+ "Id": 18387556550380114975
+ },
+ "Component_[2654521436129313160]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 2654521436129313160
+ },
+ "Component_[5265045084611556958]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5265045084611556958
+ },
+ "Component_[7169798125182238623]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7169798125182238623
+ },
+ "Component_[7255796294953281766]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 7255796294953281766,
+ "m_template": {
+ "$type": "FlyCameraInputComponent"
+ }
+ },
+ "Component_[8866210352157164042]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 8866210352157164042
+ },
+ "Component_[9129253381063760879]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 9129253381063760879
+ }
+ }
+ },
+ "Entity_[1176639161715]": {
+ "Id": "Entity_[1176639161715]",
+ "Name": "Atom Default Environment",
+ "Components": {
+ "Component_[10757302973393310045]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 10757302973393310045,
+ "Parent Entity": "Entity_[1146574390643]"
+ },
+ "Component_[14505817420424255464]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14505817420424255464,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 10757302973393310045
+ }
+ ]
+ },
+ "Component_[14988041764659020032]": {
+ "$type": "EditorLockComponent",
+ "Id": 14988041764659020032
+ },
+ "Component_[15808690248755038124]": {
+ "$type": "SelectionComponent",
+ "Id": 15808690248755038124
+ },
+ "Component_[15900837685796817138]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 15900837685796817138
+ },
+ "Component_[3298767348226484884]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3298767348226484884
+ },
+ "Component_[4076975109609220594]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 4076975109609220594
+ },
+ "Component_[5679760548946028854]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5679760548946028854
+ },
+ "Component_[5855590796136709437]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 5855590796136709437,
+ "Child Entity Order": [
+ "Entity_[1155164325235]",
+ "Entity_[1180934129011]",
+ "Entity_[1163754259827]"
+ ]
+ },
+ "Component_[9277695270015777859]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 9277695270015777859
+ }
+ }
+ },
+ "Entity_[1180934129011]": {
+ "Id": "Entity_[1180934129011]",
+ "Name": "Global Sky",
+ "Components": {
+ "Component_[11231930600558681245]": {
+ "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+ "Id": 11231930600558681245,
+ "Controller": {
+ "Configuration": {
+ "CubemapAsset": {
+ "assetId": {
+ "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
+ "subId": 1000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[11980494120202836095]": {
+ "$type": "SelectionComponent",
+ "Id": 11980494120202836095
+ },
+ "Component_[1428633914413949476]": {
+ "$type": "EditorLockComponent",
+ "Id": 1428633914413949476
+ },
+ "Component_[14936200426671614999]": {
+ "$type": "AZ::Render::EditorImageBasedLightComponent",
+ "Id": 14936200426671614999,
+ "Controller": {
+ "Configuration": {
+ "diffuseImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 3000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+ },
+ "specularImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 2000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[14994774102579326069]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 14994774102579326069
+ },
+ "Component_[15417479889044493340]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 15417479889044493340
+ },
+ "Component_[15826613364991382688]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 15826613364991382688
+ },
+ "Component_[1665003113283562343]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1665003113283562343
+ },
+ "Component_[3704934735944502280]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 3704934735944502280
+ },
+ "Component_[5698542331457326479]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 5698542331457326479
+ },
+ "Component_[6644513399057217122]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6644513399057217122,
+ "Parent Entity": "Entity_[1176639161715]"
+ },
+ "Component_[931091830724002070]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 931091830724002070
+ }
+ }
+ }
+ },
+ "Instances": {
+ "Instance_[503204883039]": {
+ "Source": "prefabs/Cloth/cloth_blinds_broken.prefab",
+ "Patches": [
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Parent Entity",
+ "value": "../Entity_[1146574390643]"
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/0",
+ "value": -3.9779629707336426
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/1",
+ "value": -0.7587795257568359
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/2",
+ "value": 1.0752365589141846
+ },
+ {
+ "op": "add",
+ "path": "/ContainerEntity/Components/Component_[7874177159288365422]/Child Entity Order/0",
+ "value": "Entity_[303326914460116]"
+ },
+ {
+ "op": "remove",
+ "path": "/LinkId"
+ }
+ ]
+ },
+ "Instance_[563334425183]": {
+ "Source": "prefabs/Cloth/cloth_locked_corners_four.prefab",
+ "Patches": [
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Parent Entity",
+ "value": "../Entity_[1146574390643]"
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/0",
+ "value": -4.94368839263916
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/1",
+ "value": 0.805694580078125
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/2",
+ "value": 2.2616283893585205
+ },
+ {
+ "op": "add",
+ "path": "/ContainerEntity/Components/Component_[7874177159288365422]/Child Entity Order/0",
+ "value": "Entity_[303417108773332]"
+ },
+ {
+ "op": "remove",
+ "path": "/LinkId"
+ }
+ ]
+ },
+ "Instance_[640643836511]": {
+ "Source": "prefabs/Cloth/cloth_locked_corners_two.prefab",
+ "Patches": [
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Parent Entity",
+ "value": "../Entity_[1146574390643]"
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/0",
+ "value": -2.416099786758423
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/1",
+ "value": 2.790005683898926
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/2",
+ "value": 2.1456499099731445
+ },
+ {
+ "op": "add",
+ "path": "/ContainerEntity/Components/Component_[7874177159288365422]/Child Entity Order/0",
+ "value": "Entity_[303387044002260]"
+ },
+ {
+ "op": "remove",
+ "path": "/LinkId"
+ }
+ ]
+ },
+ "Instance_[735133117023]": {
+ "Source": "prefabs/Cloth/cloth_locked_edge.prefab",
+ "Patches": [
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Parent Entity",
+ "value": "../Entity_[1146574390643]"
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/0",
+ "value": -1.9405040740966797
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/1",
+ "value": -0.8027572631835938
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/2",
+ "value": 0.2776646614074707
+ },
+ {
+ "op": "add",
+ "path": "/ContainerEntity/Components/Component_[7874177159288365422]/Child Entity Order/0",
+ "value": "Entity_[303356979231188]"
+ },
+ {
+ "op": "remove",
+ "path": "/LinkId"
+ }
+ ]
+ },
+ "Instance_[811083782986]": {
+ "Source": "prefabs/Cloth/cloth_blinds.prefab",
+ "Patches": [
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Parent Entity",
+ "value": "../Entity_[1146574390643]"
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/0",
+ "value": 0.6851601600646973
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/1",
+ "value": 0.1960926055908203
+ },
+ {
+ "op": "replace",
+ "path": "/ContainerEntity/Components/Component_[4272963378099646759]/Transform Data/Translate/2",
+ "value": 0.3339226245880127
+ },
+ {
+ "op": "add",
+ "path": "/ContainerEntity/Components/Component_[7874177159288365422]/Child Entity Order/0",
+ "value": "Entity_[303275374852564]"
+ },
+ {
+ "op": "remove",
+ "path": "/LinkId"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/TerrainTexture.pak b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/TerrainTexture.pak
deleted file mode 100644
index fe3604a050..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/TerrainTexture.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85
-size 22
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/filelist.xml b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/filelist.xml
deleted file mode 100644
index d3492ca7b6..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/filelist.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/level.pak b/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/level.pak
deleted file mode 100644
index 7fa23ea67f..0000000000
--- a/AutomatedTesting/Levels/NvCloth/NvCloth_AddClothSimulationToMesh/level.pak
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:81fc98854424d55e594a3983da53d2f5a4d7a7cf60e52e12366e4800d1d3f080
-size 38559
diff --git a/AutomatedTesting/Levels/Physics/ScriptCanvas_CollisionEvents/ScriptCanvas_CollisionEvents.ly b/AutomatedTesting/Levels/Physics/ScriptCanvas_CollisionEvents/ScriptCanvas_CollisionEvents.ly
index 8fcf2dcde2..846ba9101c 100644
--- a/AutomatedTesting/Levels/Physics/ScriptCanvas_CollisionEvents/ScriptCanvas_CollisionEvents.ly
+++ b/AutomatedTesting/Levels/Physics/ScriptCanvas_CollisionEvents/ScriptCanvas_CollisionEvents.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d674eac2070ed0028ceff1e84692c9cf1f69db2192c2295b6d714670ccd50308
-size 8936
+oid sha256:82a4ffbffeee43ea4ae293080e838bbc501fe9c7c20febc2e56e745451c95df3
+size 9221
diff --git a/AutomatedTesting/Levels/Physics/ScriptCanvas_PostUpdateEvent/ScriptCanvas_PostUpdateEvent.ly b/AutomatedTesting/Levels/Physics/ScriptCanvas_PostUpdateEvent/ScriptCanvas_PostUpdateEvent.ly
index 35c3674159..9328e90996 100644
--- a/AutomatedTesting/Levels/Physics/ScriptCanvas_PostUpdateEvent/ScriptCanvas_PostUpdateEvent.ly
+++ b/AutomatedTesting/Levels/Physics/ScriptCanvas_PostUpdateEvent/ScriptCanvas_PostUpdateEvent.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8a2c9ad554554eba1021abe0baf0b3455da1aaab2bb8331eb240f79c89031636
-size 5202
+oid sha256:3ef03f338cd867860068b5bd343f66fa9bda4f3de1662badf552f05716da35ed
+size 5161
diff --git a/AutomatedTesting/Levels/Physics/ScriptCanvas_PreUpdateEvent/ScriptCanvas_PreUpdateEvent.ly b/AutomatedTesting/Levels/Physics/ScriptCanvas_PreUpdateEvent/ScriptCanvas_PreUpdateEvent.ly
index 60cec8af58..c981e27142 100644
--- a/AutomatedTesting/Levels/Physics/ScriptCanvas_PreUpdateEvent/ScriptCanvas_PreUpdateEvent.ly
+++ b/AutomatedTesting/Levels/Physics/ScriptCanvas_PreUpdateEvent/ScriptCanvas_PreUpdateEvent.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:982f085cfb17ce957cd1534e89a6fb5c76bcbe6936caec214ecd422b0a5dbe7b
-size 5214
+oid sha256:bf48b69c0cc2599581bd3d931d8adc6faba5d78d950c2c0946c19ec7ba7b6215
+size 5190
diff --git a/AutomatedTesting/Levels/Physics/ScriptCanvas_ShapeCast/ScriptCanvas_ShapeCast.ly b/AutomatedTesting/Levels/Physics/ScriptCanvas_ShapeCast/ScriptCanvas_ShapeCast.ly
index 2f7291cb27..485556bb56 100644
--- a/AutomatedTesting/Levels/Physics/ScriptCanvas_ShapeCast/ScriptCanvas_ShapeCast.ly
+++ b/AutomatedTesting/Levels/Physics/ScriptCanvas_ShapeCast/ScriptCanvas_ShapeCast.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:3361ba7aa2faa53421d8a92ed0bb2e1747e766d93c0315484a3c85b74a6494c3
-size 8820
+oid sha256:be53bb087c53874577dad8f1fa084698c27fbad827f0ed7dc50927fb4c9d8884
+size 7748
diff --git a/AutomatedTesting/Levels/Sponza/Sponza.prefab b/AutomatedTesting/Levels/Sponza/Sponza.prefab
new file mode 100644
index 0000000000..d755eb9774
--- /dev/null
+++ b/AutomatedTesting/Levels/Sponza/Sponza.prefab
@@ -0,0 +1,1489 @@
+{
+ "ContainerEntity": {
+ "Id": "Entity_[406217483857]",
+ "Name": "Level",
+ "Components": {
+ "Component_[10588931505759123943]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 10588931505759123943
+ },
+ "Component_[135321489898029517]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 135321489898029517
+ },
+ "Component_[14858507413812498857]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14858507413812498857
+ },
+ "Component_[15178816766766638692]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 15178816766766638692
+ },
+ "Component_[17951702430591084334]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 17951702430591084334
+ },
+ "Component_[2563280132145207190]": {
+ "$type": "EditorLockComponent",
+ "Id": 2563280132145207190
+ },
+ "Component_[2822556265044965634]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2822556265044965634
+ },
+ "Component_[446057404408737487]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 446057404408737487
+ },
+ "Component_[5683088399314452447]": {
+ "$type": "SelectionComponent",
+ "Id": 5683088399314452447
+ },
+ "Component_[5801776107759571453]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 5801776107759571453,
+ "Parent Entity": ""
+ },
+ "Component_[9426929613394548724]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 9426929613394548724,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[1081216208506]"
+ },
+ {
+ "EntityId": "Entity_[935187320442]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[935187320442]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[935187320442]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[935187320442]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[935187320442]",
+ "SortIndex": 5
+ }
+ ]
+ }
+ }
+ },
+ "Entities": {
+ "Entity_[1081216208506]": {
+ "Id": "Entity_[1081216208506]",
+ "Name": "LIGHTING",
+ "Components": {
+ "Component_[10807484710436476353]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10807484710436476353
+ },
+ "Component_[12535994014200063229]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12535994014200063229
+ },
+ "Component_[12567916482013107382]": {
+ "$type": "SelectionComponent",
+ "Id": 12567916482013107382
+ },
+ "Component_[15060801524064219165]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 15060801524064219165
+ },
+ "Component_[1597296709936823974]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 1597296709936823974
+ },
+ "Component_[17535943354307721937]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 17535943354307721937
+ },
+ "Component_[3144604952797148227]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 3144604952797148227,
+ "Parent Entity": "Entity_[406217483857]",
+ "Transform Data": {
+ "Translate": [
+ -0.7899999022483826,
+ -10.387897491455078,
+ 8.160000801086426
+ ]
+ }
+ },
+ "Component_[3567054724563794528]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 3567054724563794528
+ },
+ "Component_[8097342669405778862]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 8097342669405778862,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[1613792153210]"
+ },
+ {
+ "EntityId": "Entity_[1119870914170]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[1115575946874]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[1111280979578]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[1102691044986]",
+ "SortIndex": 5
+ },
+ {
+ "EntityId": "Entity_[1098396077690]",
+ "SortIndex": 6
+ },
+ {
+ "EntityId": "Entity_[1094101110394]",
+ "SortIndex": 7
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 8
+ },
+ {
+ "EntityId": "Entity_[1106986012282]",
+ "SortIndex": 8
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 7
+ },
+ {
+ "EntityId": "Entity_[1089806143098]",
+ "SortIndex": 6
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 5
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[1085511175802]",
+ "SortIndex": 17
+ }
+ ]
+ },
+ "Component_[9064866490989218404]": {
+ "$type": "EditorLockComponent",
+ "Id": 9064866490989218404
+ }
+ }
+ },
+ "Entity_[1085511175802]": {
+ "Id": "Entity_[1085511175802]",
+ "Name": "ReflectionProbe_UpperLevel",
+ "Components": {
+ "Component_[1038637709631818218]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 1038637709631818218
+ },
+ "Component_[13993242205578133374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 13993242205578133374
+ },
+ "Component_[14164886745537962894]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 14164886745537962894
+ },
+ "Component_[15336954334699691810]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 15336954334699691810
+ },
+ "Component_[17468041844277100837]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 17468041844277100837
+ },
+ "Component_[18107599364473376156]": {
+ "$type": "AZ::Render::EditorReflectionProbeComponent",
+ "Id": 18107599364473376156,
+ "Controller": {
+ "Configuration": {
+ "OuterHeight": 3.0,
+ "OuterLength": 3.0,
+ "OuterWidth": 1.0,
+ "InnerHeight": 2.75,
+ "InnerLength": 2.75,
+ "InnerWidth": 0.75,
+ "BakedCubemapQualityLevel": 3,
+ "BakedCubeMapRelativePath": "ReflectionProbes/ReflectionProbe_UpperLevel__4DABA7BF-9367-4D95-AA5F-A9BF6BA0F7BE__iblspecularcm512.dds",
+ "BakedCubeMapAsset": {
+ "assetId": {
+ "guid": "{7854FC84-FDCE-5C02-AC9C-DBD6894F52F4}",
+ "subId": 2000
+ },
+ "assetHint": "reflectionprobes/reflectionprobe_upperlevel__4daba7bf-9367-4d95-aa5f-a9bf6ba0f7be__iblspecularcm512.dds.streamingimage"
+ },
+ "EntityId": 14568425243222190542,
+ "ShowVisualization": false
+ }
+ },
+ "bakedCubeMapQualityLevel": 3,
+ "bakedCubeMapRelativePath": "ReflectionProbes/ReflectionProbe_UpperLevel__4DABA7BF-9367-4D95-AA5F-A9BF6BA0F7BE__iblspecularcm512.dds"
+ },
+ "Component_[320343109587065620]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 320343109587065620
+ },
+ "Component_[3267511667303906499]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 3267511667303906499,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ -13.363113403320313,
+ 10.723356246948242,
+ -1.8831419944763184
+ ]
+ }
+ },
+ "Component_[4634887848675078464]": {
+ "$type": "EditorLockComponent",
+ "Id": 4634887848675078464
+ },
+ "Component_[4783209159709094238]": {
+ "$type": "SelectionComponent",
+ "Id": 4783209159709094238
+ },
+ "Component_[728315922784530894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 728315922784530894
+ },
+ "Component_[8999082608038997636]": {
+ "$type": "EditorAxisAlignedBoxShapeComponent",
+ "Id": 8999082608038997636,
+ "DisplayFilled": false,
+ "AxisAlignedBoxShape": {
+ "Configuration": {
+ "IsFilled": false,
+ "Dimensions": [
+ 1.0,
+ 3.0,
+ 3.0
+ ]
+ }
+ }
+ }
+ }
+ },
+ "Entity_[1089806143098]": {
+ "Id": "Entity_[1089806143098]",
+ "Name": "ReflectionProbe_Lion",
+ "Components": {
+ "Component_[14298922893146648725]": {
+ "$type": "EditorAxisAlignedBoxShapeComponent",
+ "Id": 14298922893146648725,
+ "Visible": false,
+ "DisplayFilled": false,
+ "AxisAlignedBoxShape": {
+ "Configuration": {
+ "IsFilled": false,
+ "Dimensions": [
+ 3.0,
+ 4.0,
+ 4.0
+ ]
+ }
+ }
+ },
+ "Component_[1455674266703651422]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 1455674266703651422
+ },
+ "Component_[14636684755738306181]": {
+ "$type": "AZ::Render::EditorReflectionProbeComponent",
+ "Id": 14636684755738306181,
+ "Controller": {
+ "Configuration": {
+ "OuterHeight": 4.0,
+ "OuterLength": 4.0,
+ "OuterWidth": 3.0,
+ "InnerHeight": 3.0,
+ "InnerLength": 3.0,
+ "InnerWidth": 2.0,
+ "BakedCubemapQualityLevel": 3,
+ "BakedCubeMapRelativePath": "ReflectionProbes/ReflectionProbe_Lion__CA20BB89-1587-4410-80BA-8150CB0EF47B__iblspecularcm512.dds",
+ "BakedCubeMapAsset": {
+ "assetId": {
+ "guid": "{AC2EF073-63B8-53C2-8178-9B80D2D7E56D}",
+ "subId": 2000
+ },
+ "assetHint": "reflectionprobes/reflectionprobe_lion__ca20bb89-1587-4410-80ba-8150cb0ef47b__iblspecularcm512.dds.streamingimage"
+ },
+ "EntityId": 15188201575897363858,
+ "ShowVisualization": false
+ }
+ },
+ "bakedCubeMapQualityLevel": 3,
+ "bakedCubeMapRelativePath": "ReflectionProbes/ReflectionProbe_Lion__CA20BB89-1587-4410-80BA-8150CB0EF47B__iblspecularcm512.dds"
+ },
+ "Component_[1558055592965824024]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 1558055592965824024
+ },
+ "Component_[161549568296074325]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 161549568296074325
+ },
+ "Component_[16573539057585083382]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 16573539057585083382
+ },
+ "Component_[17523994278098812420]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 17523994278098812420,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ -13.342336654663086,
+ 10.449432373046875,
+ -6.156347274780273
+ ]
+ }
+ },
+ "Component_[1895148655574754151]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 1895148655574754151
+ },
+ "Component_[2659020665645761255]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 2659020665645761255
+ },
+ "Component_[3707403743603935171]": {
+ "$type": "EditorLockComponent",
+ "Id": 3707403743603935171
+ },
+ "Component_[5008186835003860730]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 5008186835003860730
+ },
+ "Component_[7632822173429043662]": {
+ "$type": "SelectionComponent",
+ "Id": 7632822173429043662
+ }
+ }
+ },
+ "Entity_[1094101110394]": {
+ "Id": "Entity_[1094101110394]",
+ "Name": "ReflectionProbe_Scene",
+ "Components": {
+ "Component_[1084328120591698803]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 1084328120591698803,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 10.77357292175293,
+ -2.114013671875
+ ]
+ }
+ },
+ "Component_[11927919033815991882]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 11927919033815991882
+ },
+ "Component_[12922039245522655341]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 12922039245522655341
+ },
+ "Component_[13830787916768787880]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 13830787916768787880
+ },
+ "Component_[13864356435863998063]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 13864356435863998063
+ },
+ "Component_[14618987283145709626]": {
+ "$type": "EditorLockComponent",
+ "Id": 14618987283145709626
+ },
+ "Component_[14690766657349179909]": {
+ "$type": "AZ::Render::EditorReflectionProbeComponent",
+ "Id": 14690766657349179909,
+ "Controller": {
+ "Configuration": {
+ "OuterHeight": 17.0,
+ "OuterLength": 25.0,
+ "OuterWidth": 35.0,
+ "BakedCubeMapRelativePath": "ReflectionProbes/ReflectionProbe_Scene__D245F488-152E-4A3A-898B-FBCF71E4A87A__iblspecularcm256.dds",
+ "BakedCubeMapAsset": {
+ "assetId": {
+ "guid": "{E94B628B-9E61-5DD4-8AFD-200DD7540CAD}",
+ "subId": 2000
+ },
+ "assetHint": "reflectionprobes/reflectionprobe_scene__d245f488-152e-4a3a-898b-fbcf71e4a87a__iblspecularcm256.dds.streamingimage"
+ },
+ "EntityId": 18057698412353009297,
+ "ShowVisualization": false
+ }
+ },
+ "bakedCubeMapRelativePath": "ReflectionProbes/ReflectionProbe_Scene__D245F488-152E-4A3A-898B-FBCF71E4A87A__iblspecularcm256.dds"
+ },
+ "Component_[16801122362190390827]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 16801122362190390827
+ },
+ "Component_[1897972008443666285]": {
+ "$type": "SelectionComponent",
+ "Id": 1897972008443666285
+ },
+ "Component_[2961811751273549376]": {
+ "$type": "EditorBoxShapeComponent",
+ "Id": 2961811751273549376,
+ "DisplayFilled": false,
+ "BoxShape": {
+ "Configuration": {
+ "IsFilled": false,
+ "Dimensions": [
+ 35.0,
+ 25.0,
+ 17.0
+ ]
+ }
+ }
+ },
+ "Component_[879709407962202982]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 879709407962202982
+ },
+ "Component_[9324834207126061548]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 9324834207126061548
+ }
+ }
+ },
+ "Entity_[1098396077690]": {
+ "Id": "Entity_[1098396077690]",
+ "Name": "PointLight_02",
+ "Components": {
+ "Component_[10534705633537717631]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 10534705633537717631
+ },
+ "Component_[10552323305936140565]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10552323305936140565
+ },
+ "Component_[13058374277331580766]": {
+ "$type": "SelectionComponent",
+ "Id": 13058374277331580766
+ },
+ "Component_[14949512479506290054]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 14949512479506290054
+ },
+ "Component_[1548752089356963562]": {
+ "$type": "AZ::Render::EditorAreaLightComponent",
+ "Id": 1548752089356963562,
+ "Controller": {
+ "Configuration": {
+ "LightType": 1,
+ "IntensityMode": 4,
+ "Intensity": 15.359000205993652,
+ "AttenuationRadius": 72.0053482055664,
+ "Enable Shadow": true
+ }
+ }
+ },
+ "Component_[15792288291507192351]": {
+ "$type": "EditorLockComponent",
+ "Id": 15792288291507192351
+ },
+ "Component_[17205110032543434616]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 17205110032543434616
+ },
+ "Component_[2030794600614672812]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 2030794600614672812
+ },
+ "Component_[2978368743586258871]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 2978368743586258871
+ },
+ "Component_[4291094216513321822]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 4291094216513321822,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ 2.581982135772705,
+ 10.840080261230469,
+ -0.9913702011108398
+ ]
+ }
+ },
+ "Component_[4611947863173505]": {
+ "$type": "EditorSphereShapeComponent",
+ "Id": 4611947863173505,
+ "ShapeColor": [
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "SphereShape": {
+ "Configuration": {
+ "Radius": 0.05000000074505806
+ }
+ }
+ },
+ "Component_[7416869202661318055]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7416869202661318055
+ }
+ }
+ },
+ "Entity_[1102691044986]": {
+ "Id": "Entity_[1102691044986]",
+ "Name": "PointLight_01",
+ "Components": {
+ "Component_[11365983295692083092]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 11365983295692083092
+ },
+ "Component_[11475917125854123708]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 11475917125854123708
+ },
+ "Component_[14430205535050778968]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 14430205535050778968
+ },
+ "Component_[1466324423527856074]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 1466324423527856074
+ },
+ "Component_[15554484541906022976]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 15554484541906022976
+ },
+ "Component_[15619369680404016454]": {
+ "$type": "EditorLockComponent",
+ "Id": 15619369680404016454
+ },
+ "Component_[2289960019728880406]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 2289960019728880406
+ },
+ "Component_[2537457439377723385]": {
+ "$type": "SelectionComponent",
+ "Id": 2537457439377723385
+ },
+ "Component_[3297556825839117286]": {
+ "$type": "EditorSphereShapeComponent",
+ "Id": 3297556825839117286,
+ "ShapeColor": [
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "SphereShape": {
+ "Configuration": {
+ "Radius": 0.05000000074505806
+ }
+ }
+ },
+ "Component_[6893246775558579859]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 6893246775558579859
+ },
+ "Component_[776705866357873394]": {
+ "$type": "AZ::Render::EditorAreaLightComponent",
+ "Id": 776705866357873394,
+ "Controller": {
+ "Configuration": {
+ "LightType": 1,
+ "IntensityMode": 4,
+ "Intensity": 15.84000015258789,
+ "AttenuationRadius": 85.0672607421875
+ }
+ }
+ },
+ "Component_[9324553387194905409]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 9324553387194905409,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ -2.2817187309265137,
+ 10.581533432006836,
+ 7.5597944259643555
+ ]
+ }
+ }
+ }
+ },
+ "Entity_[1106986012282]": {
+ "Id": "Entity_[1106986012282]",
+ "Name": "EnvironmentLight",
+ "Components": {
+ "Component_[10422300770865106323]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 10422300770865106323
+ },
+ "Component_[15319816472229733542]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 15319816472229733542
+ },
+ "Component_[16299889256965403184]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 16299889256965403184,
+ "Parent Entity": "Entity_[1081216208506]"
+ },
+ "Component_[16493827350222098538]": {
+ "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+ "Id": 16493827350222098538,
+ "Controller": {
+ "Configuration": {
+ "CubemapAsset": {
+ "assetId": {
+ "guid": "{B78C84E9-45BE-5A50-8898-177B33B8DA84}",
+ "subId": 2000
+ },
+ "assetHint": "envhdri/photo_studio_01_4k_iblskyboxcm_iblspecular.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[16719262120090148450]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 16719262120090148450
+ },
+ "Component_[16793670898160667741]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 16793670898160667741
+ },
+ "Component_[18257477315946306250]": {
+ "$type": "AZ::Render::EditorImageBasedLightComponent",
+ "Id": 18257477315946306250,
+ "Controller": {
+ "Configuration": {
+ "diffuseImageAsset": {
+ "assetId": {
+ "guid": "{B78C84E9-45BE-5A50-8898-177B33B8DA84}",
+ "subId": 3000
+ },
+ "assetHint": "envhdri/photo_studio_01_4k_iblskyboxcm_ibldiffuse.exr.streamingimage"
+ },
+ "specularImageAsset": {
+ "assetId": {
+ "guid": "{B78C84E9-45BE-5A50-8898-177B33B8DA84}",
+ "subId": 2000
+ },
+ "assetHint": "envhdri/photo_studio_01_4k_iblskyboxcm_iblspecular.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[4042063241506989985]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 4042063241506989985
+ },
+ "Component_[4043099982625130775]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 4043099982625130775
+ },
+ "Component_[5787212845085960464]": {
+ "$type": "SelectionComponent",
+ "Id": 5787212845085960464
+ },
+ "Component_[7736270313311953442]": {
+ "$type": "EditorLockComponent",
+ "Id": 7736270313311953442
+ },
+ "Component_[9830936955971178632]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 9830936955971178632
+ }
+ }
+ },
+ "Entity_[1111280979578]": {
+ "Id": "Entity_[1111280979578]",
+ "Name": "DirectionalLight_01",
+ "Components": {
+ "Component_[10555827406016705179]": {
+ "$type": "AZ::Render::EditorDirectionalLightComponent",
+ "Id": 10555827406016705179,
+ "Controller": {
+ "Configuration": {
+ "Intensity": 2.700000047683716,
+ "CameraEntityId": "",
+ "ShadowmapSize": "Size2048",
+ "ShadowFilterMethod": 3
+ }
+ }
+ },
+ "Component_[10958643723292926203]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 10958643723292926203
+ },
+ "Component_[11446130315244380400]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 11446130315244380400
+ },
+ "Component_[13236945310915796893]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 13236945310915796893
+ },
+ "Component_[1489806191674568397]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 1489806191674568397
+ },
+ "Component_[5250190904313425540]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 5250190904313425540
+ },
+ "Component_[6777228833367576785]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 6777228833367576785
+ },
+ "Component_[7346763132239097919]": {
+ "$type": "SelectionComponent",
+ "Id": 7346763132239097919
+ },
+ "Component_[7453645446520457790]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7453645446520457790,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ 2.5331368446350098,
+ 10.560922622680664,
+ -5.415566921234131
+ ],
+ "Rotate": [
+ -103.25949096679688,
+ -1.1917028427124023,
+ 9.752097129821777
+ ]
+ }
+ },
+ "Component_[7712714857312986803]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7712714857312986803
+ },
+ "Component_[9180065208679807523]": {
+ "$type": "EditorLockComponent",
+ "Id": 9180065208679807523
+ }
+ }
+ },
+ "Entity_[1115575946874]": {
+ "Id": "Entity_[1115575946874]",
+ "Name": "DiffuseGI_02",
+ "Components": {
+ "Component_[10817704949085277229]": {
+ "$type": "EditorLockComponent",
+ "Id": 10817704949085277229
+ },
+ "Component_[11636460237576493708]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11636460237576493708
+ },
+ "Component_[16774608348754201693]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 16774608348754201693
+ },
+ "Component_[17994425379406278407]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 17994425379406278407,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ 8.965616226196289,
+ 10.854515075683594,
+ -1.710240364074707
+ ]
+ }
+ },
+ "Component_[3002179259651230640]": {
+ "$type": "AZ::Render::EditorDiffuseProbeGridComponent",
+ "Id": 3002179259651230640,
+ "Controller": {
+ "Configuration": {
+ "Extents": [
+ 21.0,
+ 23.0,
+ 16.0
+ ],
+ "BakedIrradianceTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_02_A78EEAF4-7CB2-4635-AA6F-2ED677328706_Irradiance_lutrgba16.dds",
+ "BakedDistanceTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_02_84D0F8A4-AD4F-4FD1-BA26-4803EAD88FE2_Distance_lutrg32f.dds",
+ "BakedRelocationTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_02_9DC8C208-5327-4F0F-B1DF-C98F7F81F07D_Relocation_lutrgba16f.dds",
+ "BakedClassificationTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_02_222F1F65-BF31-4E0D-9957-14AE73194A37_Classification_lutr32f.dds",
+ "BakedIrradianceTextureAsset": {
+ "assetId": {
+ "guid": "{5B66D8B5-E4AE-5571-A551-1D21333519A0}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_02_a78eeaf4-7cb2-4635-aa6f-2ed677328706_irradiance_lutrgba16.dds.streamingimage"
+ },
+ "BakedDistanceTextureAsset": {
+ "assetId": {
+ "guid": "{B75364AF-D0AC-5E8C-A3B0-EBAFB063D6C3}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_02_84d0f8a4-ad4f-4fd1-ba26-4803ead88fe2_distance_lutrg32f.dds.streamingimage"
+ },
+ "BakedRelocationTextureAsset": {
+ "assetId": {
+ "guid": "{CB803781-B18A-51CE-AF8C-DF24FC48160B}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_02_9dc8c208-5327-4f0f-b1df-c98f7f81f07d_relocation_lutrgba16f.dds.streamingimage"
+ },
+ "BakedClassificationTextureAsset": {
+ "assetId": {
+ "guid": "{D4B4F7E6-3B39-58BE-B8E9-7D057EF9A1F9}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_02_222f1f65-bf31-4e0d-9957-14ae73194a37_classification_lutr32f.dds.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[4937167128415130244]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 4937167128415130244
+ },
+ "Component_[544440683292345740]": {
+ "$type": "EditorAxisAlignedBoxShapeComponent",
+ "Id": 544440683292345740,
+ "DisplayFilled": false,
+ "AxisAlignedBoxShape": {
+ "Configuration": {
+ "IsFilled": false,
+ "Dimensions": [
+ 21.0,
+ 23.0,
+ 16.0
+ ]
+ }
+ }
+ },
+ "Component_[578950453122763358]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 578950453122763358
+ },
+ "Component_[6950664630097923667]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 6950664630097923667
+ },
+ "Component_[7122880078686807527]": {
+ "$type": "SelectionComponent",
+ "Id": 7122880078686807527
+ },
+ "Component_[800320972776069167]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 800320972776069167
+ },
+ "Component_[8383621918310482787]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 8383621918310482787
+ }
+ }
+ },
+ "Entity_[1119870914170]": {
+ "Id": "Entity_[1119870914170]",
+ "Name": "DiffuseGI_01",
+ "Components": {
+ "Component_[12209861770686976090]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 12209861770686976090
+ },
+ "Component_[15353835329112294192]": {
+ "$type": "AZ::Render::EditorDiffuseProbeGridComponent",
+ "Id": 15353835329112294192,
+ "Controller": {
+ "Configuration": {
+ "Extents": [
+ 21.0,
+ 23.0,
+ 16.0
+ ],
+ "BakedIrradianceTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_01_1B66C428-1D7C-4A53-BC9B-6F23E420FEC0_Irradiance_lutrgba16.dds",
+ "BakedDistanceTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_01_5A2C9A6B-F914-4D9E-8098-2AD411B69F87_Distance_lutrg32f.dds",
+ "BakedRelocationTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_01_52D75B1C-90BE-40A8-A874-3376F6B39299_Relocation_lutrgba16f.dds",
+ "BakedClassificationTextureRelativePath": "DiffuseProbeGrids/DiffuseGI_01_A483018F-78ED-4814-986F-F925B0AA5EF8_Classification_lutr32f.dds",
+ "BakedIrradianceTextureAsset": {
+ "assetId": {
+ "guid": "{458A2A6C-6DEA-5D69-99B5-49A4F227C0A8}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_01_1b66c428-1d7c-4a53-bc9b-6f23e420fec0_irradiance_lutrgba16.dds.streamingimage"
+ },
+ "BakedDistanceTextureAsset": {
+ "assetId": {
+ "guid": "{9CB9A440-9BB1-56CA-B988-35FCF667F993}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_01_5a2c9a6b-f914-4d9e-8098-2ad411b69f87_distance_lutrg32f.dds.streamingimage"
+ },
+ "BakedRelocationTextureAsset": {
+ "assetId": {
+ "guid": "{DD6EB8D0-B68D-5AB8-B781-8E702F57C07D}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_01_52d75b1c-90be-40a8-a874-3376f6b39299_relocation_lutrgba16f.dds.streamingimage"
+ },
+ "BakedClassificationTextureAsset": {
+ "assetId": {
+ "guid": "{17D2178C-D102-5B11-B54C-A5EB233B570F}",
+ "subId": 1000
+ },
+ "assetHint": "diffuseprobegrids/diffusegi_01_a483018f-78ed-4814-986f-f925b0aa5ef8_classification_lutr32f.dds.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[15878232015065363455]": {
+ "$type": "EditorAxisAlignedBoxShapeComponent",
+ "Id": 15878232015065363455,
+ "DisplayFilled": false,
+ "AxisAlignedBoxShape": {
+ "Configuration": {
+ "IsFilled": false,
+ "Dimensions": [
+ 21.0,
+ 23.0,
+ 16.0
+ ]
+ }
+ }
+ },
+ "Component_[17684272660747914090]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 17684272660747914090
+ },
+ "Component_[6724702399933727508]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6724702399933727508,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ -9.077760696411133,
+ 10.860031127929688,
+ -1.7297496795654297
+ ]
+ }
+ },
+ "Component_[6821316397695137380]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 6821316397695137380
+ },
+ "Component_[7220674190610508127]": {
+ "$type": "SelectionComponent",
+ "Id": 7220674190610508127
+ },
+ "Component_[7255528083818713568]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7255528083818713568
+ },
+ "Component_[7481484881559898788]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 7481484881559898788
+ },
+ "Component_[7524464908826669595]": {
+ "$type": "EditorLockComponent",
+ "Id": 7524464908826669595
+ },
+ "Component_[8325378114504743847]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 8325378114504743847
+ },
+ "Component_[997706187713882733]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 997706187713882733
+ }
+ }
+ },
+ "Entity_[1613792153210]": {
+ "Id": "Entity_[1613792153210]",
+ "Name": "Bloom",
+ "Components": {
+ "Component_[10907847005341580620]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 10907847005341580620
+ },
+ "Component_[12758150889799563454]": {
+ "$type": "SelectionComponent",
+ "Id": 12758150889799563454
+ },
+ "Component_[13247037123089245326]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 13247037123089245326
+ },
+ "Component_[14642483781584474817]": {
+ "$type": "EditorLockComponent",
+ "Id": 14642483781584474817
+ },
+ "Component_[17298230148657754532]": {
+ "$type": "AZ::Render::EditorBloomComponent",
+ "Id": 17298230148657754532,
+ "Controller": {
+ "Configuration": {
+ "Enabled": true,
+ "Intensity": 0.20000000298023224
+ }
+ }
+ },
+ "Component_[18357464390083641697]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 18357464390083641697
+ },
+ "Component_[2912267744881101414]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 2912267744881101414
+ },
+ "Component_[3110194465577429301]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 3110194465577429301
+ },
+ "Component_[5583330531036127211]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 5583330531036127211
+ },
+ "Component_[6528482372370936011]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 6528482372370936011
+ },
+ "Component_[6944819497695081730]": {
+ "$type": "AZ::Render::EditorPostFxLayerComponent",
+ "Id": 6944819497695081730
+ },
+ "Component_[8401224278912231908]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 8401224278912231908,
+ "Parent Entity": "Entity_[1081216208506]",
+ "Transform Data": {
+ "Translate": [
+ -9.137216567993164,
+ 8.613965034484863,
+ -6.547377586364746
+ ]
+ }
+ }
+ }
+ },
+ "Entity_[935187320442]": {
+ "Id": "Entity_[935187320442]",
+ "Name": "GEO_Sponza",
+ "Components": {
+ "Component_[10397152383962473889]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 10397152383962473889
+ },
+ "Component_[10403905564538530551]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 10403905564538530551
+ },
+ "Component_[1212647033037288333]": {
+ "$type": "SelectionComponent",
+ "Id": 1212647033037288333
+ },
+ "Component_[13446466918421510411]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13446466918421510411
+ },
+ "Component_[14976154143417033372]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 14976154143417033372,
+ "Controller": {
+ "Configuration": {
+ "materials": [
+ {
+ "Key": {
+ "materialSlotStableId": 333178618
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{BE4DBB1D-16BA-5D82-9865-58904BAFD500}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_columna.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 338114910
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{CE74A12B-9D17-5C84-8118-9F071E61AF82}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_curtaingreen.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 775278732
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{31A90D34-8E36-5A69-AF65-CEC3776F4BD4}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_fabricblue.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 856448979
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{7EDE4FB5-7629-5EA7-942B-DF4404F7F1BF}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_lion.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 919776125
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{BA39AE42-222C-5965-868C-1A1D7ACD3B8B}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_arch.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 1207315403
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{0B8E109B-F295-544E-A360-193D435E9CE7}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_bricks.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 1802255958
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{31EDB842-C01F-53C3-BA5B-ABE47AE4202E}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_roof.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 2017475302
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{96768574-B7E8-5AB1-A1D6-41A1FA817749}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_vaseround.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 2070928957
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{5E3B1B14-DD87-56A9-AF68-58E17A98DAA4}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_vase.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 2207162385
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{5E8EF668-45AD-5ADA-99CB-37F0BD155282}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_vaseplant.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 2270338210
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{7D57D2FA-CC79-5A05-B89D-A821A69E06AA}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_fabricgreen.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 2309916823
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{66472C16-905D-58D3-A2FF-189D0D81A72C}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_fabricred.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 2590157792
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{B064CDF8-E63A-50FE-82C7-F73863C6BAE7}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_floor.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 2958866002
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{C4EF81AF-6924-51F9-B653-374FDEEF2DFF}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_background.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3018304250
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{348EBEE6-9480-5284-8427-F3503D835C7A}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_details.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3091600944
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{1D82B774-8649-53B8-89B8-38392145D0B3}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_columnb.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3123792718
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{9ADCD89D-834D-5894-9829-81A938408C56}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_ceiling.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3332811907
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{6DC9F913-16C6-58D4-9E62-7C1BD2F17BAA}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_flagpole.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3597278613
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{CC0ED9DC-03DD-5BC3-97C7-30FCC53AB6D3}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_curtainred.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3682637945
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{0E6CFBCB-8A02-5BF8-A7BF-F367D729E343}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_curtainblue.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3761550797
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{8889EE6F-29FD-56D6-806A-77ED795F25E1}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_vasehanging.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3856935901
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{B44690C5-30A3-5B6B-8785-E51111965AFC}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_columnc.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 3861299630
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{674F363F-C927-5977-8215-4B7E9D3D7E5A}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_leaf.azmaterial"
+ }
+ }
+ },
+ {
+ "Key": {
+ "materialSlotStableId": 4043076162
+ },
+ "Value": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{73D2E54D-AA36-5EE3-818D-A627A014FE15}"
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza_mat_chain.azmaterial"
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ "Component_[17881751166570014482]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 17881751166570014482
+ },
+ "Component_[1890254654486049633]": {
+ "$type": "EditorLockComponent",
+ "Id": 1890254654486049633
+ },
+ "Component_[2265788496878584641]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 2265788496878584641
+ },
+ "Component_[4234266794358802507]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 4234266794358802507
+ },
+ "Component_[7538889219751513244]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 7538889219751513244,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{0E91A4B4-9A13-56A1-8007-4F9594DFB8FC}",
+ "subId": 282066894
+ },
+ "assetHint": "gem/sponza/assets/objects/sponza.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[8795821630604550348]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 8795821630604550348
+ },
+ "Component_[972437945687475257]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 972437945687475257,
+ "Parent Entity": "Entity_[406217483857]"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/Sponza/tags.txt b/AutomatedTesting/Levels/Sponza/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/Sponza/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/ReflectionProbes/ReflectionProbe_Lion__CA20BB89-1587-4410-80BA-8150CB0EF47B__iblspecularcm512.dds b/AutomatedTesting/ReflectionProbes/ReflectionProbe_Lion__CA20BB89-1587-4410-80BA-8150CB0EF47B__iblspecularcm512.dds
new file mode 100644
index 0000000000..86dea1906c
--- /dev/null
+++ b/AutomatedTesting/ReflectionProbes/ReflectionProbe_Lion__CA20BB89-1587-4410-80BA-8150CB0EF47B__iblspecularcm512.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d65e361a150417b56fa88ac2171bbef6512f526a15695fdc52a446a7f891c593
+size 50331796
diff --git a/AutomatedTesting/ReflectionProbes/ReflectionProbe_Scene__D245F488-152E-4A3A-898B-FBCF71E4A87A__iblspecularcm256.dds b/AutomatedTesting/ReflectionProbes/ReflectionProbe_Scene__D245F488-152E-4A3A-898B-FBCF71E4A87A__iblspecularcm256.dds
new file mode 100644
index 0000000000..536270c531
--- /dev/null
+++ b/AutomatedTesting/ReflectionProbes/ReflectionProbe_Scene__D245F488-152E-4A3A-898B-FBCF71E4A87A__iblspecularcm256.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8c3fbf2f491048ed05ff1ea15728afd2fbc059880d0e61efb8c557cf97ebaae4
+size 50331796
diff --git a/AutomatedTesting/ReflectionProbes/ReflectionProbe_UpperLevel__4DABA7BF-9367-4D95-AA5F-A9BF6BA0F7BE__iblspecularcm512.dds b/AutomatedTesting/ReflectionProbes/ReflectionProbe_UpperLevel__4DABA7BF-9367-4D95-AA5F-A9BF6BA0F7BE__iblspecularcm512.dds
new file mode 100644
index 0000000000..bb00476697
--- /dev/null
+++ b/AutomatedTesting/ReflectionProbes/ReflectionProbe_UpperLevel__4DABA7BF-9367-4D95-AA5F-A9BF6BA0F7BE__iblspecularcm512.dds
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9f142022323102e4225afc2f9b44b6631683691d180fdf4586bce34f1fd13a76
+size 50331796
diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp
index d5f2305dfb..3890a9e59a 100644
--- a/Code/Editor/CryEdit.cpp
+++ b/Code/Editor/CryEdit.cpp
@@ -2810,14 +2810,11 @@ void CCryEditApp::OpenProjectManager(const AZStd::string& screen)
{
// provide the current project path for in case we want to update the project
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
-#if !AZ_TRAIT_OS_PLATFORM_APPLE && !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS
- const char* argumentQuoteString = R"(")";
-#else
- const char* argumentQuoteString = R"(\")";
-#endif
- const AZStd::string commandLineOptions = AZStd::string::format(R"( --screen %s --project-path %s%s%s)",
- screen.c_str(),
- argumentQuoteString, projectPath.c_str(), argumentQuoteString);
+
+ const AZStd::vector commandLineOptions {
+ "--screen", screen,
+ "--project-path", AZStd::string::format(R"("%s")", projectPath.c_str()) };
+
bool launchSuccess = AzFramework::ProjectManager::LaunchProjectManager(commandLineOptions);
if (!launchSuccess)
{
diff --git a/Code/Editor/EditorModularViewportCameraComposer.cpp b/Code/Editor/EditorModularViewportCameraComposer.cpp
index f145adf72f..3f66468584 100644
--- a/Code/Editor/EditorModularViewportCameraComposer.cpp
+++ b/Code/Editor/EditorModularViewportCameraComposer.cpp
@@ -356,7 +356,8 @@ namespace SandboxEditor
AZ::TransformBus::EventResult(worldFromLocal, viewEntityId, &AZ::TransformBus::Events::GetWorldTM);
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
- m_viewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StartTrackingTransform, worldFromLocal);
+ m_viewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::StartTrackingTransform,
+ worldFromLocal);
}
else
{
@@ -367,8 +368,10 @@ namespace SandboxEditor
void EditorModularViewportCameraComposer::OnTick(const float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
{
- const float delta = [duration = &ed_cameraDefaultOrbitFadeDuration, deltaTime] {
- if (*duration == 0.0f) {
+ const float delta = [duration = &ed_cameraDefaultOrbitFadeDuration, deltaTime]
+ {
+ if (*duration == 0.0f)
+ {
return 1.0f;
}
return deltaTime / *duration;
diff --git a/Code/Editor/GotoPositionDlg.cpp b/Code/Editor/GotoPositionDlg.cpp
index 84d149de58..37f55f19ea 100644
--- a/Code/Editor/GotoPositionDlg.cpp
+++ b/Code/Editor/GotoPositionDlg.cpp
@@ -6,7 +6,6 @@
*
*/
-
#include "GotoPositionDlg.h"
#include "EditorDefs.h"
@@ -25,6 +24,17 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
#include
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
+void GotoPositionPitchConstraints::DeterminePitchRange(const AngleRangeConfigureFn& configurePitchRangeFn) const
+{
+ const auto [pitchMinRadians, pitchMaxRadians] = AzFramework::CameraPitchMinMaxRadians();
+ configurePitchRangeFn(AZ::RadToDeg(pitchMinRadians), AZ::RadToDeg(pitchMaxRadians));
+}
+
+float GotoPositionPitchConstraints::PitchClampedRadians(float pitchDegrees) const
+{
+ return AzFramework::ClampPitchRotation(AZ::DegToRad(pitchDegrees));
+}
+
GotoPositionDialog::GotoPositionDialog(QWidget* parent)
: QDialog(parent)
, m_ui(new Ui::GotoPositionDialog)
@@ -55,20 +65,23 @@ void GotoPositionDialog::OnInitDialog()
const auto yawDegrees = AZ::RadToDeg(cameraRotation.GetZ());
// position
- m_ui->m_dymX->setRange(-64000.0, 64000.0);
+ const double CameraPositionExtent = 64000.0;
+ m_ui->m_dymX->setRange(-CameraPositionExtent, CameraPositionExtent);
m_ui->m_dymX->setValue(cameraTranslation.GetX());
-
- m_ui->m_dymY->setRange(-64000.0, 64000.0);
+ m_ui->m_dymY->setRange(-CameraPositionExtent, CameraPositionExtent);
m_ui->m_dymY->setValue(cameraTranslation.GetY());
-
- m_ui->m_dymZ->setRange(-64000.0, 64000.0);
+ m_ui->m_dymZ->setRange(-CameraPositionExtent, CameraPositionExtent);
m_ui->m_dymZ->setValue(cameraTranslation.GetZ());
// rotation
- m_ui->m_dymAnglePitch->setRange(-180.0, 180.0);
+ m_gotoPositionPitchConstraints.DeterminePitchRange(
+ [this](const float minPitchDegrees, const float maxPitchDegrees)
+ {
+ m_ui->m_dymAnglePitch->setRange(minPitchDegrees, maxPitchDegrees);
+ });
m_ui->m_dymAnglePitch->setValue(pitchDegrees);
- m_ui->m_dymAngleYaw->setRange(-180.0, 180.0);
+ m_ui->m_dymAngleYaw->setRange(-360, 360);
m_ui->m_dymAngleYaw->setValue(yawDegrees);
// ensure the goto button is highlighted correctly.
@@ -108,12 +121,13 @@ void GotoPositionDialog::OnUpdateNumbers()
void GotoPositionDialog::accept()
{
- SandboxEditor::InterpolateDefaultViewportCameraToTransform(
- AZ::Vector3(
- aznumeric_cast(m_ui->m_dymX->value()), aznumeric_cast(m_ui->m_dymY->value()),
- aznumeric_cast(m_ui->m_dymZ->value())),
- AZ::DegToRad(aznumeric_cast(m_ui->m_dymAnglePitch->value())),
- AZ::DegToRad(aznumeric_cast(m_ui->m_dymAngleYaw->value())));
+ const auto position = AZ::Vector3(
+ aznumeric_cast(m_ui->m_dymX->value()), aznumeric_cast(m_ui->m_dymY->value()),
+ aznumeric_cast(m_ui->m_dymZ->value()));
+ const auto pitchRadians = m_gotoPositionPitchConstraints.PitchClampedRadians(aznumeric_cast(m_ui->m_dymAnglePitch->value()));
+ const auto yawRadians = AZ::DegToRad(aznumeric_cast(m_ui->m_dymAngleYaw->value()));
+
+ SandboxEditor::InterpolateDefaultViewportCameraToTransform(position, pitchRadians, yawRadians);
QDialog::accept();
}
diff --git a/Code/Editor/GotoPositionDlg.h b/Code/Editor/GotoPositionDlg.h
index ef46b9cbc8..5b627fcebb 100644
--- a/Code/Editor/GotoPositionDlg.h
+++ b/Code/Editor/GotoPositionDlg.h
@@ -6,21 +6,33 @@
*
*/
-
#pragma once
#if !defined(Q_MOC_RUN)
#include
#endif
+#include
+
+#include
+
namespace Ui
{
class GotoPositionDialog;
}
+//! Utility to deal with ensuring camera pitch values are in the expected range.
+struct GotoPositionPitchConstraints
+{
+ using AngleRangeConfigureFn = AZStd::function;
+ //! Notify a callback with the min and max camera pitch constraints (no tolerance included).
+ SANDBOX_API void DeterminePitchRange(const AngleRangeConfigureFn& configurePitchRangeFn) const;
+ //! Returns the clamped pitch value (including tolerance with range extents).
+ SANDBOX_API float PitchClampedRadians(float pitchDegrees) const;
+};
+
//! GotoPositionDialog for setting camera position and rotation.
-class GotoPositionDialog
- : public QDialog
+class GotoPositionDialog : public QDialog
{
Q_OBJECT
@@ -39,5 +51,6 @@ public:
QString m_transform;
private:
+ GotoPositionPitchConstraints m_gotoPositionPitchConstraints;
QScopedPointer m_ui;
};
diff --git a/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp b/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp
index dd7698a82e..0dcda3be33 100644
--- a/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp
+++ b/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp
@@ -15,6 +15,8 @@
#include
#include
+#include
+
namespace UnitTest
{
class EditorCameraFixture : public ::testing::Test
@@ -257,4 +259,35 @@ namespace UnitTest
EXPECT_THAT(interpolating, ::testing::IsFalse());
EXPECT_THAT(nextInterpolationBegan, ::testing::IsTrue());
}
+
+ TEST(GotoPositionPitchConstraints, GoToPositionPitchIsSetToPlusOrMinusNinetyDegrees)
+ {
+ float minPitch = 0.0f;
+ float maxPitch = 0.0f;
+
+ GotoPositionPitchConstraints m_gotoPositionContraints;
+ m_gotoPositionContraints.DeterminePitchRange(
+ [&minPitch, &maxPitch](const float minPitchDegrees, const float maxPitchDegrees)
+ {
+ minPitch = minPitchDegrees;
+ maxPitch = maxPitchDegrees;
+ });
+
+ using ::testing::FloatNear;
+ EXPECT_THAT(minPitch, FloatNear(-90.0f, AZ::Constants::FloatEpsilon));
+ EXPECT_THAT(maxPitch, FloatNear(90.0f, AZ::Constants::FloatEpsilon));
+ }
+
+ TEST(GotoPositionPitchConstraints, GoToPositionPitchClampsFinalPitchValueWithTolerance)
+ {
+ const auto [expectedMinPitchRadians, expectedMaxPitchRadians] = AzFramework::CameraPitchMinMaxRadiansWithTolerance();
+
+ GotoPositionPitchConstraints m_gotoPositionContraints;
+ const float minClampedPitchRadians = m_gotoPositionContraints.PitchClampedRadians(-90.0f);
+ const float maxClampedPitchRadians = m_gotoPositionContraints.PitchClampedRadians(90.0f);
+
+ using ::testing::FloatNear;
+ EXPECT_THAT(minClampedPitchRadians, FloatNear(expectedMinPitchRadians, AZ::Constants::FloatEpsilon));
+ EXPECT_THAT(maxClampedPitchRadians, FloatNear(expectedMaxPitchRadians, AZ::Constants::FloatEpsilon));
+ }
} // namespace UnitTest
diff --git a/Code/Editor/Lib/Tests/test_ClickableLabel.cpp b/Code/Editor/Lib/Tests/test_ClickableLabel.cpp
index 905e91b64c..a676714992 100644
--- a/Code/Editor/Lib/Tests/test_ClickableLabel.cpp
+++ b/Code/Editor/Lib/Tests/test_ClickableLabel.cpp
@@ -19,7 +19,7 @@ using namespace ::testing;
namespace UnitTest
{
class TestingClickableLabel
- : public testing::Test
+ : public ScopedAllocatorSetupFixture
{
public:
ClickableLabel m_clickableLabel;
diff --git a/Code/Editor/Lib/Tests/test_CryEditDocPythonBindings.cpp b/Code/Editor/Lib/Tests/test_CryEditDocPythonBindings.cpp
index f4e029cb7a..5bab9cb24b 100644
--- a/Code/Editor/Lib/Tests/test_CryEditDocPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_CryEditDocPythonBindings.cpp
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
@@ -22,7 +23,7 @@ namespace CryEditDocPythonBindingsUnitTests
{
class CryEditDocPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +31,6 @@ namespace CryEditDocPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_CryEditPythonBindings.cpp b/Code/Editor/Lib/Tests/test_CryEditPythonBindings.cpp
index 30afa07304..5246fcdee5 100644
--- a/Code/Editor/Lib/Tests/test_CryEditPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_CryEditPythonBindings.cpp
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
@@ -24,7 +25,7 @@ namespace CryEditPythonBindingsUnitTests
{
class CryEditPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -32,7 +33,6 @@ namespace CryEditPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp b/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp
index e6af0bdeff..fd65634d4e 100644
--- a/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp
@@ -11,6 +11,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -22,7 +24,7 @@ namespace DisplaySettingsPythonBindingsUnitTests
{
class DisplaySettingsPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +32,6 @@ namespace DisplaySettingsPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
m_app.RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsPythonFuncsHandler::CreateDescriptor());
@@ -52,7 +53,7 @@ namespace DisplaySettingsPythonBindingsUnitTests
}
class DisplaySettingsComponentFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -60,10 +61,14 @@ namespace DisplaySettingsPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
m_app.RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsComponent::CreateDescriptor());
+
+ // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
+ // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
+ // in the unit tests.
+ AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
}
void TearDown() override
diff --git a/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp b/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp
index de0eb5df6f..49b65f7ffc 100644
--- a/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -79,7 +80,7 @@ namespace EditorPythonBindingsUnitTests
};
class EditorPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -87,7 +88,6 @@ namespace EditorPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_EditorUtils.cpp b/Code/Editor/Lib/Tests/test_EditorUtils.cpp
index 3556757ae3..c0515a77ad 100644
--- a/Code/Editor/Lib/Tests/test_EditorUtils.cpp
+++ b/Code/Editor/Lib/Tests/test_EditorUtils.cpp
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
namespace EditorUtilsTest
{
@@ -39,7 +40,7 @@ namespace EditorUtilsTest
class TestWarningAbsorber
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
};
diff --git a/Code/Editor/Lib/Tests/test_MainWindowPythonBindings.cpp b/Code/Editor/Lib/Tests/test_MainWindowPythonBindings.cpp
index 3963ae990f..e3268704bc 100644
--- a/Code/Editor/Lib/Tests/test_MainWindowPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_MainWindowPythonBindings.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -22,7 +23,7 @@ namespace MainWindowPythonBindingsUnitTests
{
class MainWindowPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +31,6 @@ namespace MainWindowPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_ObjectManagerPythonBindings.cpp b/Code/Editor/Lib/Tests/test_ObjectManagerPythonBindings.cpp
index 64b7d36d30..6766b6a1fa 100644
--- a/Code/Editor/Lib/Tests/test_ObjectManagerPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_ObjectManagerPythonBindings.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -22,7 +23,7 @@ namespace ObjectManagerPythonBindingsUnitTests
{
class ObjectManagerPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +31,6 @@ namespace ObjectManagerPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_TerrainHoleToolPythonBindings.cpp b/Code/Editor/Lib/Tests/test_TerrainHoleToolPythonBindings.cpp
index e163004d75..fc292b1f52 100644
--- a/Code/Editor/Lib/Tests/test_TerrainHoleToolPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_TerrainHoleToolPythonBindings.cpp
@@ -23,7 +23,7 @@ namespace TerrainFuncsUnitTests
{
class TerrainHoleToolPythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -31,7 +31,6 @@ namespace TerrainFuncsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_TerrainLayerPythonBindings.cpp b/Code/Editor/Lib/Tests/test_TerrainLayerPythonBindings.cpp
index ad7baa44a5..3296572ed2 100644
--- a/Code/Editor/Lib/Tests/test_TerrainLayerPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_TerrainLayerPythonBindings.cpp
@@ -23,7 +23,7 @@ namespace TerrainFuncsUnitTests
{
class TerrainLayerPythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -31,7 +31,6 @@ namespace TerrainFuncsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_TerrainModifyPythonBindings.cpp b/Code/Editor/Lib/Tests/test_TerrainModifyPythonBindings.cpp
index 166e4c0be5..37afbe5f37 100644
--- a/Code/Editor/Lib/Tests/test_TerrainModifyPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_TerrainModifyPythonBindings.cpp
@@ -22,7 +22,7 @@ namespace TerrainModifyPythonBindingsUnitTests
{
class TerrainModifyPythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +30,6 @@ namespace TerrainModifyPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_TerrainPainterPythonBindings.cpp b/Code/Editor/Lib/Tests/test_TerrainPainterPythonBindings.cpp
index 7a2cf786cd..3281da8078 100644
--- a/Code/Editor/Lib/Tests/test_TerrainPainterPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_TerrainPainterPythonBindings.cpp
@@ -23,7 +23,7 @@ namespace TerrainFuncsUnitTests
{
class TerrainPainterPythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -31,7 +31,6 @@ namespace TerrainFuncsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_TerrainPythonBindings.cpp b/Code/Editor/Lib/Tests/test_TerrainPythonBindings.cpp
index 6a0df6b62a..786158afb3 100644
--- a/Code/Editor/Lib/Tests/test_TerrainPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_TerrainPythonBindings.cpp
@@ -23,7 +23,7 @@ namespace TerrainFuncsUnitTests
{
class TerrainPythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -31,7 +31,6 @@ namespace TerrainFuncsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_TerrainTexturePythonBindings.cpp b/Code/Editor/Lib/Tests/test_TerrainTexturePythonBindings.cpp
index 23d30c0b82..7bd81772e1 100644
--- a/Code/Editor/Lib/Tests/test_TerrainTexturePythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_TerrainTexturePythonBindings.cpp
@@ -23,7 +23,7 @@ namespace TerrainFuncsUnitTests
{
class TerrainTexturePythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -31,7 +31,6 @@ namespace TerrainFuncsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_TrackViewPythonBindings.cpp b/Code/Editor/Lib/Tests/test_TrackViewPythonBindings.cpp
index 88a4b4f63f..558bdaaabc 100644
--- a/Code/Editor/Lib/Tests/test_TrackViewPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_TrackViewPythonBindings.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -22,7 +23,7 @@ namespace TrackViewPythonBindingsUnitTests
{
class TrackViewPythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +31,6 @@ namespace TrackViewPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
@@ -82,7 +82,7 @@ namespace TrackViewPythonBindingsUnitTests
}
class TrackViewComponentFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -90,7 +90,6 @@ namespace TrackViewPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
m_app.RegisterComponentDescriptor(AzToolsFramework::TrackViewComponent::CreateDescriptor());
diff --git a/Code/Editor/Lib/Tests/test_ViewPanePythonBindings.cpp b/Code/Editor/Lib/Tests/test_ViewPanePythonBindings.cpp
index 88ce6d5767..047cea3aad 100644
--- a/Code/Editor/Lib/Tests/test_ViewPanePythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_ViewPanePythonBindings.cpp
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
@@ -22,7 +23,7 @@ namespace ViewPaneFuncsUnitTests
{
class ViewPanePythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +31,6 @@ namespace ViewPaneFuncsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Lib/Tests/test_ViewportTitleDlgPythonBindings.cpp b/Code/Editor/Lib/Tests/test_ViewportTitleDlgPythonBindings.cpp
index c3d6be1fdd..c3f7fe35f5 100644
--- a/Code/Editor/Lib/Tests/test_ViewportTitleDlgPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_ViewportTitleDlgPythonBindings.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -22,7 +23,7 @@ namespace ViewportTitleDlgFuncsUnitTests
{
class ViewportTitleDlgPythonBindingsFixture
- : public testing::Test
+ : public UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +31,6 @@ namespace ViewportTitleDlgFuncsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
index 9342c17a37..d5b903585e 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
@@ -41,6 +41,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -208,6 +209,9 @@ void SandboxIntegrationManager::Setup()
m_editorEntityAPI = AZ::Interface::Get();
AZ_Assert(m_editorEntityAPI, "SandboxIntegrationManager requires an EditorEntityAPI instance to be present on Setup().");
+ m_readOnlyEntityPublicInterface = AZ::Interface::Get();
+ AZ_Assert(m_readOnlyEntityPublicInterface, "SandboxIntegrationManager requires an ReadOnlyEntityPublicInterface instance to be present on Setup().");
+
AzToolsFramework::Layers::EditorLayerComponentNotificationBus::Handler::BusConnect();
}
@@ -658,15 +662,17 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
// when a single entity is selected, entity is created as its child
else if (selected.size() == 1)
{
+ AZ::EntityId selectedEntityId = selected.front();
+ bool selectedEntityIsReadOnly = m_readOnlyEntityPublicInterface->IsReadOnly(selectedEntityId);
auto containerEntityInterface = AZ::Interface::Get();
- if (!prefabSystemEnabled || (containerEntityInterface && containerEntityInterface->IsContainerOpen(selected.front())))
+ if (!prefabSystemEnabled || (containerEntityInterface && containerEntityInterface->IsContainerOpen(selectedEntityId) && !selectedEntityIsReadOnly))
{
action = menu->addAction(QObject::tr("Create entity"));
QObject::connect(
action, &QAction::triggered, action,
- [selected]
+ [selectedEntityId]
{
- AzToolsFramework::EditorRequestBus::Broadcast(&AzToolsFramework::EditorRequestBus::Handler::CreateNewEntityAsChild, selected.front());
+ AzToolsFramework::EditorRequestBus::Broadcast(&AzToolsFramework::EditorRequestBus::Handler::CreateNewEntityAsChild, selectedEntityId);
}
);
}
@@ -691,11 +697,27 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
SetupSliceContextMenu(menu);
}
- action = menu->addAction(QObject::tr("Duplicate"));
- QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_Duplicate(); });
- if (selected.size() == 0)
+ if (!selected.empty())
{
- action->setDisabled(true);
+ // Don't allow duplication if any of the selected entities are direct desendants of a read-only entity
+ bool selectionContainsDescendantOfReadOnlyEntity = false;
+ for (const auto& entityId : selected)
+ {
+ AZ::EntityId parentEntityId;
+ AZ::TransformBus::EventResult(parentEntityId, entityId, &AZ::TransformBus::Events::GetParentId);
+
+ if (parentEntityId.IsValid() && m_readOnlyEntityPublicInterface->IsReadOnly(parentEntityId))
+ {
+ selectionContainsDescendantOfReadOnlyEntity = true;
+ break;
+ }
+ }
+
+ if (!selectionContainsDescendantOfReadOnlyEntity)
+ {
+ action = menu->addAction(QObject::tr("Duplicate"));
+ QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_Duplicate(); });
+ }
}
if (!prefabSystemEnabled)
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h
index 7fe2881b92..79e7a4334d 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h
@@ -76,6 +76,7 @@ namespace AzToolsFramework
{
class EditorEntityAPI;
class EditorEntityUiInterface;
+ class ReadOnlyEntityPublicInterface;
namespace AssetBrowser
{
@@ -295,6 +296,7 @@ private:
AzToolsFramework::EditorEntityUiInterface* m_editorEntityUiInterface = nullptr;
AzToolsFramework::Prefab::PrefabIntegrationInterface* m_prefabIntegrationInterface = nullptr;
AzToolsFramework::EditorEntityAPI* m_editorEntityAPI = nullptr;
+ AzToolsFramework::ReadOnlyEntityPublicInterface* m_readOnlyEntityPublicInterface = nullptr;
// Overrides UI styling and behavior for Layer Entities
AzToolsFramework::LayerUiHandler m_layerUiOverrideHandler;
diff --git a/Code/Framework/AtomCore/Tests/Main.cpp b/Code/Framework/AtomCore/Tests/Main.cpp
index eb4c6bc835..728624d427 100644
--- a/Code/Framework/AtomCore/Tests/Main.cpp
+++ b/Code/Framework/AtomCore/Tests/Main.cpp
@@ -37,7 +37,7 @@ namespace AZ
using namespace AZ;
// Handle asserts
-class TraceDrillerHook
+class TestEnvironmentHook
: public AZ::Test::ITestEnvironment
, public UnitTest::TraceBusRedirector
{
@@ -57,5 +57,5 @@ public:
}
};
-AZ_UNIT_TEST_HOOK(new TraceDrillerHook());
+AZ_UNIT_TEST_HOOK(new TestEnvironmentHook());
diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h
index 0b181f6782..2459764e52 100644
--- a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h
+++ b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h
@@ -19,7 +19,6 @@
#include
#include
#include
-#include
#include
namespace AZ
@@ -581,7 +580,6 @@ namespace AZ
template
using ConnectionPolicy = AssetConnectionPolicy;
- using EventProcessingPolicy = Debug::AssetTrackingEventProcessingPolicy<>;
//////////////////////////////////////////////////////////////////////////
virtual ~AssetEvents() {}
diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp
index e419666a32..afe3330bd3 100644
--- a/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp
+++ b/Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp
@@ -10,7 +10,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -164,8 +163,6 @@ namespace AZ::Data
AZ_PROFILE_SCOPE(AzCore, "AZ::Data::LoadAssetJob::Process: %s",
asset.GetHint().c_str());
- AZ_ASSET_ATTACH_TO_SCOPE(this);
-
if (m_owner->ValidateAndRegisterAssetLoading(asset))
{
LoadAndSignal(asset);
@@ -200,7 +197,6 @@ namespace AZ::Data
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(cl_assetLoadDelay));
}
- AZ_ASSET_NAMED_SCOPE(asset.GetHint().c_str());
bool loadedSuccessfully = false;
if (!cl_assetLoadError && m_requestState == AZ::IO::IStreamerTypes::RequestStatus::Completed)
@@ -982,7 +978,6 @@ namespace AZ::Data
}
AZ_PROFILE_SCOPE(AzCore, "GetAsset: %s", assetInfo.m_relativePath.c_str());
- AZ_ASSET_NAMED_SCOPE("GetAsset: %s", assetInfo.m_relativePath.c_str());
AZStd::shared_ptr dataStream;
AssetStreamInfo loadInfo;
diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
index 06cb2c3740..693b2f1648 100644
--- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
+++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
@@ -48,10 +48,6 @@
#include
#include
-#include
-#include
-#include
-#include
#include
#include
@@ -156,7 +152,6 @@ namespace AZ
m_reservedDebug = 0;
m_recordingMode = Debug::AllocationRecords::RECORD_STACK_IF_NO_FILE_LINE;
m_stackRecordLevels = 5;
- m_enableDrilling = false;
m_useOverrunDetection = false;
m_useMalloc = false;
}
@@ -328,7 +323,6 @@ namespace AZ
->Field("blockSize", &Descriptor::m_memoryBlocksByteSize)
->Field("reservedOS", &Descriptor::m_reservedOS)
->Field("reservedDebug", &Descriptor::m_reservedDebug)
- ->Field("enableDrilling", &Descriptor::m_enableDrilling)
->Field("useOverrunDetection", &Descriptor::m_useOverrunDetection)
->Field("useMalloc", &Descriptor::m_useMalloc)
->Field("allocatorRemappings", &Descriptor::m_allocatorRemappings)
@@ -367,7 +361,6 @@ namespace AZ
->Attribute(Edit::Attributes::Step, &Descriptor::m_pageSize)
->DataElement(Edit::UIHandlers::SpinBox, &Descriptor::m_reservedOS, "OS reserved memory", "System memory reserved for OS (used only when 'Allocate all memory at startup' is true)")
->DataElement(Edit::UIHandlers::SpinBox, &Descriptor::m_reservedDebug, "Memory reserved for debugger", "System memory reserved for Debug allocator, like memory tracking (used only when 'Allocate all memory at startup' is true)")
- ->DataElement(Edit::UIHandlers::CheckBox, &Descriptor::m_enableDrilling, "Enable Driller", "Enable Drilling support for the application (ignored in Release builds)")
->DataElement(Edit::UIHandlers::CheckBox, &Descriptor::m_useOverrunDetection, "Use Overrun Detection", "Use the overrun detection memory manager (only available on some platforms, ignored in Release builds)")
->DataElement(Edit::UIHandlers::CheckBox, &Descriptor::m_useMalloc, "Use Malloc", "Use malloc for memory allocations (for memory debugging only, ignored in Release builds)")
;
diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
index f245b5f5da..d53b8e1a4e 100644
--- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
+++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
@@ -41,7 +41,6 @@ namespace AZ
}
namespace AZ::Debug
{
- class DrillerManager;
class LocalFileEventLogger;
}
@@ -143,7 +142,6 @@ namespace AZ
AZ::u64 m_reservedDebug; //!< Reserved memory for Debugging (allocation,etc.). Used only when m_grabAllMemory is set to true. (default: 0)
Debug::AllocationRecords::Mode m_recordingMode; //!< When to record stack traces (default: AZ::Debug::AllocationRecords::RECORD_STACK_IF_NO_FILE_LINE)
AZ::u64 m_stackRecordLevels; //!< If stack recording is enabled, how many stack levels to record. (default: 5)
- bool m_enableDrilling; //!< True to enabled drilling support for the application. RegisterDrillers will be called. Ignored in release. (default: true)
bool m_useOverrunDetection; //!< True to use the overrun detection memory management scheme. Only available on some platforms; greatly increases memory consumption.
bool m_useMalloc; //!< True to use malloc instead of the internal memory manager. Intended for debugging purposes only.
diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h
index feefa95973..10f35d6e00 100644
--- a/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h
+++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h
@@ -37,11 +37,6 @@ namespace AZ
class ComponentFactoryInterface;
}
- namespace Debug
- {
- class DrillerManager;
- }
-
struct ApplicationTypeQuery
{
bool IsEditor() const;
diff --git a/Code/Framework/AzCore/AzCore/Component/Entity.cpp b/Code/Framework/AzCore/AzCore/Component/Entity.cpp
index 0fe201d448..c5cda98f2c 100644
--- a/Code/Framework/AzCore/AzCore/Component/Entity.cpp
+++ b/Code/Framework/AzCore/AzCore/Component/Entity.cpp
@@ -811,12 +811,12 @@ namespace AZ
if (behaviorContext)
{
behaviorContext->Class()
- ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
+ ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "entity")
->Method("IsValid", &EntityId::IsValid)
- ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
+ ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Method("ToString", &EntityId::ToString)
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
diff --git a/Code/Framework/AzCore/AzCore/Component/TickBus.h b/Code/Framework/AzCore/AzCore/Component/TickBus.h
index e65efb93f2..1b588f41cc 100644
--- a/Code/Framework/AzCore/AzCore/Component/TickBus.h
+++ b/Code/Framework/AzCore/AzCore/Component/TickBus.h
@@ -16,7 +16,6 @@
#define AZCORE_COMPONENT_TICK_BUS_H
#include
-#include
#include
#include // For TickBus thread events.
#include
@@ -112,10 +111,6 @@ namespace AZ
AZ_FORCE_INLINE bool operator()(TickEvents* left, TickEvents* right) const { return left->GetTickOrder() < right->GetTickOrder(); }
};
- /**
- * Enable tick bus to work with the AssetTracking
- */
- using EventProcessingPolicy = Debug::AssetTrackingEventProcessingPolicy<>;
//////////////////////////////////////////////////////////////////////////
/**
@@ -217,10 +212,6 @@ namespace AZ
*/
typedef AZStd::mutex EventQueueMutexType;
- /**
- * Enable tick bus to work with the AssetTracking
- */
- using EventProcessingPolicy = Debug::AssetTrackingEventProcessingPolicy<>;
//////////////////////////////////////////////////////////////////////////
/**
diff --git a/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonBackend.h b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonBackend.h
new file mode 100644
index 0000000000..1023796f61
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonBackend.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace AZ::Dom
+{
+ //! A DOM backend for serializing and deserializing JSON <=> UTF-8 text
+ //! \param ParseFlags Controls how deserialized JSON is parsed.
+ //! \param WriteFormat Controls how serialized JSON is formatted.
+ template<
+ Json::ParseFlags ParseFlags = Json::ParseFlags::ParseComments,
+ Json::OutputFormatting WriteFormat = Json::OutputFormatting::PrettyPrintedJson>
+ class JsonBackend final : public Backend
+ {
+ public:
+ Visitor::Result ReadFromBuffer(const char* buffer, size_t size, AZ::Dom::Lifetime lifetime, Visitor& visitor) override
+ {
+ return Json::VisitSerializedJson({ buffer, size }, lifetime, visitor);
+ }
+
+ Visitor::Result ReadFromBufferInPlace(char* buffer, [[maybe_unused]] AZStd::optional size, Visitor& visitor) override
+ {
+ return Json::VisitSerializedJsonInPlace(buffer, visitor);
+ }
+
+ Visitor::Result WriteToBuffer(AZStd::string& buffer, WriteCallback callback)
+ {
+ AZ::IO::ByteContainerStream stream{ &buffer };
+ AZStd::unique_ptr visitor = Json::CreateJsonStreamWriter(stream, WriteFormat);
+ return callback(*visitor);
+ }
+ };
+} // namespace AZ::Dom
diff --git a/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp
new file mode 100644
index 0000000000..17f9bfea54
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.cpp
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace AZ::Dom::Json
+{
+ //
+ // class RapidJsonValueWriter
+ //
+ RapidJsonValueWriter::RapidJsonValueWriter(rapidjson::Value& outputValue, rapidjson::Value::AllocatorType& allocator)
+ : m_result(outputValue)
+ , m_allocator(allocator)
+ {
+ }
+
+ VisitorFlags RapidJsonValueWriter::GetVisitorFlags() const
+ {
+ return VisitorFlags::SupportsRawKeys | VisitorFlags::SupportsArrays | VisitorFlags::SupportsObjects;
+ }
+
+ Visitor::Result RapidJsonValueWriter::Null()
+ {
+ CurrentValue().SetNull();
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::Bool(bool value)
+ {
+ CurrentValue().SetBool(value);
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::Int64(AZ::s64 value)
+ {
+ CurrentValue().SetInt64(value);
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::Uint64(AZ::u64 value)
+ {
+ CurrentValue().SetUint64(value);
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::Double(double value)
+ {
+ CurrentValue().SetDouble(value);
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::String(AZStd::string_view value, Lifetime lifetime)
+ {
+ if (lifetime == Lifetime::Temporary)
+ {
+ CurrentValue().SetString(value.data(), aznumeric_cast(value.length()), m_allocator);
+ }
+ else
+ {
+ CurrentValue().SetString(value.data(), aznumeric_cast(value.length()));
+ }
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::StartObject()
+ {
+ CurrentValue().SetObject();
+
+ const bool isObject = true;
+ m_entryStack.emplace_front(isObject, CurrentValue());
+ return VisitorSuccess();
+ }
+
+ Visitor::Result RapidJsonValueWriter::EndObject(AZ::u64 attributeCount)
+ {
+ if (m_entryStack.empty())
+ {
+ return VisitorFailure(VisitorErrorCode::InternalError, "EndObject called without a matching BeginObject call");
+ }
+
+ const ValueInfo& frontEntry = m_entryStack.front();
+ if (!frontEntry.m_isObject)
+ {
+ return VisitorFailure(VisitorErrorCode::InternalError, "Expected EndArray and received EndObject instead");
+ }
+
+ if (frontEntry.m_entryCount != attributeCount)
+ {
+ return VisitorFailure(
+ VisitorErrorCode::InternalError,
+ AZStd::string::format(
+ "EndObject: Expected %llu attributes but received %llu attributes instead", attributeCount,
+ frontEntry.m_entryCount));
+ }
+
+ m_entryStack.pop_front();
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::Key(AZ::Name key)
+ {
+ return RawKey(key.GetStringView(), Lifetime::Persistent);
+ }
+
+ Visitor::Result RapidJsonValueWriter::RawKey(AZStd::string_view key, Lifetime lifetime)
+ {
+ AZ_Assert(!m_entryStack.empty(), "Attempmted to push a key with no object");
+ AZ_Assert(m_entryStack.front().m_isObject, "Attempted to push a key to an array");
+ if (lifetime == Lifetime::Persistent)
+ {
+ m_entryStack.front().m_key.SetString(key.data(), aznumeric_cast(key.size()));
+ }
+ else
+ {
+ m_entryStack.front().m_key.SetString(key.data(), aznumeric_cast(key.size()), m_allocator);
+ }
+ return VisitorSuccess();
+ }
+
+ Visitor::Result RapidJsonValueWriter::StartArray()
+ {
+ CurrentValue().SetArray();
+
+ const bool isObject = false;
+ m_entryStack.emplace_front(isObject, CurrentValue());
+ return VisitorSuccess();
+ }
+
+ Visitor::Result RapidJsonValueWriter::EndArray(AZ::u64 elementCount)
+ {
+ if (m_entryStack.empty())
+ {
+ return VisitorFailure(VisitorErrorCode::InternalError, "EndArray called without a matching BeginArray call");
+ }
+
+ const ValueInfo& frontEntry = m_entryStack.front();
+ if (frontEntry.m_isObject)
+ {
+ return VisitorFailure(VisitorErrorCode::InternalError, "Expected EndObject and received EndArray instead");
+ }
+
+ if (frontEntry.m_entryCount != elementCount)
+ {
+ return VisitorFailure(
+ VisitorErrorCode::InternalError,
+ AZStd::string::format(
+ "EndArray: Expected %llu elements but received %llu elements instead", elementCount, frontEntry.m_entryCount));
+ }
+
+ m_entryStack.pop_front();
+ return FinishWrite();
+ }
+
+ Visitor::Result RapidJsonValueWriter::FinishWrite()
+ {
+ if (m_entryStack.empty())
+ {
+ return VisitorSuccess();
+ }
+
+ // Retrieve the top value of the stack and replace it with a null value
+ rapidjson::Value value;
+ m_entryStack.front().m_value.Swap(value);
+ ValueInfo& newEntry = m_entryStack.front();
+ ++newEntry.m_entryCount;
+
+ if (newEntry.m_key.IsString())
+ {
+ newEntry.m_container.AddMember(m_entryStack.front().m_key.Move(), AZStd::move(value), m_allocator);
+ newEntry.m_key.SetNull();
+ }
+ else
+ {
+ newEntry.m_container.PushBack(AZStd::move(value), m_allocator);
+ }
+
+ return VisitorSuccess();
+ }
+
+ rapidjson::Value& RapidJsonValueWriter::CurrentValue()
+ {
+ if (m_entryStack.empty())
+ {
+ return m_result;
+ }
+ return m_entryStack.front().m_value;
+ }
+
+ RapidJsonValueWriter::ValueInfo::ValueInfo(bool isObject, rapidjson::Value& container)
+ : m_isObject(isObject)
+ , m_container(container)
+ {
+ }
+
+ //
+ // class StreamWriter
+ //
+ // Visitor that writes to a rapidjson::Writer
+ template
+ class StreamWriter : public Visitor
+ {
+ public:
+ StreamWriter(AZ::IO::GenericStream* stream)
+ : m_streamWriter(stream)
+ , m_writer(Writer(m_streamWriter))
+ {
+ }
+
+ VisitorFlags GetVisitorFlags() const override
+ {
+ return VisitorFlags::SupportsRawKeys | VisitorFlags::SupportsArrays | VisitorFlags::SupportsObjects;
+ }
+
+ Result Null() override
+ {
+ return CheckWrite(m_writer.Null());
+ }
+
+ Result Bool(bool value) override
+ {
+ return CheckWrite(m_writer.Bool(value));
+ }
+
+ Result Int64(AZ::s64 value) override
+ {
+ return CheckWrite(m_writer.Int64(value));
+ }
+
+ Result Uint64(AZ::u64 value) override
+ {
+ return CheckWrite(m_writer.Uint64(value));
+ }
+
+ Result Double(double value) override
+ {
+ return CheckWrite(m_writer.Double(value));
+ }
+
+ Result String(AZStd::string_view value, Lifetime lifetime) override
+ {
+ const bool shouldCopy = lifetime == Lifetime::Temporary;
+ return CheckWrite(m_writer.String(value.data(), aznumeric_cast(value.size()), shouldCopy));
+ }
+
+ Result StartObject() override
+ {
+ return CheckWrite(m_writer.StartObject());
+ }
+
+ Result EndObject(AZ::u64 attributeCount) override
+ {
+ return CheckWrite(m_writer.EndObject(aznumeric_cast(attributeCount)));
+ }
+
+ Result Key(AZ::Name key) override
+ {
+ return RawKey(key.GetStringView(), Lifetime::Persistent);
+ }
+
+ Result RawKey(AZStd::string_view key, Lifetime lifetime) override
+ {
+ const bool shouldCopy = lifetime == Lifetime::Temporary;
+ return CheckWrite(m_writer.Key(key.data(), aznumeric_cast(key.size()), shouldCopy));
+ }
+
+ Result StartArray() override
+ {
+ return CheckWrite(m_writer.StartArray());
+ }
+
+ Result EndArray(AZ::u64 elementCount) override
+ {
+ return CheckWrite(m_writer.EndArray(aznumeric_cast(elementCount)));
+ }
+
+ private:
+ Result CheckWrite(bool writeSucceeded)
+ {
+ if (writeSucceeded)
+ {
+ return VisitorSuccess();
+ }
+ else
+ {
+ return VisitorFailure(VisitorErrorCode::InternalError, "Failed to write JSON");
+ }
+ }
+
+ AZ::IO::RapidJSONStreamWriter m_streamWriter;
+ Writer m_writer;
+ };
+
+ //
+ // struct JsonReadHandler
+ //
+ RapidJsonReadHandler::RapidJsonReadHandler(Visitor* visitor, Lifetime stringLifetime)
+ : m_visitor(visitor)
+ , m_stringLifetime(stringLifetime)
+ , m_outcome(AZ::Success())
+ {
+ }
+
+ bool RapidJsonReadHandler::Null()
+ {
+ return CheckResult(m_visitor->Null());
+ }
+
+ bool RapidJsonReadHandler::Bool(bool b)
+ {
+ return CheckResult(m_visitor->Bool(b));
+ }
+
+ bool RapidJsonReadHandler::Int(int i)
+ {
+ return CheckResult(m_visitor->Int64(aznumeric_cast(i)));
+ }
+
+ bool RapidJsonReadHandler::Uint(unsigned i)
+ {
+ return CheckResult(m_visitor->Uint64(aznumeric_cast(i)));
+ }
+
+ bool RapidJsonReadHandler::Int64(int64_t i)
+ {
+ return CheckResult(m_visitor->Int64(i));
+ }
+
+ bool RapidJsonReadHandler::Uint64(uint64_t i)
+ {
+ return CheckResult(m_visitor->Uint64(i));
+ }
+
+ bool RapidJsonReadHandler::Double(double d)
+ {
+ return CheckResult(m_visitor->Double(d));
+ }
+
+ bool RapidJsonReadHandler::RawNumber(
+ [[maybe_unused]] const char* str, [[maybe_unused]] rapidjson::SizeType length, [[maybe_unused]] bool copy)
+ {
+ AZ_Assert(false, "Raw numbers are unsupported in the rapidjson DOM backend");
+ return false;
+ }
+
+ bool RapidJsonReadHandler::String(const char* str, rapidjson::SizeType length, bool copy)
+ {
+ const Lifetime lifetime = copy ? m_stringLifetime : Lifetime::Temporary;
+ return CheckResult(m_visitor->String(AZStd::string_view(str, length), lifetime));
+ }
+
+ bool RapidJsonReadHandler::StartObject()
+ {
+ return CheckResult(m_visitor->StartObject());
+ }
+
+ bool RapidJsonReadHandler::Key(const char* str, rapidjson::SizeType length, [[maybe_unused]] bool copy)
+ {
+ AZStd::string_view key = AZStd::string_view(str, length);
+ if (!m_visitor->SupportsRawKeys())
+ {
+ m_visitor->Key(AZ::Name(key));
+ }
+ const Lifetime lifetime = copy ? m_stringLifetime : Lifetime::Temporary;
+ return CheckResult(m_visitor->RawKey(key, lifetime));
+ }
+
+ bool RapidJsonReadHandler::EndObject([[maybe_unused]] rapidjson::SizeType memberCount)
+ {
+ return CheckResult(m_visitor->EndObject(memberCount));
+ }
+
+ bool RapidJsonReadHandler::StartArray()
+ {
+ return CheckResult(m_visitor->StartArray());
+ }
+
+ bool RapidJsonReadHandler::EndArray([[maybe_unused]] rapidjson::SizeType elementCount)
+ {
+ return CheckResult(m_visitor->EndArray(elementCount));
+ }
+
+ Visitor::Result&& RapidJsonReadHandler::TakeOutcome()
+ {
+ return AZStd::move(m_outcome);
+ }
+
+ bool RapidJsonReadHandler::CheckResult(Visitor::Result result)
+ {
+ if (result.IsSuccess())
+ {
+ return true;
+ }
+ else
+ {
+ m_outcome = AZStd::move(result);
+ return false;
+ }
+ }
+
+ //
+ // Serialized JSON util functions
+ //
+ AZStd::unique_ptr CreateJsonStreamWriter(AZ::IO::GenericStream& stream, OutputFormatting format)
+ {
+ if (format == OutputFormatting::MinifiedJson)
+ {
+ using WriterType = rapidjson::Writer;
+ return AZStd::make_unique>(&stream);
+ }
+ else
+ {
+ using WriterType = rapidjson::PrettyWriter;
+ return AZStd::make_unique>(&stream);
+ }
+ }
+
+ //
+ // In-memory rapidjson util functions
+ //
+ AZ::Outcome WriteToRapidJsonDocument(Backend::WriteCallback writeCallback)
+ {
+ rapidjson::Document document;
+ RapidJsonValueWriter writer(document, document.GetAllocator());
+ auto result = writeCallback(writer);
+ if (!result.IsSuccess())
+ {
+ return AZ::Failure(result.TakeError().FormatVisitorErrorMessage());
+ }
+ return AZ::Success(AZStd::move(document));
+ }
+
+ Visitor::Result WriteToRapidJsonValue(
+ rapidjson::Value& value, rapidjson::Value::AllocatorType& allocator, Backend::WriteCallback writeCallback)
+ {
+ RapidJsonValueWriter writer(value, allocator);
+ return writeCallback(writer);
+ }
+
+ Visitor::Result VisitRapidJsonValue(const rapidjson::Value& value, Visitor& visitor, Lifetime lifetime)
+ {
+ struct EndArrayMarker
+ {
+ };
+ struct EndObjectMarker
+ {
+ };
+
+ // Processing stack consists of values comprised of one of a:
+ // - rapidjson::Value to process
+ // - EndArrayMarker or EndObjectMarker denoting the end of an array or object
+ // - string denoting a key at the beginning of a key/value pair
+ using Entry = AZStd::variant;
+ AZStd::stack entryStack;
+ AZStd::stack entryCountStack;
+ entryStack.push(&value);
+
+ while (!entryStack.empty())
+ {
+ const Entry currentEntry = entryStack.top();
+ entryStack.pop();
+
+ Visitor::Result result = AZ::Success();
+
+ AZStd::visit(
+ [&visitor, &entryStack, &entryCountStack, &result, lifetime](auto&& arg)
+ {
+ using Alternative = AZStd::decay_t;
+ if constexpr (AZStd::is_same_v)
+ {
+ const rapidjson::Value& currentValue = *arg;
+ if (!entryCountStack.empty())
+ {
+ ++entryCountStack.top();
+ }
+
+ switch (currentValue.GetType())
+ {
+ case rapidjson::kNullType:
+ result = visitor.Null();
+ break;
+ case rapidjson::kFalseType:
+ result = visitor.Bool(false);
+ break;
+ case rapidjson::kTrueType:
+ result = visitor.Bool(true);
+ break;
+ case rapidjson::kObjectType:
+ entryStack.push(EndObjectMarker{});
+ entryCountStack.push(0);
+ result = visitor.StartObject();
+ for (auto it = currentValue.MemberEnd(); it != currentValue.MemberBegin(); --it)
+ {
+ auto entry = (it - 1);
+ const AZStd::string_view key(
+ entry->name.GetString(), aznumeric_cast(entry->name.GetStringLength()));
+ entryStack.push(&entry->value);
+ entryStack.push(key);
+ }
+ break;
+ case rapidjson::kArrayType:
+ entryStack.push(EndArrayMarker{});
+ entryCountStack.push(0);
+ result = visitor.StartArray();
+ for (auto it = currentValue.End(); it != currentValue.Begin(); --it)
+ {
+ auto entry = (it - 1);
+ entryStack.push(entry);
+ }
+ break;
+ case rapidjson::kStringType:
+ result = visitor.String(
+ AZStd::string_view(currentValue.GetString(), aznumeric_cast(currentValue.GetStringLength())),
+ lifetime);
+ break;
+ case rapidjson::kNumberType:
+ if (currentValue.IsFloat() || currentValue.IsDouble())
+ {
+ result = visitor.Double(currentValue.GetDouble());
+ }
+ else if (currentValue.IsInt64() || currentValue.IsInt())
+ {
+ result = visitor.Int64(currentValue.GetInt64());
+ }
+ else
+ {
+ result = visitor.Uint64(currentValue.GetUint64());
+ }
+ break;
+ default:
+ result = AZ::Failure(VisitorError(VisitorErrorCode::InvalidData, "Value with invalid type specified"));
+ }
+ }
+ else if constexpr (AZStd::is_same_v)
+ {
+ result = visitor.EndArray(entryCountStack.top());
+ entryCountStack.pop();
+ }
+ else if constexpr (AZStd::is_same_v)
+ {
+ result = visitor.EndObject(entryCountStack.top());
+ entryCountStack.pop();
+ }
+ else if constexpr (AZStd::is_same_v)
+ {
+ if (visitor.SupportsRawKeys())
+ {
+ visitor.RawKey(arg, lifetime);
+ }
+ else
+ {
+ visitor.Key(AZ::Name(arg));
+ }
+ }
+ },
+ currentEntry);
+
+ if (!result.IsSuccess())
+ {
+ return result;
+ }
+ }
+
+ return AZ::Success();
+ }
+} // namespace AZ::Dom::Json
diff --git a/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.h b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.h
new file mode 100644
index 0000000000..af0955dcfe
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace AZ::Dom::Json
+{
+ //! Specifies how JSON should be formatted when serialized.
+ enum class OutputFormatting
+ {
+ MinifiedJson, //!< Formats JSON in compact minified form, focusing on minimizing output size.
+ PrettyPrintedJson, //!< Formats JSON in a pretty printed form, focusing on legibility to readers.
+ };
+
+ //! Specifies parsing behavior when deserializing JSON.
+ enum class ParseFlags : int
+ {
+ Null = 0,
+ StopWhenDone = rapidjson::kParseStopWhenDoneFlag,
+ FullFloatingPointPrecision = rapidjson::kParseFullPrecisionFlag,
+ ParseComments = rapidjson::kParseCommentsFlag,
+ ParseNumbersAsStrings = rapidjson::kParseNumbersAsStringsFlag,
+ ParseTrailingCommas = rapidjson::kParseTrailingCommasFlag,
+ ParseNanAndInfinity = rapidjson::kParseNanAndInfFlag,
+ ParseEscapedApostrophies = rapidjson::kParseEscapedApostropheFlag,
+ };
+
+ AZ_DEFINE_ENUM_BITWISE_OPERATORS(ParseFlags);
+
+ //! Visitor that feeds into a rapidjson::Value
+ class RapidJsonValueWriter final : public Visitor
+ {
+ public:
+ RapidJsonValueWriter(rapidjson::Value& outputValue, rapidjson::Value::AllocatorType& allocator);
+
+ VisitorFlags GetVisitorFlags() const override;
+ Result Null() override;
+ Result Bool(bool value) override;
+ Result Int64(AZ::s64 value) override;
+ Result Uint64(AZ::u64 value) override;
+ Result Double(double value) override;
+
+ Result String(AZStd::string_view value, Lifetime lifetime) override;
+ Result StartObject() override;
+ Result EndObject(AZ::u64 attributeCount) override;
+ Result Key(AZ::Name key) override;
+ Result RawKey(AZStd::string_view key, Lifetime lifetime) override;
+ Result StartArray() override;
+ Result EndArray(AZ::u64 elementCount) override;
+
+ private:
+ Result FinishWrite();
+ rapidjson::Value& CurrentValue();
+
+ struct ValueInfo
+ {
+ ValueInfo(bool isObject, rapidjson::Value& container);
+
+ rapidjson::Value m_key;
+ rapidjson::Value m_value;
+ rapidjson::Value& m_container;
+ AZ::u64 m_entryCount = 0;
+ bool m_isObject;
+ };
+
+ rapidjson::Value& m_result;
+ rapidjson::Value::AllocatorType& m_allocator;
+ AZStd::deque m_entryStack;
+ };
+
+ //! Handler for a rapidjson::Reader that translates reads into an AZ::Dom::Visitor
+ struct RapidJsonReadHandler
+ {
+ public:
+ RapidJsonReadHandler(Visitor* visitor, Lifetime stringLifetime);
+
+ bool Null();
+ bool Bool(bool b);
+ bool Int(int i);
+ bool Uint(unsigned i);
+ bool Int64(int64_t i);
+ bool Uint64(uint64_t i);
+ bool Double(double d);
+ bool RawNumber(const char* str, rapidjson::SizeType length, bool copy);
+ bool String(const char* str, rapidjson::SizeType length, bool copy);
+ bool StartObject();
+ bool Key(const char* str, rapidjson::SizeType length, bool copy);
+ bool EndObject(rapidjson::SizeType memberCount);
+ bool StartArray();
+ bool EndArray(rapidjson::SizeType elementCount);
+ Visitor::Result&& TakeOutcome();
+
+ private:
+ bool CheckResult(Visitor::Result result);
+
+ Visitor::Result m_outcome;
+ Visitor* m_visitor;
+ Lifetime m_stringLifetime;
+ };
+
+ //! rapidjson stream wrapper for AZStd::string suitable for in-situ parsing
+ //! Faster than rapidjson::MemoryStream for reading from AZStd::string / AZStd::string_view (because it requires a null terminator)
+ //! \note This needs to be inlined for performance reasons.
+ struct NullDelimitedStringStream
+ {
+ using Ch = char; //(buffer.data());
+ m_begin = m_cursor;
+ }
+
+ AZ_FORCE_INLINE char Peek() const
+ {
+ return *m_cursor;
+ }
+
+ AZ_FORCE_INLINE char Take()
+ {
+ return *m_cursor++;
+ }
+
+ AZ_FORCE_INLINE size_t Tell() const
+ {
+ return static_cast(m_cursor - m_begin);
+ }
+
+ AZ_FORCE_INLINE char* PutBegin()
+ {
+ m_write = m_cursor;
+ return m_cursor;
+ }
+
+ AZ_FORCE_INLINE void Put(char c)
+ {
+ (*m_write++) = c;
+ }
+
+ AZ_FORCE_INLINE void Flush()
+ {
+ }
+
+ AZ_FORCE_INLINE size_t PutEnd(char* begin)
+ {
+ return m_write - begin;
+ }
+
+ AZ_FORCE_INLINE const char* Peek4() const
+ {
+ AZ_Assert(false, "Not implemented, encoding is hard-coded to UTF-8");
+ return m_cursor;
+ }
+
+ char* m_cursor; //!< Current read position.
+ char* m_write; //!< Current write position.
+ const char* m_begin; //!< Head of string.
+ };
+
+ //! Creates a Visitor that will write serialized JSON to the specified stream.
+ //! \param stream The stream the visitor will write to.
+ //! \param format The format to write in.
+ //! \return A Visitor that will write to stream when visited.
+ AZStd::unique_ptr CreateJsonStreamWriter(
+ AZ::IO::GenericStream& stream, OutputFormatting format = OutputFormatting::PrettyPrintedJson);
+ //! Reads serialized JSON from a string and applies it to a visitor.
+ //! \param buffer The UTF-8 serialized JSON to read.
+ //! \param lifetime Specifies the lifetime of the specified buffer. If the string specified by buffer might be deallocated,
+ //! ensure Lifetime::Temporary is specified.
+ //! \param visitor The visitor to visit with the JSON buffer's contents.
+ //! \param parseFlags (template) Settings for adjusting parser behavior.
+ //! \return The aggregate result specifying whether the visitor operations were successful.
+ template
+ Visitor::Result VisitSerializedJson(AZStd::string_view buffer, Lifetime lifetime, Visitor& visitor);
+
+ //! Reads serialized JSON from a string in-place and applies it to a visitor.
+ //! \param buffer The UTF-8 serialized JSON to read. This buffer will be modified as part of the deserialization process to
+ //! apply null terminators.
+ //! \param visitor The visitor to visit with the JSON buffer's contents. The strings provided to the visitor will only
+ //! be valid for the lifetime of buffer.
+ //! \param parseFlags (template) Settings for adjusting parser behavior.
+ //! \return The aggregate result specifying whether the visitor operations were successful.
+ template
+ Visitor::Result VisitSerializedJsonInPlace(char* buffer, Visitor& visitor);
+
+ //! Takes a visitor specified by a callback and produces a rapidjson::Document.
+ //! \param writeCallback A callback specifying a visitor to accept to build the resulting document.
+ //! \return An outcome with either the rapidjson::Document or an error message.
+ AZ::Outcome WriteToRapidJsonDocument(Backend::WriteCallback writeCallback);
+ //! Takes a visitor specified by a callback and reads them into a rapidjson::Value.
+ //! \param value The value to read into, its contents will be overridden.
+ //! \param allocator The allocator to use when performing rapidjson allocations (generally provded by the rapidjson::Document).
+ //! \param writeCallback A callback specifying a visitor to accept to build the resulting document.
+ //! \return An outcome with either the rapidjson::Document or an error message.
+ Visitor::Result WriteToRapidJsonValue(
+ rapidjson::Value& value, rapidjson::Value::AllocatorType& allocator, Backend::WriteCallback writeCallback);
+ //! Accepts a visitor with the contents of a rapidjson::Value.
+ //! \param value The rapidjson::Value to apply to visitor.
+ //! \param visitor The visitor to receive the contents of value.
+ //! \param lifetime The lifetime to specify for visiting strings. If the rapidjson::Value might be destroyed or changed
+ //! before the visitor is finished using these values, Lifetime::Temporary should be specified.
+ //! \return The aggregate result specifying whether the visitor operations were successful.
+ Visitor::Result VisitRapidJsonValue(const rapidjson::Value& value, Visitor& visitor, Lifetime lifetime);
+
+ template
+ Visitor::Result VisitSerializedJson(AZStd::string_view buffer, Lifetime lifetime, Visitor& visitor)
+ {
+ rapidjson::Reader reader;
+ RapidJsonReadHandler handler(&visitor, lifetime);
+
+ // If the string is null terminated, we can use the faster AzStringStream path - otherwise we fall back on rapidjson::MemoryStream
+ if (buffer.data()[buffer.size()] == '\0')
+ {
+ NullDelimitedStringStream stream(buffer);
+ reader.Parse(parseFlags)>(stream, handler);
+ }
+ else
+ {
+ rapidjson::MemoryStream stream(buffer.data(), buffer.size());
+ reader.Parse(parseFlags)>(stream, handler);
+ }
+ return handler.TakeOutcome();
+ }
+
+ template
+ Visitor::Result VisitSerializedJsonInPlace(char* buffer, Visitor& visitor)
+ {
+ rapidjson::Reader reader;
+ NullDelimitedStringStream stream(buffer);
+ RapidJsonReadHandler handler(&visitor, Lifetime::Persistent);
+
+ reader.Parse(parseFlags) | rapidjson::kParseInsituFlag>(stream, handler);
+ return handler.TakeOutcome();
+ }
+} // namespace AZ::Dom::Json
diff --git a/Code/Framework/AzCore/AzCore/DOM/DomBackend.cpp b/Code/Framework/AzCore/AzCore/DOM/DomBackend.cpp
new file mode 100644
index 0000000000..b29c0be231
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/DOM/DomBackend.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+namespace AZ::Dom
+{
+ Visitor::Result Backend::ReadFromBufferInPlace(char* buffer, AZStd::optional size, Visitor& visitor)
+ {
+ return ReadFromBuffer(buffer, size.value_or(strlen(buffer)), AZ::Dom::Lifetime::Persistent, visitor);
+ }
+} // namespace AZ::Dom
diff --git a/Code/Framework/AzCore/AzCore/DOM/DomBackend.h b/Code/Framework/AzCore/AzCore/DOM/DomBackend.h
new file mode 100644
index 0000000000..2e4ccf8f3e
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/DOM/DomBackend.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace AZ::Dom
+{
+ //! Backends are registered centrally and used to transition DOM formats to and from a textual format.
+ class Backend
+ {
+ public:
+ virtual ~Backend() = default;
+
+ //! Attempt to read this format from the given buffer into the target Visitor.
+ virtual Visitor::Result ReadFromBuffer(
+ const char* buffer, size_t size, AZ::Dom::Lifetime lifetime, Visitor& visitor) = 0;
+ //! Attempt to read this format from a mutable string into the target Visitor. This enables some backends to
+ //! parse without making additional string allocations.
+ //! This string must be null terminated.
+ //! This string may be modified and read in place without being copied, so when calling this please ensure that:
+ //! - The string won't be deallocated until the visitor no longer needs the values and
+ //! - The string is safe to modify in place.
+ //! The base implementation simply calls ReadFromBuffer.
+ virtual Visitor::Result ReadFromBufferInPlace(char* buffer, AZStd::optional size, Visitor& visitor);
+
+ //! A callback that accepts a Visitor, making DOM calls to inform the serializer, and returns an
+ //! aggregate error code to indicate whether or not the operation succeeded.
+ using WriteCallback = AZStd::function;
+ //! Attempt to write a value to the specified string using a write callback.
+ virtual Visitor::Result WriteToBuffer(AZStd::string& buffer, WriteCallback callback) = 0;
+ };
+} // namespace AZ::Dom
diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp
new file mode 100644
index 0000000000..9751b9cecc
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+#include
+
+namespace AZ::Dom::Utils
+{
+ Visitor::Result ReadFromString(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime, Visitor& visitor)
+ {
+ return backend.ReadFromBuffer(string.data(), string.length(), lifetime, visitor);
+ }
+
+ Visitor::Result ReadFromStringInPlace(Backend& backend, AZStd::string& string, Visitor& visitor)
+ {
+ return backend.ReadFromBufferInPlace(string.data(), string.size(), visitor);
+ }
+}
diff --git a/Code/Framework/AzCore/AzCore/DOM/DomUtils.h b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h
new file mode 100644
index 0000000000..84a6eb5687
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/DOM/DomUtils.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+
+namespace AZ::Dom::Utils
+{
+ Visitor::Result ReadFromString(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime, Visitor& visitor);
+ Visitor::Result ReadFromStringInPlace(Backend& backend, AZStd::string& string, Visitor& visitor);
+} // namespace AZ::Dom::Utils
diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp
index 5d66bb6ac5..ad314da385 100644
--- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp
+++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.cpp
@@ -8,7 +8,7 @@
#include
-namespace AZ::DOM
+namespace AZ::Dom
{
const char* VisitorError::CodeToString(VisitorErrorCode code)
{
@@ -236,4 +236,4 @@ namespace AZ::DOM
{
return (GetVisitorFlags() & VisitorFlags::SupportsOpaqueValues) != VisitorFlags::Null;
}
-} // namespace AZ::DOM
+} // namespace AZ::Dom
diff --git a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h
index 584cfce4ed..bbe78131c3 100644
--- a/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h
+++ b/Code/Framework/AzCore/AzCore/DOM/DomVisitor.h
@@ -13,11 +13,11 @@
#include
#include
-namespace AZ::DOM
+namespace AZ::Dom
{
//
// Lifetime enum
- //
+ //
//! Specifies the period in which a reference value will still be alive and safe to read.
enum class Lifetime
{
@@ -30,7 +30,7 @@ namespace AZ::DOM
//
// VisitorErrorCode enum
- //
+ //
//! Error code specifying the reason a Visitor operation failed.
enum class VisitorErrorCode
{
@@ -75,7 +75,7 @@ namespace AZ::DOM
};
//! A type alias for opaque DOM types that aren't meant to be serializable.
- //! /see VisitorInterface::OpaqueValue
+ //! \see VisitorInterface::OpaqueValue
using OpaqueType = AZStd::any;
//
@@ -116,7 +116,7 @@ namespace AZ::DOM
//! - \ref Double: 64 bit double precision float
//! - \ref Null: sentinel "empty" type with no value representation
//! - \ref String: UTF8 encoded string
- //! - \ref Object: an ordered container of key/value pairs where keys are AZ::Names and values may be any DOM type
+ //! - \ref Object: an ordered container of key/value pairs where keys are \ref AZ::Name and values may be any DOM type
//! (including Object)
//! - \ref Array: an ordered container of values, in which values are any DOM value type (including Array)
//! - \ref Node: a container
@@ -144,17 +144,17 @@ namespace AZ::DOM
//! Raw (\see VisitorFlags::SupportsRawValues) and opaque values (\see VisitorFlags::SupportsOpaqueValues)
//! are disallowed by default, as their handling is intended to be implementation-specific.
virtual VisitorFlags GetVisitorFlags() const;
- //! /see VisitorFlags::SupportsRawValues
+ //! \see VisitorFlags::SupportsRawValues
bool SupportsRawValues() const;
- //! /see VisitorFlags::SupportsRawKeys
+ //! \see VisitorFlags::SupportsRawKeys
bool SupportsRawKeys() const;
- //! /see VisitorFlags::SupportsObjects
+ //! \see VisitorFlags::SupportsObjects
bool SupportsObjects() const;
- //! /see VisitorFlags::SupportsArrays
+ //! \see VisitorFlags::SupportsArrays
bool SupportsArrays() const;
- //! /see VisitorFlags::SupportsNodes
+ //! \see VisitorFlags::SupportsNodes
bool SupportsNodes() const;
- //! /see VisitorFlags::SupportsOpaqueValues
+ //! \see VisitorFlags::SupportsOpaqueValues
bool SupportsOpaqueValues() const;
//! Operates on an empty null value.
@@ -231,7 +231,8 @@ namespace AZ::DOM
static Result VisitorFailure(VisitorErrorCode code, AZStd::string additionalInfo);
//! Helper method, constructs a failure \ref Result with the specified error.
static Result VisitorFailure(VisitorError error);
+
//! Helper method, constructs a success \ref Result.
static Result VisitorSuccess();
};
-} // namespace AZ::DOM
+} // namespace AZ::Dom
diff --git a/Code/Framework/AzCore/AzCore/Debug/AssetTracking.cpp b/Code/Framework/AzCore/AzCore/Debug/AssetTracking.cpp
deleted file mode 100644
index c03b75d118..0000000000
--- a/Code/Framework/AzCore/AzCore/Debug/AssetTracking.cpp
+++ /dev/null
@@ -1,326 +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
- *
- */
-
-#include "AssetTracking.h"
-
-#include
-#include
-#include
-#include
-#include
-
-namespace AZ::Debug
-{
- namespace
- {
- struct AssetTreeNode;
-
- // Per-thread data that needs to be stored.
- struct ThreadData
- {
- AZStd::vector m_currentAssetStack;
- };
-
- // Access thread data through a virtual function to ensure that the same thread-local data is being shared across DLLs.
- // Otherwise, the thread_local variables are replicated across DLLs that link the AzCore library, and you'll get a
- // different version in each module.
- class ThreadDataProvider
- {
- public:
- virtual ThreadData& GetThreadData() = 0;
- };
- }
-
- class AssetTrackingImpl final :
- public ThreadDataProvider
- {
- public:
- AZ_TYPE_INFO(AssetTrackingImpl, "{01E2A099-3523-40BE-80E0-E0ADD861BEE1}");
- AZ_CLASS_ALLOCATOR(AssetTrackingImpl, OSAllocator, 0);
-
- AssetTrackingImpl(AssetTreeBase* assetTree, AssetAllocationTableBase* allocationTable);
- ~AssetTrackingImpl();
-
- void AssetBegin(const char* id, const char* file, int line);
- void AssetAttach(void* otherAllocation, const char* file, int line);
- void AssetEnd();
-
- ThreadData& GetThreadData() override;
-
- private:
- static EnvironmentVariable& GetEnvironmentVariable();
- static AssetTrackingImpl* GetSharedInstance();
- static ThreadData& GetSharedThreadData();
-
- using PrimaryAssets = AZStd::unordered_map, AZStd::equal_to, AZStdAssetTrackingAllocator>;
- using ThreadData = ThreadData;
- using mutex_type = AZStd::mutex;
- using lock_type = AZStd::lock_guard;
-
- mutex_type m_mutex;
- PrimaryAssets m_primaryAssets;
- AssetTreeNodeBase* m_assetRoot = nullptr;
- AssetAllocationTableBase* m_allocationTable = nullptr;
- bool m_performingAnalysis = false;
-
- friend class AssetTracking;
- friend class AssetTracking::Scope;
- };
-
-
-///////////////////////////////////////////////////////////////////////////////
-// AssetTrackingImpl methods
-///////////////////////////////////////////////////////////////////////////////
-
- AssetTrackingImpl::AssetTrackingImpl(AssetTreeBase* assetTree, AssetAllocationTableBase* allocationTable) :
- m_assetRoot(&assetTree->GetRoot()),
- m_allocationTable(allocationTable)
- {
- AZ_Assert(!GetSharedInstance(), "Only one AssetTrackingImpl can exist!");
-
- GetEnvironmentVariable().Set(this);
- AllocatorManager::Instance().EnterProfilingMode();
- }
-
- AssetTrackingImpl::~AssetTrackingImpl()
- {
- AllocatorManager::Instance().ExitProfilingMode();
- GetEnvironmentVariable().Reset();
- }
-
- void AssetTrackingImpl::AssetBegin(const char* id, const char* file, int line)
- {
- // In the future it may be desirable to organize assets based on where in code the asset was entered into.
- // For now these are ignored.
- AZ_UNUSED(file);
- AZ_UNUSED(line);
-
- using namespace Internal;
-
- AssetTrackingId assetId(id);
- auto& threadData = GetSharedThreadData();
- AssetTreeNodeBase* parentAsset = threadData.m_currentAssetStack.empty() ? nullptr : threadData.m_currentAssetStack.back();
- AssetTreeNodeBase* childAsset;
- AssetPrimaryInfo* assetPrimaryInfo;
-
- if (!parentAsset)
- {
- parentAsset = m_assetRoot;
- }
-
- {
- lock_type lock(m_mutex);
-
- // Locate or create the primary record for this asset
- auto primaryItr = m_primaryAssets.find(assetId);
-
- if (primaryItr != m_primaryAssets.end())
- {
- assetPrimaryInfo = &primaryItr->second;
- }
- else
- {
- auto insertResult = m_primaryAssets.emplace(assetId, AssetPrimaryInfo());
- assetPrimaryInfo = &insertResult.first->second;
- assetPrimaryInfo->m_id = &insertResult.first->first;
- }
-
- // Add this asset to the stack for this thread's context
- childAsset = parentAsset->FindOrAddChild(assetId, assetPrimaryInfo);
- }
-
- threadData.m_currentAssetStack.push_back(childAsset);
- }
-
- void AssetTrackingImpl::AssetAttach(void* otherAllocation, const char* file, int line)
- {
- AZ_UNUSED(file);
- AZ_UNUSED(line);
-
- using namespace Internal;
-
- AssetTreeNodeBase* assetInfo = m_allocationTable->FindAllocation(otherAllocation);
-
- // We will push back a nullptr if there is no asset, this is necessary to balance the call to AssetEnd()
- GetSharedThreadData().m_currentAssetStack.push_back(assetInfo);
- }
-
- void AssetTrackingImpl::AssetEnd()
- {
- AZ_Assert(!GetSharedThreadData().m_currentAssetStack.empty(), "AssetEnd() called without matching AssetBegin() or AssetAttach. Use the AZ_ASSET_NAMED_SCOPE and AZ_ASSET_ATTACH_TO_SCOPE macros to avoid this!");
- GetSharedThreadData().m_currentAssetStack.pop_back();
- }
-
- AssetTrackingImpl* AssetTrackingImpl::GetSharedInstance()
- {
- auto environmentVariable = GetEnvironmentVariable();
-
- if(environmentVariable)
- {
- return *environmentVariable;
- }
-
- return nullptr;
- }
-
- ThreadData& AssetTrackingImpl::GetSharedThreadData()
- {
- // Cast to the base type so our virtual call doesn't get optimized away. We require GetThreadData() to be executed in the same DLL every time.
- return static_cast(GetSharedInstance())->GetThreadData();
- }
-
- AssetTrackingImpl::ThreadData& AssetTrackingImpl::GetThreadData()
- {
- static thread_local ThreadData* data = nullptr;
- static thread_local typename AZStd::aligned_storage_t storage;
-
- if (!data)
- {
- data = new (&storage) ThreadData;
- }
-
- return *data;
- }
-
- EnvironmentVariable& AssetTrackingImpl::GetEnvironmentVariable()
- {
- static EnvironmentVariable assetTrackingImpl = Environment::CreateVariable(AzTypeInfo::Name());
-
- return assetTrackingImpl;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // AssetTracking::Scope functions
- ///////////////////////////////////////////////////////////////////////////////
-
- AssetTracking::Scope AssetTracking::Scope::ScopeFromAssetId(const char* file, int line, const char* fmt, ...)
- {
- if (auto impl = AssetTrackingImpl::GetSharedInstance())
- {
- static const int BUFFER_SIZE = 1024;
-
- char buffer[BUFFER_SIZE];
- va_list args;
- va_start(args, fmt);
- azvsnprintf(buffer, BUFFER_SIZE, fmt, args);
- va_end(args);
-
- impl->AssetBegin(buffer, file, line);
- }
-
- return Scope();
- }
-
- AssetTracking::Scope AssetTracking::Scope::ScopeFromAttachment(void* attachTo, const char* file, int line)
- {
- if (auto impl = AssetTrackingImpl::GetSharedInstance())
- {
- impl->AssetAttach(attachTo, file, line);
- }
-
- return Scope();
- }
-
- AssetTracking::Scope::~Scope()
- {
- if (auto impl = AssetTrackingImpl::GetSharedInstance())
- {
- impl->AssetEnd();
- }
- }
-
- AssetTracking::Scope::Scope()
- {
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // AssetTracking functions
- ///////////////////////////////////////////////////////////////////////////////
-
- void AssetTracking::EnterScopeByAssetId(const char* file, int line, const char* fmt, ...)
- {
- if (auto impl = AssetTrackingImpl::GetSharedInstance())
- {
- static const int BUFFER_SIZE = 1024;
-
- char buffer[BUFFER_SIZE];
- va_list args;
- va_start(args, fmt);
- azvsnprintf(buffer, BUFFER_SIZE, fmt, args);
- va_end(args);
-
- impl->AssetBegin(buffer, file, line);
- }
- }
-
- void AssetTracking::EnterScopeByAttachment(void* attachTo, const char* file, int line)
- {
- if (auto impl = AssetTrackingImpl::GetSharedInstance())
- {
- impl->AssetAttach(attachTo, file, line);
- }
- }
-
- void AssetTracking::ExitScope()
- {
- if (auto impl = AssetTrackingImpl::GetSharedInstance())
- {
- impl->AssetEnd();
- }
- }
-
- const char* AssetTracking::GetDebugScope()
- {
- // Output debug information about the current asset scope in the current thread.
- // Do not use in production code.
-#ifndef RELEASE
- static const int BUFFER_SIZE = 1024;
- static char buffer[BUFFER_SIZE];
- const auto& assetStack = AssetTrackingImpl::GetSharedInstance()->GetThreadData().m_currentAssetStack;
-
- if (assetStack.empty())
- {
- azsnprintf(buffer, BUFFER_SIZE, "");
- }
- else
- {
- char* pos = buffer;
- for (auto itr = assetStack.rbegin(); itr != assetStack.rend(); ++itr)
- {
- pos += azsnprintf(pos, BUFFER_SIZE - (pos - buffer), "%s\n", (*itr)->GetAssetPrimaryInfo()->m_id->m_id.c_str());
-
- if (pos >= buffer + BUFFER_SIZE)
- {
- break;
- }
- }
- }
-
- return buffer;
-#else
- return "";
-#endif
- }
-
- AssetTracking::AssetTracking(AssetTreeBase* assetTree, AssetAllocationTableBase* allocationTable)
- {
- m_impl.reset(aznew AssetTrackingImpl(assetTree, allocationTable));
- }
-
- AssetTracking::~AssetTracking()
- {
- }
-
- AssetTreeNodeBase* AssetTracking::GetCurrentThreadAsset() const
- {
- const auto& assetStack = m_impl->GetThreadData().m_currentAssetStack;
- AssetTreeNodeBase* result = assetStack.empty() ? nullptr : assetStack.back();
-
- return result;
- }
-} // namespace AzFramework
diff --git a/Code/Framework/AzCore/AzCore/Debug/AssetTracking.h b/Code/Framework/AzCore/AzCore/Debug/AssetTracking.h
deleted file mode 100644
index 615634c05a..0000000000
--- a/Code/Framework/AzCore/AzCore/Debug/AssetTracking.h
+++ /dev/null
@@ -1,131 +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
-
-#include
-#include
-#include
-
-#ifndef AZ_TRACK_ASSET_SCOPES
-// You may manually uncomment this to enable asset tracking.
-//# define AZ_TRACK_ASSET_SCOPES
-#endif
-
-#if !defined(AZ_TRACK_ASSET_SCOPES)
-// Default to enabling asset tracking when memory tracking is enabled
-# define AZ_TRACK_ASSET_SCOPES
-#endif
-
-
-#ifdef AZ_TRACK_ASSET_SCOPES
-#define AZ_ASSET_SCOPE_VARIABLE_NAME(line) AZ_JOIN(_az_assettracking_scope_, line)
-
-///////////////////////////////////////////////////////////////////////////////
-// Preferred macros to use at the top of a scope you want to to track asset memory for.
-///////////////////////////////////////////////////////////////////////////////
-
-// Creates a new scope with a name, usually the name of an asset being loaded. (This may be a format-string, e.g. "Foo: %s", bar.c_str())
-# define AZ_ASSET_NAMED_SCOPE(...) AZ::Debug::AssetTracking::Scope AZ_ASSET_SCOPE_VARIABLE_NAME(__LINE__) (AZ::Debug::AssetTracking::Scope::ScopeFromAssetId(__FILE__, __LINE__, __VA_ARGS__))
-
-// Attempts to enter an existing scope that already owns some other allocation.
-# define AZ_ASSET_ATTACH_TO_SCOPE(other) AZ::Debug::AssetTracking::Scope AZ_ASSET_SCOPE_VARIABLE_NAME(__LINE__) (AZ::Debug::AssetTracking::Scope::ScopeFromAttachment((other), __FILE__, __LINE__))
-
-///////////////////////////////////////////////////////////////////////////////
-// Optional macros to manually enter and exit a scope.
-// It is the responsibility of the user to make sure every call to AZ_ASSET_ENTER_SCOPE_* is matched by a corresponding call to AZ_ASSET_EXIT_SCOPE.
-///////////////////////////////////////////////////////////////////////////////
-# define AZ_ASSET_ENTER_SCOPE_BY_ASSET_ID(...) AZ::Debug::AssetTracking::EnterScopeByAssetId(__FILE__, __LINE__, __VA_ARGS__)
-# define AZ_ASSET_ENTER_SCOPE_BY_ATTACHMENT(other) AZ::Debug::AssetTracking::EnterScopeByAttachment((other), __FILE__, __LINE__)
-# define AZ_ASSET_EXIT_SCOPE AZ::Debug::AssetTracking::ExitScope()
-
-#else
-# define AZ_ASSET_NAMED_SCOPE(...) (void)0
-# define AZ_ASSET_ATTACH_TO_SCOPE(other) (void)0
-
-# define AZ_ASSET_ENTER_SCOPE_BY_ASSET_ID(...) (void)0
-# define AZ_ASSET_ENTER_SCOPE_BY_ATTACHMENT(other) (void)0
-# define AZ_ASSET_EXIT_SCOPE (void)0
-
-#endif
-
-namespace AZ
-{
- class ReflectContext;
-
- namespace Debug
- {
- class AssetTrackingImpl;
- class AssetTreeBase;
- class AssetTreeNodeBase;
- class AssetAllocationTableBase;
-
- class AssetTracking
- {
- public:
- AZ_TYPE_INFO(AssetTracking, "{D4335180-09A2-415A-8B50-9B734E7CE1E6}");
- AZ_CLASS_ALLOCATOR(AssetTracking, OSAllocator, 0);
-
- // Provide RAII method for entering and exiting scopes.
- // Generally you will want to use the macros at the top of this file rather than instantiating this object directly.
- class Scope
- {
- public:
- static Scope ScopeFromAssetId(const char* file, int line, const char* fmt, ...);
- static Scope ScopeFromAttachment(void* attachTo, const char* file, int line);
-
- Scope(Scope&&) = default;
- ~Scope();
-
- private:
- Scope();
- };
-
- // Generally you will want to use the macros at the top of this file rather than calling these functions directly.
- static void EnterScopeByAssetId(const char* file, int line, const char* fmt, ...);
- static void EnterScopeByAttachment(void* attachTo, const char* file, int line);
- static void ExitScope();
- static const char* GetDebugScope();
-
- AssetTracking(AssetTreeBase* assetTree, AssetAllocationTableBase* allocationTable);
- ~AssetTracking();
-
- AssetTreeNodeBase* GetCurrentThreadAsset() const;
-
- private:
- AZStd::unique_ptr m_impl;
- };
-
- // An EBus processing policy that attempts to attach to an existing scope before calling a handler.
- //
- // Use this on EBuses where you want the callees to track asset memory during their event handlers.
- // This will work so long as the callees were themselves allocated inside an existing asset scope.
- //
- // May be added to an existing EBus with the following code:
- // using EventProcessingPolicy = Debug::AssetTrackingEventProcessingPolicy;
- //
- template
- struct AssetTrackingEventProcessingPolicy
- {
- template
- static void CallResult(Results& results, Function&& func, Interface&& iface, InputArgs&&... args)
- {
- AZ_ASSET_ATTACH_TO_SCOPE(iface);
- Parent::CallResult(results, AZStd::forward(func), AZStd::forward(iface), AZStd::forward(args)...);
- }
-
- template
- static void Call(Function&& func, Interface&& iface, InputArgs&&... args)
- {
- AZ_ASSET_ATTACH_TO_SCOPE(iface);
- Parent::Call(AZStd::forward(func), AZStd::forward(iface), AZStd::forward(args)...);
- }
- };
- }
-
-} // namespace AzFramework
diff --git a/Code/Framework/AzCore/AzCore/Debug/AssetTrackingTypes.h b/Code/Framework/AzCore/AzCore/Debug/AssetTrackingTypes.h
deleted file mode 100644
index f538c516c3..0000000000
--- a/Code/Framework/AzCore/AzCore/Debug/AssetTrackingTypes.h
+++ /dev/null
@@ -1,120 +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
-
-#include
-#include
-#include
-
-namespace AZ
-{
- namespace Debug
- {
- struct AssetTrackingId;
- }
-}
-
-namespace AZStd
-{
- // Declare hash specializations for types that need them; implementations will have to come after the classes are fully defined
- template<>
- struct hash
- {
- size_t operator()(const AZ::Debug::AssetTrackingId& id) const;
- };
-}
-
-namespace AZ
-{
- namespace Debug
- {
- class AssetTrackingImpl;
-
- // Custom allocator for the Analyzer that doesn't go through profiling tools and cannot be overridden
- class AssetTrackingAllocator : public AZ::SimpleSchemaAllocator
- {
- public:
- AZ_TYPE_INFO(AssetTrackingAllocator, "{F6C08E92-559C-4153-9620-6A8491F78F10}");
-
- using Base = AZ::SimpleSchemaAllocator;
- using Descriptor = Base::Descriptor;
-
- AssetTrackingAllocator()
- : Base("AssetTrackingAllocator", "Allocator for the AssetTracking")
- {
- DisableOverriding();
- }
- };
-
- using AZStdAssetTrackingAllocator = AZ::AZStdAlloc;
- using AssetTrackingString = AZStd::basic_string, AZStdAssetTrackingAllocator>;
-
- template
- using AssetTrackingMap = AZStd::unordered_map, AZStd::equal_to, AZStdAssetTrackingAllocator>;
-
-
- // ID for an asset that is hashable.
- // Currently only contains one string identifier, but we may want to store a more sophisticated ID in the future.
- struct AssetTrackingId
- {
- AssetTrackingId(const char* id) : m_id(id)
- {
- }
-
- bool operator==(const AssetTrackingId& other) const
- {
- return m_id == other.m_id;
- }
-
- AssetTrackingString m_id;
- };
-
- // Primary information about an asset.
- // Currently just contains the ID of the asset, but in the future may carry additional information about that asset (such as where in code it was initialized).
- struct AssetPrimaryInfo
- {
- const AssetTrackingId* m_id;
- };
-
- // Base class for a node in the asset tree. Implemented by the template AssetTreeNode<>.
- class AssetTreeNodeBase
- {
- public:
- virtual ~AssetTreeNodeBase() = default;
- virtual const AssetPrimaryInfo* GetAssetPrimaryInfo() const = 0;
- virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) = 0;
- };
-
- // Base class for an asset tree. Implemented by the template AssetTree<>.
- class AssetTreeBase
- {
- public:
- virtual ~AssetTreeBase() = default;
- virtual AssetTreeNodeBase& GetRoot() = 0;
- };
-
- // Base class for an asset allocation table. Implemented by the template AssetAllocationTable<>.
- class AssetAllocationTableBase
- {
- public:
- virtual ~AssetAllocationTableBase() = default;
- virtual AssetTreeNodeBase* FindAllocation(void* ptr) const = 0;
- };
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Hash functions for map support
-///////////////////////////////////////////////////////////////////////////////
-
-inline size_t AZStd::hash::operator()(const AZ::Debug::AssetTrackingId& info) const
-{
- return AZStd::hash()(info.m_id);
-}
-
diff --git a/Code/Framework/AzCore/AzCore/Debug/AssetTrackingTypesImpl.h b/Code/Framework/AzCore/AzCore/Debug/AssetTrackingTypesImpl.h
deleted file mode 100644
index eac809c406..0000000000
--- a/Code/Framework/AzCore/AzCore/Debug/AssetTrackingTypesImpl.h
+++ /dev/null
@@ -1,174 +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
-
-#include
-
-#include
-
-namespace AZ
-{
- namespace Debug
- {
- // A node in the current asset state tree.
- // Each thread maintains a stack of currently in-scope assets. As this stack changes the asset tree forms.
- // The same asset may appear in multiple places in the tree, e.g. if asset A is a common asset loaded by both asset B and asset C, the tree may look like:
- // Root -> B -> A
- // \--> C -> A
- template
- class AssetTreeNode : public AssetTreeNodeBase
- {
- public:
- AssetTreeNode(const AssetPrimaryInfo* primaryInfo = nullptr, AssetTreeNode* parent = nullptr) :
- m_primaryinfo(primaryInfo),
- m_parent(parent)
- {
- }
-
- ~AssetTreeNode() override = default;
-
- const AssetPrimaryInfo* GetAssetPrimaryInfo() const override
- {
- return m_primaryinfo;
- }
-
- AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) override
- {
- AssetTreeNodeBase* result = nullptr;
- auto childItr = m_children.find(id);
-
- if (childItr != m_children.end())
- {
- result = &childItr->second;
- }
- else
- {
- auto childResult = m_children.emplace(id, AssetTreeNode(info, this));
- result = &childResult.first->second;
- }
-
- return result;
- }
-
-
- using AssetMap = AssetTrackingMap;
-
- const AssetPrimaryInfo* m_primaryinfo;
- AssetTreeNode* m_parent;
- AssetMap m_children;
- AssetDataT m_data;
- };
-
- template
- class AssetTree : public AssetTreeBase
- {
- public:
- ~AssetTree() override = default;
-
- AssetTreeNodeBase& GetRoot() override
- {
- return m_rootAssets;
- }
-
- using NodeType = AssetTreeNode;
-
- NodeType m_rootAssets;
- };
-
-
- template
- struct AllocationRecord
- {
- AssetTreeNodeBase* m_asset;
- uint32_t m_size;
- AllocationDataT m_data;
- };
-
-
- template
- class AllocationTable : public AssetAllocationTableBase
- {
- public:
- using RecordType = AllocationRecord;
- using AllocationReverseMap = AZStd::map, AZStdAssetTrackingAllocator>;
- using mutex_type = AZStd::mutex;
- using lock_type = AZStd::lock_guard