diff --git a/.github/ISSUE_TEMPLATE/ar_bug_report.md b/.github/ISSUE_TEMPLATE/ar_bug_report.md
index 0d4aee9397..93b6e70b03 100644
--- a/.github/ISSUE_TEMPLATE/ar_bug_report.md
+++ b/.github/ISSUE_TEMPLATE/ar_bug_report.md
@@ -1,5 +1,5 @@
---
-name: ar_bug_report.md
+name: Automated Review bug report
about: Create a bug for a an issue found in the Automated Review
title: 'AR Bug Report'
labels: 'needs-triage,kind/bug,kind/automation'
diff --git a/.gitignore b/.gitignore
index 9fd70a927f..9012ec7576 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@ Editor/EditorEventLog.xml
Editor/EditorLayout.xml
**/*egg-info/**
**/*egg-link
+**/[Rr]estricted
UserSettings.xml
[Uu]ser/
FrameCapture/**
diff --git a/Assets/Editor/Scripts/export_all_project_levels.py b/Assets/Editor/Scripts/export_all_project_levels.py
deleted file mode 100755
index ba900b37a8..0000000000
--- a/Assets/Editor/Scripts/export_all_project_levels.py
+++ /dev/null
@@ -1,78 +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
-#
-#
-"""
-This script loads every level in a game project and exports them. You will be prompted with the standard
-Check-Out/Overwrite/Cancel dialog for each level.
-This is useful when there is a version update to a file that requires re-exporting.
-"""
-import sys, os
-import azlmbr.legacy.general as general
-import azlmbr.legacy.checkout_dialog as checkout_dialog
-
-
-class CheckOutDialogEnableAll:
- """
- Helper class to wrap enabling the "Apply to all" checkbox in the CheckOutDialog.
- Guarantees that the old setting will be restored.
- To use, do:
-
- with CheckOutDialogEnableAll():
- # your code here
- """
-
- def __init__(self):
- self.old_setting = False
-
- def __enter__(self):
- self.old_setting = checkout_dialog.enable_for_all(True)
- print(self.old_setting)
-
- def __exit__(self, type, value, traceback):
- checkout_dialog.enable_for_all(self.old_setting)
-
-
-level_list = []
-
-
-def is_in_special_folder(file_full_path):
- if file_full_path.find("_savebackup") >= 0:
- return True
- if file_full_path.find("_autobackup") >= 0:
- return True
- if file_full_path.find("_hold") >= 0:
- return True
- if file_full_path.find("_tmpresize") >= 0:
- return True
-
- return False
-
-
-game_folder = general.get_game_folder()
-
-
-# Recursively search every directory in the game project for files ending with .cry and .ly
-for root, dirs, files in os.walk(game_folder):
- for file in files:
- if file.endswith(".cry") or file.endswith(".ly"):
- # The engine expects the full path of the .cry file
- file_full_path = os.path.abspath(os.path.join(root, file))
- # Exclude files in special directories
- if not is_in_special_folder(file_full_path):
- level_list.append(file_full_path)
-
-# make the checkout dialog enable the 'Apply to all' checkbox
-with CheckOutDialogEnableAll():
-
- # For each valid .cry file found, open it in the editor and export it
- for level in level_list:
- if not isinstance(level, str):
- # general.open_level_no_prompt expects the file path in utf8 format
- level = level.encode("utf-8")
-
- general.open_level_no_prompt(level)
- general.export_to_engine()
diff --git a/Assets/Editor/Scripts/generatelod.py b/Assets/Editor/Scripts/generatelod.py
deleted file mode 100755
index 618827c5b4..0000000000
--- a/Assets/Editor/Scripts/generatelod.py
+++ /dev/null
@@ -1,40 +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
-#
-#
-'''
-Generates a 50% lod for the selected model
-
-@argument name="Lod Percentage", type="string", default="50.0f"
-'''
-
-import sys
-import time
-
-percentage = float(sys.argv[1])
-
-selectedcgf = lodtools.getselected()
-selectedmaterial = lodtools.getselectedmaterial()
-
-loadedmodel = lodtools.loadcgf(selectedcgf)
-loadedmaterial = lodtools.loadmaterial(selectedmaterial)
-
-if loadedmodel == True and loadedmaterial == True:
- lodtools.generatelodchain()
- finished = 0.0
- while finished >= 0.0:
- finished = lodtools.generatetick()
- print 'Lod Chain Generation progress: ' + str(finished)
- time.sleep(1)
- if finished == 1.0:
- break
-
- lodtools.createlod(1,percentage)
- lodtools.generatematerials(1,512,512)
- lodtools.savetextures(1)
- lodtools.savesettings()
- lodtools.reloadmodel()
-
diff --git a/Assets/Editor/Scripts/rename_cgf.py b/Assets/Editor/Scripts/rename_cgf.py
deleted file mode 100755
index 1196c4c6a2..0000000000
--- a/Assets/Editor/Scripts/rename_cgf.py
+++ /dev/null
@@ -1,14 +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
-#
-#
-objects = general.get_all_objects("", "") # Get the name list of all objects in the level.
-# If there is any object with the geometry file of "objects\\default\\primitive_box.cgf",
-# change it to "objects\\default\\primitive_cube.cgf".
-for obj in objects:
- geometry_file = general.get_entity_geometry_file(obj)
- if geometry_file == "objects\\default\\primitive_box.cgf":
- general.set_entity_geometry_file(obj, "objects\\default\\primitive_cube.cgf")
diff --git a/Assets/Editor/Scripts/select_story_anim_objects.py b/Assets/Editor/Scripts/select_story_anim_objects.py
deleted file mode 100755
index 93021baac4..0000000000
--- a/Assets/Editor/Scripts/select_story_anim_objects.py
+++ /dev/null
@@ -1,14 +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
-#
-#
-objects = general.get_all_objects("AnimObject", "") # Get the name list of all anim objects in the level.
-general.clear_selection()
-# If there is any object with the geometry file whose name contains "\\story\\", select it
-for obj in objects:
- geometry_file = general.get_entity_geometry_file(obj)
- if geometry_file.find("\\story\\") != -1:
- general.select_object(obj)
diff --git a/Assets/Editor/Scripts/tools_shelf_actions.py b/Assets/Editor/Scripts/tools_shelf_actions.py
deleted file mode 100755
index 8b99d76e1f..0000000000
--- a/Assets/Editor/Scripts/tools_shelf_actions.py
+++ /dev/null
@@ -1,508 +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 __future__
-import time, re, os, sys, itertools, ast
-import azlmbr.legacy.general as general
-
-global ctrlFile
-ctrlFile = 'setState.txt'
-global logfile
-logfile = 'Editor.log'
-
-global HIDDEN_MASK_PREFIX
-HIDDEN_MASK_PREFIX= 'hidden_mask_for_'
-global HIDDEN_MASK_PREFIX_LENGTH
-HIDDEN_MASK_PREFIX_LENGTH = len(HIDDEN_MASK_PREFIX)
-
-def getLogList(logfile):
- logList = [x for x in open(logfile, 'r')]
- return logList
-
-def getCheckList(ctrlFile):
- try:
- with open(ctrlFile):
- stateList = open(ctrlFile, 'r')
-
- except:
- open(ctrlFile, 'w').close()
- stateList = open(ctrlFile, 'r')
-
- checkList = [x for x in stateList]
- return checkList
-
-#Store/Restore CVars default values -----------------------------------------------------------------#
-if 'CVARS' not in globals():
- CVARS = {}
-
-def saveDefaultValue(cVars, value):
- if cVars not in CVARS:
- CVARS[cVars] = value
-
-def restoreDefaultValue(cVars):
- if cVars not in CVARS:
- return
-
- defaultValue = CVARS[cVars]
- del CVARS[cVars]
- if cVars.startswith(HIDDEN_MASK_PREFIX):
- type = cVars[HIDDEN_MASK_PREFIX_LENGTH:]
- general.set_hidemask(type, defaultValue)
- else:
- general.set_cvar(cVars, defaultValue)
-
-#toggle CVars--------------------------------------------------------------------#
-
-def updateCvars(cVars, value):
- saveDefaultValue(cVars, value)
- general.set_cvar(cVars, value)
-
-def toggleCvarsRestartCheck(log, state, mode, cVars, onValue, offValue, ctrlFile):
- if log in state:
- toggleCvarsV(mode, cVars, onValue, offValue, ctrlFile)
- else:
- stateList = open(ctrlFile, 'w')
- stateList.write(log)
- stateList = open(ctrlFile, 'r')
- toggleCvarsV(mode, cVars, onValue, offValue, ctrlFile)
-
-def toggleCvarsV(mode, cVars, onValue, offValue, ctrlFile):
- stateList = open(ctrlFile, 'r')
- setState = [x for x in enumerate(stateList)]
- blankCheck = [x for x in setState]
- getList = [x for x in stateList]
-
- if blankCheck == []:
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str("%s,{'%s': %s}" % (mode, cVars, offValue))+'\n'))
- general.set_cvar(cVars, offValue)
- else:
- stateList = open(ctrlFile, 'r')
- checkFor = str([x for x in stateList])
-
- if mode not in str(checkFor):
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
- getList.insert(1, str("%s,{'%s': %s}\n" % (mode, cVars , offValue)))
- print (str("{'%s': %s}\n" % (cVars , offValue)))
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(getList))
- general.set_cvar(cVars, offValue)
-
- else:
- stateList = open(ctrlFile, 'r')
- for d in enumerate(stateList):
- values = d[1].split(',')
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
-
- if mode in values[0]:
- getDict = ast.literal_eval(values[1])
- getState = getDict.get(cVars)
-
- if getState == offValue:
- getDict[cVars] = onValue
- joinStr = [mode,",",str(getDict), '\n']
- newLine = ''.join(joinStr)
- print (getDict)
- getList[d[0]] = newLine
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.set_cvar(cVars, onValue)
- else:
- getDict[cVars] = offValue
- joinStr = [mode,",",str(getDict), '\n']
- newLine = ''.join(joinStr)
- print (getDict)
- getList[d[0]] = newLine
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.set_cvar(cVars, offValue)
-
-def toggleCvarsValue(mode, cVars, onValue, offValue):
- currentValue = general.get_cvar(cVars)
-
- if type(onValue) is str:
- saveDefaultValue(cVars, currentValue)
- elif type(onValue) is int:
- saveDefaultValue(cVars, int(currentValue))
- elif type(onValue) is float:
- saveDefaultValue(cVars, float(currentValue))
- else:
- general.log('Failed to store default value for {0}'.format(cVars))
-
- if currentValue == str(onValue):
- general.set_cvar(cVars, offValue)
- else:
- general.set_cvar(cVars, onValue)
-
-#toggleConsol--------------------------------------------------------------------#
-
-def toggleConsolRestartCheck(log,state, mode, onValue, offValue, ctrlFile):
- if log in state:
- toggleConsolV(mode, onValue, offValue, ctrlFile)
- else:
- stateList = open(ctrlFile, 'w')
- stateList.write(log)
- stateList = open(ctrlFile, 'r')
- toggleConsolV(mode, onValue, offValue, ctrlFile)
-
-def toggleConsolV(mode, onValue, offValue):
- stateList = open(ctrlFile, 'r')
- setState = [x for x in enumerate(stateList)]
- blankCheck = [x for x in setState]
- getList = [x for x in stateList]
- onOffList = [onValue, offValue]
-
- if blankCheck == []:
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str("%s,'%s'" % (mode, offValue))+'\n'))
- general.run_console(offValue)
- else:
- stateList = open(ctrlFile, 'r')
- checkFor = str([x for x in stateList])
-
- if mode not in str(checkFor):
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
- getList.insert(1, str("%s,'%s'\n" % (mode, offValue)))
- print (str("{'%s': %s}\n" % (cVars , offValue)))
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(getList))
- general.run_console(onValue)
-
- else:
- stateList = open(ctrlFile, 'r')
- for d in enumerate(stateList):
-
- values = d[1].split(',')
-
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
-
- if mode in values[0]:
- getDict = values[1]
- off = ["'",str(offValue),"'", '\n']
- joinoff = ''.join(off)
-
- if values[1] == joinoff:
- getDict = onValue
- joinStr = [mode,",","'",getDict,"'", '\n']
- newLine = ''.join(joinStr)
- print (getDict)
- getList[d[0]] = str(newLine)
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.run_console(onValue)
- else:
- getDict = offValue
- joinStr = [mode,",","'",getDict,"'", '\n']
- newLine = ''.join(joinStr)
- print (getDict)
- getList[d[0]] = str(newLine)
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.run_console(offValue)
-
-def toggleConsolValue(log, state, mode, onValue, offValue):
- logList = getLogList(logfile)
- checkList = getCheckList(ctrlFile)
- toggleConsolRestartCheck(logList[1],checkList, mode, onValue, offValue, ctrlFile)
-
-#cycleCvars----------------------------------------------------------------------#
-
-def cycleCvarsRestartCheck(log, state, mode, cVars, cycleList, ctrlFile):
- if log in state:
- cycleCvarsV(mode, cVars, cycleList, ctrlFile)
- else:
- stateList = open(ctrlFile, 'w')
- stateList.write(log)
- stateList = open(ctrlFile, 'r')
- cycleCvarsV(mode, cVars, cycleList, ctrlFile)
-
-def cycleCvarsV(mode, cVars, cycleList, ctrlFile):
- stateList = open(ctrlFile, 'r')
- setState = [x for x in enumerate(stateList)]
- blankCheck = [x for x in setState]
- getList = [x for x in stateList]
-
- if blankCheck == []:
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str("%s,{'%s': %s}" % (mode, cVars, cycleList[1]))+'\n'))
- general.set_cvar(cVars, cycleList[1])
- else:
- stateList = open(ctrlFile, 'r')
- checkFor = str([x for x in stateList])
-
- if mode not in str(checkFor):
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
- getList.insert(1, str("%s,{'%s': %s}\n" % (mode, cVars , cycleList[1])))
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(getList))
- general.set_cvar(cVars, cycleList[1])
-
- else:
- stateList = open(ctrlFile, 'r')
-
- for d in enumerate(stateList):
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
- values = d[1].split(',')
-
- if mode in values[0]:
- getDict = ast.literal_eval(values[1])
- getState = getDict.get(cVars)
-
- cycleL = [x for x in enumerate(cycleList)]
-
- for x in cycleL:
- if getState == x[1]:
- number = [n[1] for n in cycleL]
- getMax = max(number)
- nextNum = x[0]+1
-
- if nextNum > getMax:
- getDict[cVars] = cycleList[0]
- joinStr = [mode,",",str(getDict), '\n']
- newLine = ''.join(joinStr)
- getList[d[0]] = newLine
- print (getDict)
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.set_cvar(cVars, cycleList[0])
- else:
- getDict[cVars] = cycleList[x[0]+1]
- joinStr = [mode,",",str(getDict), '\n']
- newLine = ''.join(joinStr)
- getList[d[0]] = newLine
- print (getDict)
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.set_cvar(cVars, cycleList[x[0]+1])
-
-def cycleCvarsValue(log, state, mode, cVars, cycleList):
- logList = getLogList(logfile)
- checkList = getCheckList(ctrlFile)
- cycleCvarsRestartCheck(logList[1],checkList, mode, cVars, cycleList, ctrlFile)
-
-def cycleCvarsFloatValue(cVars, cycleList):
- currentValueAsString = general.get_cvar(cVars)
- try:
- currentValue = float(currentValueAsString)
- except:
- currentValue = -1.0
-
- saveDefaultValue(cVars, currentValue)
-
- # make sure we sort the list in ascending fashion
- cycleList = sorted(cycleList)
-
- # find out what the next closest index is
- newIndex = 0
- for x in cycleList:
- if (currentValue < x):
- break
- newIndex = newIndex + 1
-
- # loop around, if we need to
- if newIndex >= len(cycleList):
- newIndex = 0
-
- general.set_cvar(cVars, cycleList[newIndex])
-
-
-def cycleCvarsIntValue(cVars, cycleList):
- currentValueAsString = general.get_cvar(cVars)
- try:
- currentValue = int(currentValueAsString)
- except:
- currentValue = 0
-
- saveDefaultValue(cVars, currentValue)
-
- # find out what index we're on already
- # default to -1 so that when we increment to the next, we'll be at 0
- newIndex = -1
- for x in cycleList:
- if (currentValue == x):
- break
- newIndex = newIndex + 1
-
- # move to the next item
- newIndex = newIndex + 1
-
- # validate
- if newIndex >= len(cycleList):
- newIndex = 0
-
- general.set_cvar(cVars, cycleList[newIndex])
-
-#cycleConsol----------------------------------------------------------------------#
-
-def cycleConsolRestartCheck(log, state, mode, cycleList, ctrlFile):
- if log in state:
- cycleConsolV(mode, cycleList, ctrlFile)
- else:
- stateList = open(ctrlFile, 'w')
- stateList.write(log)
- stateList = open(ctrlFile, 'r')
- cycleConsolV(mode, cycleList, ctrlFile)
-
-def cycleConsolV(mode, cycleList, ctrlFile):
- stateList = open(ctrlFile, 'r')
- setState = [x for x in enumerate(stateList)]
- blankCheck = [x for x in setState]
- getList = [x for x in stateList]
-
- if blankCheck == []:
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str("%s,'%s'" % (mode, cycleList[0]))+'\n'))
- general.run_console(cycleList[0])
- else:
- stateList = open(ctrlFile, 'r')
- checkFor = str([x for x in stateList])
-
- if mode not in str(checkFor):
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
- getList.insert(1, str("%s,'%s'\n" % (mode, cycleList[0])))
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(getList))
- general.run_console(cycleList[0])
-
- else:
- stateList = open(ctrlFile, 'r')
- for d in enumerate(stateList):
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
- values = d[1].split(',')
-
- if mode in values[0]:
- newValue = ''.join(values[1].split('\n'))
- cycleL = [e for e in enumerate(cycleList)]
- getDict = ''.join(values[1].split('\n'))
-
- for x in cycleL:
-
- if newValue in "'%s'" % x[1]:
- number = [n[0] for n in cycleL]
- getMax = max(number)
- nextNum = x[0]+1
-
- if nextNum > getMax:
- getDict = '%s' % cycleList[0]
- joinStr = [mode,",","'",getDict,"'", '\n']
- newLine = ''.join(joinStr)
- getList[d[0]] = newLine
- print (getDict)
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.run_console(getDict)
- else:
- getDict = '%s' % cycleList[x[0]+1]
- joinStr = [mode,",","'",getDict,"'", '\n']
- newLine = ''.join(joinStr)
- getList[d[0]] = newLine
- print (getDict)
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- general.run_console(getDict)
-
-def cycleConsolValue(mode, cycleList):
- logList = getLogList(logfile)
- checkList = getCheckList(ctrlFile)
- cycleConsolRestartCheck(logList[1],checkList, mode, cycleList, ctrlFile)
-
-def toggleHideMaskValues(type):
- cVars = "%s%s" % (HIDDEN_MASK_PREFIX, type)
- currentValue = general.get_hidemask(type)
- saveDefaultValue(cVars, int(currentValue))
- if (currentValue):
- general.set_hidemask(type, 0)
- else:
- general.set_hidemask(type, 1)
-
-#toggleHide------------------------------------------------------------------------#
-
-def toggleHideRestartCheck(log, state, mode, type, onValue, offValue, ctrlFile):
- if log in state:
- toggleHideByT(mode, type, onValue, offValue, ctrlFile)
- else:
- stateList = open(ctrlFile, 'w')
- stateList.write(log)
- stateList = open(ctrlFile, 'r')
- toggleHideByT(mode, type, onValue, offValue, ctrlFile)
-
-def toggleHideByType(mode, type, onValue, offValue):
- logList = getLogList(logfile)
- checkList = getCheckList(ctrlFile)
- toggleHideRestartCheck(logList[1],checkList, mode, type, onValue, offValue, ctrlFile)
-
-def toggleHideByT(mode, type, onValue, offValue, ctrlFile):
- stateList = open(ctrlFile, 'r')
- setState = [x for x in enumerate(stateList)]
- blankCheck = [x for x in setState]
- getList = [x for x in stateList]
-
- if blankCheck == []:
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str("%s,{'%s': %s}" % (mode, type, offValue))+'\n'))
-
- hideByType(type)
- else:
- stateList = open(ctrlFile, 'r')
- checkFor = str([x for x in stateList])
-
- if mode not in str(checkFor):
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
- getList.insert(1, str("%s,{'%s': %s}\n" % (mode, type , offValue)))
- print (str("{'%s': %s}\n" % (type , offValue)))
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(getList))
- hideByType(type)
-
- else:
- stateList = open(ctrlFile, 'r')
- for d in enumerate(stateList):
- values = d[1].split(',')
- stateList = open(ctrlFile, 'r')
- getList = [x for x in stateList]
-
- if mode in values[0]:
- getDict = ast.literal_eval(values[1])
- getState = getDict.get(type)
-
- if getState == offValue:
- getDict[type] = onValue
- joinStr = [mode,",",str(getDict), '\n']
- newLine = ''.join(joinStr)
- print (getDict)
- getList[d[0]] = newLine
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- unHideByType(type)
- else:
- getDict[type] = offValue
- joinStr = [mode,",",str(getDict), '\n']
- newLine = ''.join(joinStr)
- print (getDict)
- getList[d[0]] = newLine
- stateList = open(ctrlFile, 'w')
- stateList.write(''.join(str(''.join(getList))))
- hideByType(type)
-
-def hideByType(type):
- typeList = general.get_all_objects(str(type), "")
- for x in typeList:
- general.hide_object(x)
-
-def unHideByType(type):
- typeList = general.get_all_objects(str(type), "")
- for x in typeList:
- general.unhide_object(x)
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/Gems/AssetMemoryAnalyzer/CMakeLists.txt b/AutomatedTesting/Editor/Scripts/Profiler/__init__.py
similarity index 89%
rename from Gems/AssetMemoryAnalyzer/CMakeLists.txt
rename to AutomatedTesting/Editor/Scripts/Profiler/__init__.py
index 2bb380fae3..7a325ca97e 100644
--- a/Gems/AssetMemoryAnalyzer/CMakeLists.txt
+++ b/AutomatedTesting/Editor/Scripts/Profiler/__init__.py
@@ -5,5 +5,3 @@
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
-
-add_subdirectory(Code)
diff --git a/AutomatedTesting/Editor/Scripts/Profiler/profiler_system_example.py b/AutomatedTesting/Editor/Scripts/Profiler/profiler_system_example.py
new file mode 100644
index 0000000000..16f161c50e
--- /dev/null
+++ b/AutomatedTesting/Editor/Scripts/Profiler/profiler_system_example.py
@@ -0,0 +1,30 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+import azlmbr.debug as debug
+
+import pathlib
+
+def test_profiler_system():
+ if not debug.g_ProfilerSystem.IsValid():
+ print('g_ProfilerSystem is INVALID')
+ return
+
+ state = 'ACTIVE' if debug.g_ProfilerSystem.IsActive() else 'INACTIVE'
+ print(f'Profiler system is currently {state}')
+
+ capture_location = pathlib.Path(debug.g_ProfilerSystem.GetCaptureLocation())
+ print(f'Capture location set to {capture_location}')
+
+ print('Capturing single frame...' )
+ capture_file = str(capture_location / 'script_capture_frame.json')
+ debug.g_ProfilerSystem.CaptureFrame(capture_file)
+
+# Invoke main function
+if __name__ == '__main__':
+ test_profiler_system()
diff --git a/AutomatedTesting/Editor/Scripts/auto_lod.py b/AutomatedTesting/Editor/Scripts/auto_lod.py
new file mode 100644
index 0000000000..058303242a
--- /dev/null
+++ b/AutomatedTesting/Editor/Scripts/auto_lod.py
@@ -0,0 +1,124 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+import os, traceback, binascii, sys, json, pathlib, logging
+import azlmbr.math
+import azlmbr.bus
+from scene_helpers import *
+
+#
+# SceneAPI Processor
+#
+
+def update_manifest(scene):
+ import uuid
+ import azlmbr.scene as sceneApi
+ import azlmbr.scene.graph
+ from scene_api import scene_data as sceneData
+
+ graph = sceneData.SceneGraph(scene.graph)
+ # Get a list of all the mesh nodes, as well as all the nodes
+ mesh_name_list, all_node_paths = get_mesh_node_names(graph)
+ mesh_name_list.sort(key=lambda node: str.casefold(node.get_path()))
+ scene_manifest = sceneData.SceneManifest()
+
+ clean_filename = scene.sourceFilename.replace('.', '_')
+
+ # Compute the filename of the scene file
+ source_basepath = scene.watchFolder
+ source_relative_path = os.path.dirname(os.path.relpath(clean_filename, source_basepath))
+ source_filename_only = os.path.basename(clean_filename)
+
+ created_entities = []
+ previous_entity_id = azlmbr.entity.InvalidEntityId
+ first_mesh = True
+
+ # Make a list of mesh node paths
+ mesh_path_list = list(map(lambda node: node.get_path(), mesh_name_list))
+
+ # Assume the first mesh is the main mesh
+ main_mesh = mesh_name_list[0]
+ mesh_path = main_mesh.get_path()
+
+ # Create a unique mesh group name using the filename + node name
+ mesh_group_name = '{}_{}'.format(source_filename_only, main_mesh.get_name())
+ # Remove forbidden filename characters from the name since this will become a file on disk later
+ mesh_group_name = "".join(char for char in mesh_group_name if char not in "|<>:\"/?*\\")
+ # Add the MeshGroup to the manifest and give it a unique ID
+ mesh_group = scene_manifest.add_mesh_group(mesh_group_name)
+ mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, source_filename_only + mesh_path)) + '}'
+ # Set our current node as the only node that is included in this MeshGroup
+ scene_manifest.mesh_group_select_node(mesh_group, mesh_path)
+
+ # Explicitly remove all other nodes to prevent implicit inclusions
+ for node in mesh_path_list:
+ if node != mesh_path:
+ scene_manifest.mesh_group_unselect_node(mesh_group, node)
+
+ # Create a LOD rule
+ lod_rule = scene_manifest.mesh_group_add_lod_rule(mesh_group)
+
+ # Loop all the mesh nodes after the first
+ for x in mesh_path_list[1:]:
+ # Add a new LOD level
+ lod = scene_manifest.lod_rule_add_lod(lod_rule)
+ # Select the current mesh for this LOD level
+ scene_manifest.lod_select_node(lod, x)
+
+ # Unselect every other mesh for this LOD level
+ for y in mesh_path_list:
+ if y != x:
+ scene_manifest.lod_unselect_node(lod, y)
+
+ # Create an editor entity
+ entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name)
+ # Add an EditorMeshComponent to the entity
+ editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "AZ::Render::EditorMeshComponent")
+ # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just created + the azmodel extension
+ # The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel
+ # The assetHint will be converted to an AssetId later during prefab loading
+ json_update = json.dumps({
+ "Controller": { "Configuration": { "ModelAsset": {
+ "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
+ });
+ # Apply the JSON above to the component we created
+ result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update)
+
+ if not result:
+ raise RuntimeError("UpdateComponentForEntity failed for Mesh component")
+
+ create_prefab(scene_manifest, source_filename_only, [entity_id])
+
+ # Convert the manifest to a JSON string and return it
+ new_manifest = scene_manifest.export()
+
+ return new_manifest
+
+sceneJobHandler = None
+
+def on_update_manifest(args):
+ try:
+ scene = args[0]
+ return update_manifest(scene)
+ except RuntimeError as err:
+ print (f'ERROR - {err}')
+ log_exception_traceback()
+ except:
+ log_exception_traceback()
+
+ global sceneJobHandler
+ sceneJobHandler = None
+
+# try to create SceneAPI handler for processing
+try:
+ import azlmbr.scene as sceneApi
+ if (sceneJobHandler == None):
+ sceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler()
+ sceneJobHandler.connect()
+ sceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest)
+except:
+ sceneJobHandler = None
diff --git a/AutomatedTesting/Editor/Scripts/scene_helpers.py b/AutomatedTesting/Editor/Scripts/scene_helpers.py
new file mode 100644
index 0000000000..761068e796
--- /dev/null
+++ b/AutomatedTesting/Editor/Scripts/scene_helpers.py
@@ -0,0 +1,95 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+import traceback, logging, json
+from typing import Tuple, List
+
+import azlmbr.bus
+from scene_api import scene_data as sceneData
+from scene_api.scene_data import SceneGraphName
+
+
+def log_exception_traceback():
+ """
+ Outputs an exception stacktrace.
+ """
+ data = traceback.format_exc()
+ logger = logging.getLogger('python')
+ logger.error(data)
+
+
+def sanitize_name_for_disk(name: str):
+ """
+ Removes illegal filename characters from a string.
+
+ :param name: String to clean.
+ :return: Name with illegal characters removed.
+ """
+ return "".join(char for char in name if char not in "|<>:\"/?*\\")
+
+
+def get_mesh_node_names(scene_graph: sceneData.SceneGraph) -> Tuple[List[SceneGraphName], List[str]]:
+ """
+ Returns a tuple of all the mesh nodes as well as all the node paths
+
+ :param scene_graph: Scene graph to search
+ :return: Tuple of [Mesh Nodes, All Node Paths]
+ """
+ import azlmbr.scene as sceneApi
+ import azlmbr.scene.graph
+
+ mesh_data_list = []
+ node = scene_graph.get_root()
+ children = []
+ paths = []
+
+ while node.IsValid():
+ # store children to process after siblings
+ if scene_graph.has_node_child(node):
+ children.append(scene_graph.get_node_child(node))
+
+ node_name = sceneData.SceneGraphName(scene_graph.get_node_name(node))
+ paths.append(node_name.get_path())
+
+ # store any node that has mesh data content
+ node_content = scene_graph.get_node_content(node)
+ if node_content.CastWithTypeName('MeshData'):
+ if scene_graph.is_node_end_point(node) is False:
+ if len(node_name.get_path()):
+ mesh_data_list.append(sceneData.SceneGraphName(scene_graph.get_node_name(node)))
+
+ # advance to next node
+ if scene_graph.has_node_sibling(node):
+ node = scene_graph.get_node_sibling(node)
+ elif children:
+ node = children.pop()
+ else:
+ node = azlmbr.scene.graph.NodeIndex()
+
+ return mesh_data_list, paths
+
+
+def create_prefab(scene_manifest: sceneData.SceneManifest, prefab_name: str, entities: list) -> None:
+ prefab_filename = prefab_name + ".prefab"
+ created_template_id = azlmbr.prefab.PrefabSystemScriptingBus(azlmbr.bus.Broadcast, "CreatePrefab", entities,
+ prefab_filename)
+
+ if created_template_id is None or created_template_id == azlmbr.prefab.InvalidTemplateId:
+ raise RuntimeError("CreatePrefab {} failed".format(prefab_filename))
+
+ # Convert the prefab to a JSON string
+ output = azlmbr.prefab.PrefabLoaderScriptingBus(azlmbr.bus.Broadcast, "SaveTemplateToString", created_template_id)
+
+ if output is not None and output.IsSuccess():
+ json_string = output.GetValue()
+ uuid = azlmbr.math.Uuid_CreateRandom().ToString()
+ json_result = json.loads(json_string)
+ # Add a PrefabGroup to the manifest and store the JSON on it
+ scene_manifest.add_prefab_group(prefab_name, uuid, json_result)
+ else:
+ raise RuntimeError(
+ "SaveTemplateToString failed for template id {}, prefab {}".format(created_template_id, prefab_filename))
diff --git a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
index e832b1f82b..db8df09091 100644
--- a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
+++ b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
@@ -5,55 +5,17 @@
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
-import os, traceback, binascii, sys, json, pathlib
-import azlmbr.math
import azlmbr.bus
+import azlmbr.math
+
+from scene_api.scene_data import PrimitiveShape, DecompositionMode
+from scene_helpers import *
+
#
# SceneAPI Processor
#
-
-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_mesh_node_names(sceneGraph):
- import azlmbr.scene as sceneApi
- import azlmbr.scene.graph
- from scene_api import scene_data as sceneData
-
- meshDataList = []
- node = sceneGraph.get_root()
- children = []
- paths = []
-
- while node.IsValid():
- # store children to process after siblings
- if sceneGraph.has_node_child(node):
- children.append(sceneGraph.get_node_child(node))
-
- nodeName = sceneData.SceneGraphName(sceneGraph.get_node_name(node))
- paths.append(nodeName.get_path())
-
- # store any node that has mesh data content
- nodeContent = sceneGraph.get_node_content(node)
- if nodeContent.CastWithTypeName('MeshData'):
- if sceneGraph.is_node_end_point(node) is False:
- if (len(nodeName.get_path())):
- meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node)))
-
- # advance to next node
- if sceneGraph.has_node_sibling(node):
- node = sceneGraph.get_node_sibling(node)
- elif children:
- node = children.pop()
- else:
- node = azlmbr.scene.graph.NodeIndex()
-
- return meshDataList, paths
-
def add_material_component(entity_id):
# Create an override AZ::Render::EditorMaterialComponent
editor_material_component = azlmbr.entity.EntityUtilityBus(
@@ -64,24 +26,53 @@ def add_material_component(entity_id):
# this fills out the material asset to a known product AZMaterial asset relative path
json_update = json.dumps({
- "Controller": { "Configuration": { "materials": [
- {
- "Key": {},
- "Value": { "MaterialAsset":{
- "assetHint": "materials/basic_grey.azmaterial"
- }}
- }]
- }}
- });
- result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_material_component, json_update)
+ "Controller": {"Configuration": {"materials": [
+ {
+ "Key": {},
+ "Value": {"MaterialAsset": {
+ "assetHint": "materials/basic_grey.azmaterial"
+ }}
+ }]
+ }}
+ })
+ result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id,
+ editor_material_component, json_update)
if not result:
raise RuntimeError("UpdateComponentForEntity for editor_material_component failed")
+
+def add_physx_meshes(scene_manifest: sceneData.SceneManifest, source_file_name: str, mesh_name_list: List, all_node_paths: List[str]):
+ first_mesh = mesh_name_list[0].get_path()
+
+ # Add a Box Primitive PhysX mesh with a comment
+ physx_box = scene_manifest.add_physx_primitive_mesh_group(source_file_name + "_box", PrimitiveShape.BOX, 0.0, None)
+ scene_manifest.physx_mesh_group_add_comment(physx_box, "This is a box primitive")
+ # Select the first mesh, unselect every other node
+ scene_manifest.physx_mesh_group_add_selected_node(physx_box, first_mesh)
+
+ for node in all_node_paths:
+ if node != first_mesh:
+ scene_manifest.physx_mesh_group_add_unselected_node(physx_box, node)
+
+ # Add a Convex Mesh PhysX mesh with a comment
+ convex_mesh = scene_manifest.add_physx_convex_mesh_group(source_file_name + "_convex", 0.08, .0004,
+ True, True, True, True, True, 24, True, "Glass")
+ scene_manifest.physx_mesh_group_add_comment(convex_mesh, "This is a convex mesh")
+ # Select/Unselect nodes using lists
+ all_except_first_mesh = [x for x in all_node_paths if x != first_mesh]
+ scene_manifest.physx_mesh_group_add_selected_unselected_nodes(convex_mesh, [first_mesh], all_except_first_mesh)
+
+ # Configure mesh decomposition for this mesh
+ scene_manifest.physx_mesh_group_decompose_meshes(convex_mesh, 512, 32, .002, 100100, DecompositionMode.TETRAHEDRON,
+ 0.06, 0.055, 0.00015, 3, 3, True, False)
+
+ # Add a Triangle mesh
+ triangle = scene_manifest.add_physx_triangle_mesh_group(source_file_name + "_triangle", False, True, True, True, True, True)
+ scene_manifest.physx_mesh_group_add_selected_unselected_nodes(triangle, [first_mesh], all_except_first_mesh)
+
def update_manifest(scene):
- import json
import uuid, os
- import azlmbr.scene as sceneApi
import azlmbr.scene.graph
from scene_api import scene_data as sceneData
@@ -89,9 +80,9 @@ def update_manifest(scene):
# Get a list of all the mesh nodes, as well as all the nodes
mesh_name_list, all_node_paths = get_mesh_node_names(graph)
scene_manifest = sceneData.SceneManifest()
-
+
clean_filename = scene.sourceFilename.replace('.', '_')
-
+
# Compute the filename of the scene file
source_basepath = scene.watchFolder
source_relative_path = os.path.dirname(os.path.relpath(clean_filename, source_basepath))
@@ -101,6 +92,8 @@ def update_manifest(scene):
previous_entity_id = azlmbr.entity.InvalidEntityId
first_mesh = True
+ add_physx_meshes(scene_manifest, source_filename_only, mesh_name_list, all_node_paths)
+
# Loop every mesh node in the scene
for activeMeshIndex in range(len(mesh_name_list)):
mesh_name = mesh_name_list[activeMeshIndex]
@@ -108,52 +101,82 @@ def update_manifest(scene):
# Create a unique mesh group name using the filename + node name
mesh_group_name = '{}_{}'.format(source_filename_only, mesh_name.get_name())
# Remove forbidden filename characters from the name since this will become a file on disk later
- mesh_group_name = "".join(char for char in mesh_group_name if char not in "|<>:\"/?*\\")
+ mesh_group_name = sanitize_name_for_disk(mesh_group_name)
# Add the MeshGroup to the manifest and give it a unique ID
mesh_group = scene_manifest.add_mesh_group(mesh_group_name)
mesh_group['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, source_filename_only + mesh_path)) + '}'
# Set our current node as the only node that is included in this MeshGroup
scene_manifest.mesh_group_select_node(mesh_group, mesh_path)
+ scene_manifest.mesh_group_add_comment(mesh_group, "Hello World")
# Explicitly remove all other nodes to prevent implicit inclusions
for node in all_node_paths:
if node != mesh_path:
scene_manifest.mesh_group_unselect_node(mesh_group, node)
+ scene_manifest.mesh_group_add_cloth_rule(mesh_group, mesh_path, "Col0", 1, "Col0", 2, "Col0", 2, 3)
+ scene_manifest.mesh_group_add_advanced_mesh_rule(mesh_group, True, False, True, "Col0")
+ scene_manifest.mesh_group_add_skin_rule(mesh_group, 3, 0.002)
+ scene_manifest.mesh_group_add_tangent_rule(mesh_group, 1, 0)
+
# Create an editor entity
entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name)
# Add an EditorMeshComponent to the entity
- editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "AZ::Render::EditorMeshComponent")
- # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just created + the azmodel extension
- # The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel
- # The assetHint will be converted to an AssetId later during prefab loading
+ editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName",
+ entity_id, "AZ::Render::EditorMeshComponent")
+ # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just
+ # created + the azmodel extension The MeshGroup we created will be output as a product in the asset's path
+ # named mesh_group_name.azmodel The assetHint will be converted to an AssetId later during prefab loading
json_update = json.dumps({
- "Controller": { "Configuration": { "ModelAsset": {
- "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
- });
+ "Controller": {"Configuration": {"ModelAsset": {
+ "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel"}}}
+ })
# Apply the JSON above to the component we created
- result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update)
+ result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id,
+ editor_mesh_component, json_update)
if not result:
raise RuntimeError("UpdateComponentForEntity failed for Mesh component")
+ # Add a physics component referencing the triangle mesh we made for the first node
+ if previous_entity_id is None:
+ physx_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName",
+ entity_id, "{FD429282-A075-4966-857F-D0BBF186CFE6} EditorColliderComponent")
+
+ json_update = json.dumps({
+ "ShapeConfiguration": {
+ "PhysicsAsset": {
+ "Asset": {
+ "assetHint": os.path.join(source_relative_path, source_filename_only + "_triangle.pxmesh")
+ }
+ }
+ }
+ })
+
+ result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, physx_mesh_component, json_update)
+
+ if not result:
+ raise RuntimeError("UpdateComponentForEntity failed for PhysX mesh component")
+
# an example of adding a material component to override the default material
if previous_entity_id is not None and first_mesh:
first_mesh = False
add_material_component(entity_id)
# Get the transform component
- transform_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0")
+ transform_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName",
+ entity_id, "27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0")
# Set this entity to be a child of the last entity we created
# This is just an example of how to do parenting and isn't necessarily useful to parent everything like this
if previous_entity_id is not None:
transform_json = json.dumps({
- "Parent Entity" : previous_entity_id.to_json()
- });
+ "Parent Entity": previous_entity_id.to_json()
+ })
# Apply the JSON update
- result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, transform_component, transform_json)
+ result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id,
+ transform_component, transform_json)
if not result:
raise RuntimeError("UpdateComponentForEntity failed for Transform component")
@@ -165,37 +188,23 @@ def update_manifest(scene):
created_entities.append(entity_id)
# Create a prefab with all our entities
- prefab_filename = source_filename_only + ".prefab"
- created_template_id = azlmbr.prefab.PrefabSystemScriptingBus(azlmbr.bus.Broadcast, "CreatePrefab", created_entities, prefab_filename)
-
- if created_template_id == azlmbr.prefab.InvalidTemplateId:
- raise RuntimeError("CreatePrefab {} failed".format(prefab_filename))
-
- # Convert the prefab to a JSON string
- output = azlmbr.prefab.PrefabLoaderScriptingBus(azlmbr.bus.Broadcast, "SaveTemplateToString", created_template_id)
-
- if output.IsSuccess():
- jsonString = output.GetValue()
- uuid = azlmbr.math.Uuid_CreateRandom().ToString()
- jsonResult = json.loads(jsonString)
- # Add a PrefabGroup to the manifest and store the JSON on it
- scene_manifest.add_prefab_group(source_filename_only, uuid, jsonResult)
- else:
- raise RuntimeError("SaveTemplateToString failed for template id {}, prefab {}".format(created_template_id, prefab_filename))
+ create_prefab(scene_manifest, source_filename_only, created_entities)
# Convert the manifest to a JSON string and return it
new_manifest = scene_manifest.export()
return new_manifest
+
sceneJobHandler = None
+
def on_update_manifest(args):
try:
scene = args[0]
return update_manifest(scene)
except RuntimeError as err:
- print (f'ERROR - {err}')
+ print(f'ERROR - {err}')
log_exception_traceback()
except:
log_exception_traceback()
@@ -203,10 +212,12 @@ def on_update_manifest(args):
global sceneJobHandler
sceneJobHandler = None
+
# try to create SceneAPI handler for processing
try:
import azlmbr.scene as sceneApi
- if (sceneJobHandler == None):
+
+ if sceneJobHandler is None:
sceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler()
sceneJobHandler.connect()
sceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest)
diff --git a/AutomatedTesting/Gem/AssetProcessorGemConfig.setreg b/AutomatedTesting/Gem/AssetProcessorGemConfig.setreg
index 043774c9cc..d4de26a2dc 100644
--- a/AutomatedTesting/Gem/AssetProcessorGemConfig.setreg
+++ b/AutomatedTesting/Gem/AssetProcessorGemConfig.setreg
@@ -3,19 +3,19 @@
"AssetProcessor": {
"Settings": {
"Exclude PythonTest Benchmark Settings Assets": {
- "pattern": ".*\\\\/PythonTests\\\\/.*benchmarksettings"
+ "pattern": "(^|.+/)PythonTests/.*benchmarksettings"
},
"Exclude fbx_tests": {
- "pattern": ".*\\\\/fbx_tests\\\\/assets\\\\/.*"
+ "pattern": "(^|.+/)fbx_tests/assets(/.+)$"
},
"Exclude wwise_bank_dependency_tests": {
- "pattern": ".*\\\\/wwise_bank_dependency_tests\\\\/assets\\\\/.*"
+ "pattern": "(^|.+/)wwise_bank_dependency_tests/assets(/.+)$"
},
"Exclude AssetProcessorTestAssets": {
- "pattern": ".*\\\\/asset_processor_tests\\\\/assets\\\\/.*"
+ "pattern": "(^|.+/)asset_processor_tests/assets(/.+)$"
},
"Exclude Restricted AssetProcessorTestAssets": {
- "pattern": ".*\\\\/asset_processor_tests\\\\/restricted\\\\/.*"
+ "pattern": "(^|.+/)asset_processor_tests/restricted(/.+)$"
}
}
}
diff --git a/AutomatedTesting/Gem/Code/CMakeLists.txt b/AutomatedTesting/Gem/Code/CMakeLists.txt
index 6f55cc2764..8808507765 100644
--- a/AutomatedTesting/Gem/Code/CMakeLists.txt
+++ b/AutomatedTesting/Gem/Code/CMakeLists.txt
@@ -14,15 +14,25 @@ ly_add_target(
FILES_CMAKE
automatedtesting_files.cmake
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
+ automatedtesting_autogen_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
PUBLIC
Include
BUILD_DEPENDENCIES
+ PUBLIC
+ AZ::AzNetworking
+ Gem::Multiplayer
PRIVATE
AZ::AzCore
Gem::Atom_AtomBridge.Static
+ Gem::Multiplayer.Static
+ AUTOGEN_RULES
+ *.AutoComponent.xml,AutoComponent_Header.jinja,$path/$fileprefix.AutoComponent.h
+ *.AutoComponent.xml,AutoComponent_Source.jinja,$path/$fileprefix.AutoComponent.cpp
+ *.AutoComponent.xml,AutoComponentTypes_Header.jinja,$path/AutoComponentTypes.h
+ *.AutoComponent.xml,AutoComponentTypes_Source.jinja,$path/AutoComponentTypes.cpp
)
# if enabled, AutomatedTesting is used by all kinds of applications
diff --git a/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml b/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml
new file mode 100644
index 0000000000..46d6191835
--- /dev/null
+++ b/AutomatedTesting/Gem/Code/Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/Code/Source/AutomatedTestingModule.cpp b/AutomatedTesting/Gem/Code/Source/AutomatedTestingModule.cpp
index 7ed37e89ca..b5be8410ef 100644
--- a/AutomatedTesting/Gem/Code/Source/AutomatedTestingModule.cpp
+++ b/AutomatedTesting/Gem/Code/Source/AutomatedTestingModule.cpp
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
@@ -27,6 +28,8 @@ namespace AutomatedTesting
m_descriptors.insert(m_descriptors.end(), {
AutomatedTestingSystemComponent::CreateDescriptor(),
});
+
+ CreateComponentDescriptors(m_descriptors); //< Register multiplayer components
}
/**
diff --git a/AutomatedTesting/Gem/Code/Source/AutomatedTestingSystemComponent.cpp b/AutomatedTesting/Gem/Code/Source/AutomatedTestingSystemComponent.cpp
index 3b373b1f65..06a0775d70 100644
--- a/AutomatedTesting/Gem/Code/Source/AutomatedTestingSystemComponent.cpp
+++ b/AutomatedTesting/Gem/Code/Source/AutomatedTestingSystemComponent.cpp
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
@@ -45,7 +46,7 @@ namespace AutomatedTesting
void AutomatedTestingSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
- AZ_UNUSED(required);
+ required.push_back(AZ_CRC_CE("MultiplayerService"));
}
void AutomatedTestingSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
@@ -60,6 +61,7 @@ namespace AutomatedTesting
void AutomatedTestingSystemComponent::Activate()
{
AutomatedTestingRequestBus::Handler::BusConnect();
+ RegisterMultiplayerComponents(); //< Register AutomatedTesting's multiplayer components to assign NetComponentIds
}
void AutomatedTestingSystemComponent::Deactivate()
diff --git a/AutomatedTesting/Gem/Code/automatedtesting_autogen_files.cmake b/AutomatedTesting/Gem/Code/automatedtesting_autogen_files.cmake
new file mode 100644
index 0000000000..b3c6fcaa0b
--- /dev/null
+++ b/AutomatedTesting/Gem/Code/automatedtesting_autogen_files.cmake
@@ -0,0 +1,14 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+ ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponent_Common.jinja
+ ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponent_Header.jinja
+ ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponent_Source.jinja
+ ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponentTypes_Header.jinja
+ ${LY_ROOT_FOLDER}/Gems/Multiplayer/Code/Include/Multiplayer/AutoGen/AutoComponentTypes_Source.jinja
+)
diff --git a/AutomatedTesting/Gem/Code/automatedtesting_files.cmake b/AutomatedTesting/Gem/Code/automatedtesting_files.cmake
index 6bf2bf72d9..eb619104a4 100644
--- a/AutomatedTesting/Gem/Code/automatedtesting_files.cmake
+++ b/AutomatedTesting/Gem/Code/automatedtesting_files.cmake
@@ -11,4 +11,5 @@ set(FILES
Source/AutomatedTestingModule.cpp
Source/AutomatedTestingSystemComponent.cpp
Source/AutomatedTestingSystemComponent.h
+ Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml
)
diff --git a/AutomatedTesting/Gem/Code/enabled_gems.cmake b/AutomatedTesting/Gem/Code/enabled_gems.cmake
index 7d33a65bc7..3915fd36da 100644
--- a/AutomatedTesting/Gem/Code/enabled_gems.cmake
+++ b/AutomatedTesting/Gem/Code/enabled_gems.cmake
@@ -56,4 +56,5 @@ set(ENABLED_GEMS
AudioSystem
Terrain
Profiler
+ Multiplayer
)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
index ff3cd5c465..26eb96e7ec 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
@@ -20,19 +20,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED)
COMPONENT
Atom
)
- ly_add_pytest(
- NAME AutomatedTesting::Atom_TestSuite_Main_Optimized
- TEST_SUITE main
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
- TEST_SERIAL
- TIMEOUT 600
- RUNTIME_DEPENDENCIES
- AssetProcessor
- AutomatedTesting.Assets
- Editor
- COMPONENT
- Atom
- )
ly_add_pytest(
NAME AutomatedTesting::Atom_TestSuite_Sandbox
TEST_SUITE sandbox
@@ -60,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.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py
index 6cc48984ab..d79e144ae0 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py
@@ -4,252 +4,117 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-import logging
-import os
-
import pytest
-import ly_test_tools.environment.file_system as file_system
-import editor_python_test_tools.hydra_test_utils as hydra
-from Atom.atom_utils.atom_constants import LIGHT_TYPES
-
-logger = logging.getLogger(__name__)
-TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
+from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-@pytest.mark.parametrize("level", ["auto_test"])
-class TestAtomEditorComponentsMain(object):
- """Holds tests for Atom components."""
+class TestAutomation(EditorTestSuite):
- @pytest.mark.test_case_id("C32078118") # Decal
- @pytest.mark.test_case_id("C32078119") # DepthOfField
- @pytest.mark.test_case_id("C32078120") # Directional Light
- @pytest.mark.test_case_id("C32078121") # Exposure Control
- @pytest.mark.test_case_id("C32078115") # Global Skylight (IBL)
- @pytest.mark.test_case_id("C32078125") # Physical Sky
- @pytest.mark.test_case_id("C32078127") # PostFX Layer
- @pytest.mark.test_case_id("C32078131") # PostFX Radius Weight Modifier
- @pytest.mark.test_case_id("C32078117") # Light
- @pytest.mark.test_case_id("C36525660") # Display Mapper
- def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
- """
- Please review the hydra script run by this test for more specific test info.
- Tests the Atom components & verifies all "expected_lines" appear in Editor.log
- """
- cfg_args = [level]
+ enable_prefab_system = False
- expected_lines = [
- # Decal Component
- "Decal Entity successfully created",
- "Decal_test: Component added to the entity: True",
- "Decal_test: Component removed after UNDO: True",
- "Decal_test: Component added after REDO: True",
- "Decal_test: Entered game mode: True",
- "Decal_test: Exit game mode: True",
- "Decal Controller|Configuration|Material: SUCCESS",
- "Decal_test: Entity is hidden: True",
- "Decal_test: Entity is shown: True",
- "Decal_test: Entity deleted: True",
- "Decal_test: UNDO entity deletion works: True",
- "Decal_test: REDO entity deletion works: True",
- # DepthOfField Component
- "DepthOfField Entity successfully created",
- "DepthOfField_test: Component added to the entity: True",
- "DepthOfField_test: Component removed after UNDO: True",
- "DepthOfField_test: Component added after REDO: True",
- "DepthOfField_test: Entered game mode: True",
- "DepthOfField_test: Exit game mode: True",
- "DepthOfField_test: Entity disabled initially: True",
- "DepthOfField_test: Entity enabled after adding required components: True",
- "DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
- "DepthOfField_test: Entity is hidden: True",
- "DepthOfField_test: Entity is shown: True",
- "DepthOfField_test: Entity deleted: True",
- "DepthOfField_test: UNDO entity deletion works: True",
- "DepthOfField_test: REDO entity deletion works: True",
- # Directional Light Component
- "Directional Light Entity successfully created",
- "Directional Light_test: Component added to the entity: True",
- "Directional Light_test: Component removed after UNDO: True",
- "Directional Light_test: Component added after REDO: True",
- "Directional Light_test: Entered game mode: True",
- "Directional Light_test: Exit game mode: True",
- "Directional Light_test: Entity is hidden: True",
- "Directional Light_test: Entity is shown: True",
- "Directional Light_test: Entity deleted: True",
- "Directional Light_test: UNDO entity deletion works: True",
- "Directional Light_test: REDO entity deletion works: True",
- # Exposure Control Component
- "Exposure Control Entity successfully created",
- "Exposure Control_test: Component added to the entity: True",
- "Exposure Control_test: Component removed after UNDO: True",
- "Exposure Control_test: Component added after REDO: True",
- "Exposure Control_test: Entered game mode: True",
- "Exposure Control_test: Exit game mode: True",
- "Exposure Control_test: Entity disabled initially: True",
- "Exposure Control_test: Entity enabled after adding required components: True",
- "Exposure Control_test: Entity is hidden: True",
- "Exposure Control_test: Entity is shown: True",
- "Exposure Control_test: Entity deleted: True",
- "Exposure Control_test: UNDO entity deletion works: True",
- "Exposure Control_test: REDO entity deletion works: True",
- # Global Skylight (IBL) Component
- "Global Skylight (IBL) Entity successfully created",
- "Global Skylight (IBL)_test: Component added to the entity: True",
- "Global Skylight (IBL)_test: Component removed after UNDO: True",
- "Global Skylight (IBL)_test: Component added after REDO: True",
- "Global Skylight (IBL)_test: Entered game mode: True",
- "Global Skylight (IBL)_test: Exit game mode: True",
- "Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
- "Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
- "Global Skylight (IBL)_test: Entity is hidden: True",
- "Global Skylight (IBL)_test: Entity is shown: True",
- "Global Skylight (IBL)_test: Entity deleted: True",
- "Global Skylight (IBL)_test: UNDO entity deletion works: True",
- "Global Skylight (IBL)_test: REDO entity deletion works: True",
- # Physical Sky Component
- "Physical Sky Entity successfully created",
- "Physical Sky component was added to entity",
- "Entity has a Physical Sky component",
- "Physical Sky_test: Component added to the entity: True",
- "Physical Sky_test: Component removed after UNDO: True",
- "Physical Sky_test: Component added after REDO: True",
- "Physical Sky_test: Entered game mode: True",
- "Physical Sky_test: Exit game mode: True",
- "Physical Sky_test: Entity is hidden: True",
- "Physical Sky_test: Entity is shown: True",
- "Physical Sky_test: Entity deleted: True",
- "Physical Sky_test: UNDO entity deletion works: True",
- "Physical Sky_test: REDO entity deletion works: True",
- # PostFX Layer Component
- "PostFX Layer Entity successfully created",
- "PostFX Layer_test: Component added to the entity: True",
- "PostFX Layer_test: Component removed after UNDO: True",
- "PostFX Layer_test: Component added after REDO: True",
- "PostFX Layer_test: Entered game mode: True",
- "PostFX Layer_test: Exit game mode: True",
- "PostFX Layer_test: Entity is hidden: True",
- "PostFX Layer_test: Entity is shown: True",
- "PostFX Layer_test: Entity deleted: True",
- "PostFX Layer_test: UNDO entity deletion works: True",
- "PostFX Layer_test: REDO entity deletion works: True",
- # PostFX Radius Weight Modifier Component
- "PostFX Radius Weight Modifier Entity successfully created",
- "PostFX Radius Weight Modifier_test: Component added to the entity: True",
- "PostFX Radius Weight Modifier_test: Component removed after UNDO: True",
- "PostFX Radius Weight Modifier_test: Component added after REDO: True",
- "PostFX Radius Weight Modifier_test: Entered game mode: True",
- "PostFX Radius Weight Modifier_test: Exit game mode: True",
- "PostFX Radius Weight Modifier_test: Entity is hidden: True",
- "PostFX Radius Weight Modifier_test: Entity is shown: True",
- "PostFX Radius Weight Modifier_test: Entity deleted: True",
- "PostFX Radius Weight Modifier_test: UNDO entity deletion works: True",
- "PostFX Radius Weight Modifier_test: REDO entity deletion works: True",
- # Light Component
- "Light Entity successfully created",
- "Light_test: Component added to the entity: True",
- "Light_test: Component removed after UNDO: True",
- "Light_test: Component added after REDO: True",
- "Light_test: Entered game mode: True",
- "Light_test: Exit game mode: True",
- "Light_test: Entity is hidden: True",
- "Light_test: Entity is shown: True",
- "Light_test: Entity deleted: True",
- "Light_test: UNDO entity deletion works: True",
- "Light_test: REDO entity deletion works: True",
- # Display Mapper Component
- "Display Mapper Entity successfully created",
- "Display Mapper_test: Component added to the entity: True",
- "Display Mapper_test: Component removed after UNDO: True",
- "Display Mapper_test: Component added after REDO: True",
- "Display Mapper_test: Entered game mode: True",
- "Display Mapper_test: Exit game mode: True",
- "Display Mapper_test: Entity is hidden: True",
- "Display Mapper_test: Entity is shown: True",
- "Display Mapper_test: Entity deleted: True",
- "Display Mapper_test: UNDO entity deletion works: True",
- "Display Mapper_test: REDO entity deletion works: True",
- ]
+ @pytest.mark.test_case_id("C36525657")
+ class AtomEditorComponents_BloomAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_BloomAdded as test_module
- unexpected_lines = [
- "Trace::Assert",
- "Trace::Error",
- "Traceback (most recent call last):",
- ]
+ @pytest.mark.test_case_id("C32078118")
+ class AtomEditorComponents_DecalAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module
- hydra.launch_and_validate_results(
- request,
- TEST_DIRECTORY,
- editor,
- "hydra_AtomEditorComponents_AddedToEntity.py",
- timeout=120,
- expected_lines=expected_lines,
- unexpected_lines=unexpected_lines,
- halt_on_unexpected=True,
- null_renderer=True,
- cfg_args=cfg_args,
- )
+ @pytest.mark.test_case_id("C36525658")
+ class AtomEditorComponents_DeferredFogAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_DeferredFogAdded as test_module
- @pytest.mark.test_case_id("C34525095")
- def test_AtomEditorComponents_LightComponent(
- 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 has the expected property options available to it.
- """
- cfg_args = [level]
+ @pytest.mark.test_case_id("C32078119")
+ class AtomEditorComponents_DepthOfFieldAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module
- expected_lines = [
- "light_entity Entity successfully created",
- "Entity has a Light component",
- "light_entity_test: Component added to the entity: True",
- f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}",
- "Controller|Configuration|Shadows|Enable shadow set to True",
- "light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS",
- "Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF
- "Controller|Configuration|Shadows|Filtering sample count set to 4",
- "Controller|Configuration|Shadows|Filtering sample count set to 64",
- "Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM
- "Controller|Configuration|Shadows|ESM exponent set to 50.0",
- "Controller|Configuration|Shadows|ESM exponent set to 5000.0",
- "Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF
- f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}",
- f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}",
- f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}",
- "light_entity Controller|Configuration|Fast approximation: SUCCESS",
- "light_entity Controller|Configuration|Both directions: SUCCESS",
- f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}",
- f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} "
- f"which matches {LIGHT_TYPES['simple_point']}",
- "Controller|Configuration|Attenuation radius|Mode set to 0",
- "Controller|Configuration|Attenuation radius|Radius set to 100.0",
- f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} "
- f"which matches {LIGHT_TYPES['simple_spot']}",
- "Controller|Configuration|Shutters|Outer angle set to 45.0",
- "Controller|Configuration|Shutters|Outer angle set to 90.0",
- "light_entity_test: Component added to the entity: True",
- "Light component test (non-GPU) completed.",
- ]
+ @pytest.mark.test_case_id("C36525659")
+ class AtomEditorComponents_DiffuseProbeGridAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_DiffuseProbeGridAdded as test_module
- unexpected_lines = [
- "Trace::Assert",
- "Trace::Error",
- "Traceback (most recent call last):",
- ]
+ @pytest.mark.test_case_id("C32078120")
+ class AtomEditorComponents_DirectionalLightAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_DirectionalLightAdded as test_module
- hydra.launch_and_validate_results(
- request,
- TEST_DIRECTORY,
- editor,
- "hydra_AtomEditorComponents_LightComponent.py",
- timeout=120,
- expected_lines=expected_lines,
- unexpected_lines=unexpected_lines,
- halt_on_unexpected=True,
- null_renderer=True,
- cfg_args=cfg_args,
- )
+ @pytest.mark.test_case_id("C36525660")
+ class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
+ @pytest.mark.test_case_id("C36525661")
+ class AtomEditorComponents_EntityReferenceAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_EntityReferenceAdded as test_module
+ @pytest.mark.test_case_id("C32078121")
+ class AtomEditorComponents_ExposureControlAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module
+
+ @pytest.mark.test_case_id("C32078115")
+ class AtomEditorComponents_GlobalSkylightIBLAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module
+
+ @pytest.mark.test_case_id("C32078122")
+ class AtomEditorComponents_GridAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_GridAdded as test_module
+
+ @pytest.mark.test_case_id("C36525671")
+ class AtomEditorComponents_HDRColorGradingAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_HDRColorGradingAdded as test_module
+
+ @pytest.mark.test_case_id("C32078116")
+ class AtomEditorComponents_HDRiSkyboxAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_HDRiSkyboxAdded as test_module
+
+ @pytest.mark.test_case_id("C32078117")
+ class AtomEditorComponents_LightAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_LightAdded as test_module
+
+ @pytest.mark.test_case_id("C36525662")
+ class AtomEditorComponents_LookModificationAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_LookModificationAdded as test_module
+
+ @pytest.mark.test_case_id("C32078123")
+ class AtomEditorComponents_MaterialAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_MaterialAdded as test_module
+
+ @pytest.mark.test_case_id("C32078124")
+ class AtomEditorComponents_MeshAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_MeshAdded as test_module
+
+ @pytest.mark.test_case_id("C36525663")
+ class AtomEditorComponents_OcclusionCullingPlaneAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_OcclusionCullingPlaneAdded as test_module
+
+ @pytest.mark.test_case_id("C32078125")
+ class AtomEditorComponents_PhysicalSkyAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_PhysicalSkyAdded as test_module
+
+ @pytest.mark.test_case_id("C36525664")
+ class AtomEditorComponents_PostFXGradientWeightModifierAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded as test_module
+
+ @pytest.mark.test_case_id("C32078127")
+ class AtomEditorComponents_PostFXLayerAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_PostFXLayerAdded as test_module
+
+ @pytest.mark.test_case_id("C32078131")
+ class AtomEditorComponents_PostFXRadiusWeightModifierAdded(EditorSharedTest):
+ from Atom.tests import (
+ hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded as test_module)
+
+ @pytest.mark.test_case_id("C36525665")
+ class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module
+
+ @pytest.mark.test_case_id("C32078128")
+ class AtomEditorComponents_ReflectionProbeAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_ReflectionProbeAdded as test_module
+
+ @pytest.mark.test_case_id("C36525666")
+ class AtomEditorComponents_SSAOAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponents_SSAOAdded as test_module
+
+ class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
+ from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
index 23fb249761..14d850245c 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU.py
@@ -4,131 +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 ly_test_tools.environment.file_system as file_system
-from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots
-from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator
-
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
-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", ["auto_test"])
-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 = [
- "Trace::Assert",
- "Trace::Error",
- "Traceback (most recent call last):",
- "Screenshot failed"
- ]
+ 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,
- )
-
- for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
- compare_screenshots(test_screenshot, golden_screenshot)
-
- create_screenshots_archive(screenshot_directory)
+ 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",
@@ -136,42 +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 = [
- "Trace::Assert",
- "Trace::Error",
- "Traceback (most recent call last):",
- "Screenshot failed",
- ]
- 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,
- )
+ from Atom.tests import hydra_AtomGPU_SpotLightScreenshotTest as test_module
- for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
- compare_screenshots(test_screenshot, golden_screenshot)
-
- create_screenshots_archive(screenshot_directory)
+ assert compare_screenshot_to_golden_image(screenshot_directory, test_screenshots, golden_images, 0.99) is True
@pytest.mark.parametrize('rhi', ['dx12', 'vulkan'])
@@ -202,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,
@@ -211,6 +145,7 @@ class TestPerformanceBenchmarkSuite(object):
halt_on_unexpected=True,
cfg_args=[level],
null_renderer=False,
+ enable_prefab_system=False,
)
aggregator = BenchmarkDataAggregator(workspace, logger, 'periodic')
@@ -219,7 +154,6 @@ class TestPerformanceBenchmarkSuite(object):
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
-@pytest.mark.system
class TestMaterialEditor(object):
@pytest.mark.parametrize("cfg_args,expected_lines", [
@@ -239,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",
@@ -249,5 +183,6 @@ class TestMaterialEditor(object):
halt_on_unexpected=False,
null_renderer=False,
cfg_args=[cfg_args],
- log_file_name="MaterialEditor.log"
+ log_file_name="MaterialEditor.log",
+ enable_prefab_system=False,
)
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 568768e12e..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_GPU_Optimized.py
+++ /dev/null
@@ -1,44 +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"]
-
- @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/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
deleted file mode 100644
index c29a391be4..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py
+++ /dev/null
@@ -1,79 +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 pytest
-
-from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
-
-
-@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):
-
- @pytest.mark.test_case_id("C32078118")
- class AtomEditorComponents_DecalAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module
-
- @pytest.mark.test_case_id("C32078119")
- class AtomEditorComponents_DepthOfFieldAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module
-
- @pytest.mark.test_case_id("C32078120")
- class AtomEditorComponents_DirectionalLightAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_DirectionalLightAdded as test_module
-
- @pytest.mark.test_case_id("C32078121")
- class AtomEditorComponents_ExposureControlAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module
-
- @pytest.mark.test_case_id("C32078115")
- class AtomEditorComponents_GlobalSkylightIBLAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module
-
- @pytest.mark.test_case_id("C32078125")
- class AtomEditorComponents_PhysicalSkyAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_PhysicalSkyAdded as test_module
-
- @pytest.mark.test_case_id("C32078131")
- class AtomEditorComponents_PostFXRadiusWeightModifierAdded(EditorSharedTest):
- from Atom.tests import (
- hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded as test_module)
-
- @pytest.mark.test_case_id("C32078117")
- class AtomEditorComponents_LightAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_LightAdded as test_module
-
- @pytest.mark.test_case_id("C36525660")
- class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module
-
- @pytest.mark.test_case_id("C32078128")
- class AtomEditorComponents_ReflectionProbeAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_ReflectionProbeAdded as test_module
-
- @pytest.mark.test_case_id("C32078124")
- class AtomEditorComponents_MeshAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_MeshAdded as test_module
-
- @pytest.mark.test_case_id("C32078123")
- class AtomEditorComponents_MaterialAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_MaterialAdded as test_module
-
- @pytest.mark.test_case_id("C32078127")
- class AtomEditorComponents_PostFXLayerAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_PostFXLayerAdded as test_module
-
- @pytest.mark.test_case_id("C36525665")
- class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module
-
- @pytest.mark.test_case_id("C36525664")
- class AtomEditorComponents_PostFXGradientWeightModifierAdded(EditorSharedTest):
- from Atom.tests import hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded as test_module
-
- class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
- from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py
index ad45e51080..f0bb6e72ca 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py
@@ -9,63 +9,86 @@ import os
import pytest
+import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
+from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
+from Atom.atom_utils.atom_constants import LIGHT_TYPES
+
logger = logging.getLogger(__name__)
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
+
class TestAtomEditorComponentsSandbox(object):
# It requires at least one test
def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
pass
- @pytest.mark.parametrize("project", ["AutomatedTesting"])
- @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
- @pytest.mark.parametrize("level", ["auto_test"])
- class TestAtomEditorComponentsMain(object):
- """Holds tests for Atom components."""
- @pytest.mark.test_case_id("C32078128")
- def test_AtomEditorComponents_ReflectionProbeAddedToEntity(
- self, request, editor, level, workspace, project, launcher_platform):
- """
- Please review the hydra script run by this test for more specific test info.
- Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
- 1. Reflection Probe
- """
- cfg_args = [level]
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+@pytest.mark.parametrize("level", ["auto_test"])
+class TestAtomEditorComponentsMain(object):
+ """Holds tests for Atom components."""
- expected_lines = [
- # Reflection Probe Component
- "Reflection Probe Entity successfully created",
- "Reflection Probe_test: Component added to the entity: True",
- "Reflection Probe_test: Component removed after UNDO: True",
- "Reflection Probe_test: Component added after REDO: True",
- "Reflection Probe_test: Entered game mode: True",
- "Reflection Probe_test: Exit game mode: True",
- "Reflection Probe_test: Entity disabled initially: True",
- "Reflection Probe_test: Entity enabled after adding required components: True",
- "Reflection Probe_test: Cubemap is generated: True",
- "Reflection Probe_test: Entity is hidden: True",
- "Reflection Probe_test: Entity is shown: True",
- "Reflection Probe_test: Entity deleted: True",
- "Reflection Probe_test: UNDO entity deletion works: True",
- "Reflection Probe_test: REDO entity deletion works: True",
- ]
+ @pytest.mark.test_case_id("C34525095")
+ def test_AtomEditorComponents_LightComponent(
+ 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 has the expected property options available to it.
+ """
+ cfg_args = [level]
+
+ expected_lines = [
+ "light_entity Entity successfully created",
+ "Entity has a Light component",
+ "light_entity_test: Component added to the entity: True",
+ f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}",
+ "Controller|Configuration|Shadows|Enable shadow set to True",
+ "light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS",
+ "Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF
+ "Controller|Configuration|Shadows|Filtering sample count set to 4",
+ "Controller|Configuration|Shadows|Filtering sample count set to 64",
+ "Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM
+ "Controller|Configuration|Shadows|ESM exponent set to 50.0",
+ "Controller|Configuration|Shadows|ESM exponent set to 5000.0",
+ "Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF
+ f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}",
+ f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}",
+ f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}",
+ "light_entity Controller|Configuration|Fast approximation: SUCCESS",
+ "light_entity Controller|Configuration|Both directions: SUCCESS",
+ f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}",
+ f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} "
+ f"which matches {LIGHT_TYPES['simple_point']}",
+ "Controller|Configuration|Attenuation radius|Mode set to 0",
+ "Controller|Configuration|Attenuation radius|Radius set to 100.0",
+ f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} "
+ f"which matches {LIGHT_TYPES['simple_spot']}",
+ "Controller|Configuration|Shutters|Outer angle set to 45.0",
+ "Controller|Configuration|Shutters|Outer angle set to 90.0",
+ "light_entity_test: Component added to the entity: True",
+ "Light component test (non-GPU) completed.",
+ ]
+
+ unexpected_lines = ["Traceback (most recent call last):"]
+
+ hydra.launch_and_validate_results(
+ request,
+ TEST_DIRECTORY,
+ editor,
+ "hydra_AtomEditorComponents_LightComponent.py",
+ timeout=120,
+ expected_lines=expected_lines,
+ unexpected_lines=unexpected_lines,
+ halt_on_unexpected=True,
+ null_renderer=True,
+ cfg_args=cfg_args,
+ enable_prefab_system=False,
+ )
- hydra.launch_and_validate_results(
- request,
- TEST_DIRECTORY,
- editor,
- "hydra_AtomEditorComponents_AddedToEntity.py",
- timeout=120,
- expected_lines=expected_lines,
- unexpected_lines=[],
- halt_on_unexpected=True,
- null_renderer=True,
- cfg_args=cfg_args,
- )
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
@@ -119,8 +142,6 @@ class TestMaterialEditorBasicTests(object):
"Save All worked as expected: True",
]
unexpected_lines = [
- # "Trace::Assert",
- # "Trace::Error",
"Traceback (most recent call last):"
]
@@ -136,5 +157,20 @@ class TestMaterialEditorBasicTests(object):
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
+ enable_prefab_system=False,
)
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+class TestAutomation(EditorTestSuite):
+
+ enable_prefab_system = False
+
+ @pytest.mark.test_case_id("C36529666")
+ class AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded as test_module
+
+ @pytest.mark.test_case_id("C36525660")
+ class AtomEditorComponentsLevel_DisplayMapperAdded(EditorSharedTest):
+ from Atom.tests import hydra_AtomEditorComponentsLevel_DisplayMapperAdded as test_module
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 a0db95c203..5fdd4c810d 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
@@ -1,5 +1,6 @@
"""
-Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+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
@@ -8,12 +9,19 @@ import datetime
import os
import zipfile
+from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots
+
+
+class ImageComparisonTestFailure(Exception):
+ """Custom test failure for failed image comparisons."""
+ pass
+
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.
+ :return: path to the created .zip file archive.
"""
files_to_archive = []
@@ -27,14 +35,16 @@ def create_screenshots_archive(screenshot_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'screenshots_{formatted_timestamp}.zip')
+ screenshots_zip_file = os.path.join(screenshot_path, f'screenshots_{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:
+ with zipfile.ZipFile(screenshots_zip_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)
+ return screenshots_zip_file
+
def golden_images_directory():
"""
@@ -53,176 +63,195 @@ def golden_images_directory():
return golden_images_dir
-def create_basic_atom_level(level_name):
+def compare_screenshot_similarity(
+ test_screenshot, golden_image, similarity_threshold, create_zip_archive=False, screenshot_directory=""):
"""
- 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 the similarity between a test screenshot and a golden image.
+ It returns a "Screenshots match" string if the comparison mean value is higher than the similarity threshold.
+ Otherwise, it returns an error string.
+ :param test_screenshot: path to the test screenshot to compare.
+ :param golden_image: path to the golden image to compare.
+ :param similarity_threshold: value for the comparison mean value to be asserted against.
+ :param create_zip_archive: toggle to create a zip archive containing the screenshots if the assert check fails.
+ :param screenshot_directory: directory containing screenshots to create zip archive from.
+ :return: Error string if compared mean value < similarity threshold or screenshot_directory is missing for .zip,
+ otherwise it returns a "Screenshots match" string.
+ """
+ result = "Screenshots match"
+ if create_zip_archive and not screenshot_directory:
+ result = 'You must specify a screenshot_directory in order to create a zip archive.\n'
+
+ mean_similarity = compare_screenshots(test_screenshot, golden_image)
+ if not mean_similarity > similarity_threshold:
+ if create_zip_archive:
+ create_screenshots_archive(screenshot_directory)
+ result = (
+ f"When comparing the test_screenshot: '{test_screenshot}' "
+ f"to golden_image: '{golden_image}' the mean similarity of '{mean_similarity}' "
+ f"was lower than the similarity threshold of '{similarity_threshold}'. ")
+
+ return result
+
+
+def compare_screenshot_to_golden_image(
+ screenshot_directory, test_screenshots, golden_images, similarity_threshold=0.99):
+ """
+ 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.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
- import azlmbr.math as math
- import azlmbr.object
- import editor_python_test_tools.hydra_editor_utils as hydra
- from editor_python_test_tools.editor_test_helper import EditorTestHelper
-
- helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
-
- # Create a new level.
- new_level_name = level_name
- heightmap_resolution = 512
- heightmap_meters_per_pixel = 1
- terrain_texture_resolution = 412
- use_terrain = False
-
- # Return codes are ECreateLevelResult defined in CryEdit.h
- return_code = general.create_level_no_prompt(
- new_level_name, heightmap_resolution, heightmap_meters_per_pixel, terrain_texture_resolution, use_terrain)
- if return_code == 1:
- general.log(f"{new_level_name} level already exists")
- elif return_code == 2:
- general.log("Failed to create directory")
- elif return_code == 3:
- general.log("Directory length is too long")
- elif return_code != 0:
- general.log("Unknown error, failed to create level")
- else:
- general.log(f"{new_level_name} level created successfully")
-
- # Enable idle and update viewport.
- 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)
-
- # Delete all existing entities & 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")
- 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)
- 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)
+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.legacy.general as general
- # Work around to add the correct Atom Mesh component
- 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("Models", "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)
+ from editor_python_test_tools.utils import TestHelper
- # 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)
+ from Atom.atom_utils.screenshot_utils import ScreenshotHelper
- # 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)
- 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)
+ 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)
- # Work around to add the correct Atom Mesh component
- sphere_entity.components.append(
- editor.EditorComponentAPIBus(
- bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id]
- ).GetValue()[0]
- )
+
+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.paths
+
+ from editor_python_test_tools.asset_utils import Asset
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
+
+ DEGREE_RADIAN_FACTOR = 0.0174533
+
+ # 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)
+
+ # 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 = 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 = 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)
+ 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 = 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)
- # 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)
+ # 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 4884dbff56..e6d6ac7fb1 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py
@@ -19,6 +19,20 @@ LIGHT_TYPES = {
}
+# 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,
+ 'Medium': 1,
+ 'High': 2,
+}
+
+
class AtomComponentProperties:
"""
Holds Atom component related constants
@@ -42,12 +56,14 @@ class AtomComponentProperties:
Bloom component properties. Requires PostFX Layer component.
- 'requires' a list of component names as strings required by this component.
Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n
+ - 'Enable Bloom' Toggle active state of the component True/False
: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': 'Bloom',
'requires': [AtomComponentProperties.postfx_layer()],
+ 'Enable Bloom': 'Controller|Configuration|Enable Bloom',
}
return properties[property]
@@ -85,12 +101,14 @@ class AtomComponentProperties:
Deferred Fog component properties. Requires PostFX Layer component.
- 'requires' a list of component names as strings required by this component.
Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n
+ - 'Enable Deferred Fog' Toggle active state of the component True/False
: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': 'Deferred Fog',
'requires': [AtomComponentProperties.postfx_layer()],
+ 'Enable Deferred Fog': 'Controller|Configuration|Enable Deferred Fog',
}
return properties[property]
@@ -113,7 +131,22 @@ class AtomComponentProperties:
return properties[property]
@staticmethod
- def diffuse_probe(property: str = 'name') -> str:
+ def diffuse_global_illumination(property: str = 'name') -> str:
+ """
+ Diffuse Global Illumination level component properties.
+ Controls global settings for Diffuse Probe Grid components.
+ - 'Quality Level' from atom_constants.py GLOBAL_ILLUMINATION_QUALITY
+ :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': 'Diffuse Global Illumination',
+ 'Quality Level': 'Controller|Configuration|Quality Level'
+ }
+ return properties[property]
+
+ @staticmethod
+ def diffuse_probe_grid(property: str = 'name') -> str:
"""
Diffuse Probe Grid component properties. Requires one of 'shapes'.
- 'shapes' a list of supported shapes as component names.
@@ -144,12 +177,17 @@ class AtomComponentProperties:
@staticmethod
def display_mapper(property: str = 'name') -> str:
"""
- Display Mapper component properties.
+ Display Mapper level component properties.
+ - 'Enable LDR color grading LUT' toggles the use of LDR color grading LUT
+ - 'LDR color Grading LUT' is the Low Definition Range (LDR) color grading for Look-up Textures (LUT) which is
+ an Asset.id value corresponding to a lighting asset file.
:param property: From the last element of the property tree path. Default 'name' for component name string.
:return: Full property path OR component name if no property specified.
"""
properties = {
'name': 'Display Mapper',
+ 'Enable LDR color grading LUT': 'Controller|Configuration|Enable LDR color grading LUT',
+ 'LDR color Grading LUT': 'Controller|Configuration|LDR color Grading LUT',
}
return properties[property]
@@ -216,12 +254,14 @@ class AtomComponentProperties:
HDR Color Grading component properties. Requires PostFX Layer component.
- 'requires' a list of component names as strings required by this component.
Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n
+ - 'Enable HDR color grading' Toggle active state of the component True/False
: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': 'HDR Color Grading',
'requires': [AtomComponentProperties.postfx_layer()],
+ 'Enable HDR color grading': 'Controller|Configuration|Enable HDR color grading',
}
return properties[property]
@@ -243,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]
@@ -259,12 +313,16 @@ class AtomComponentProperties:
Look Modification component properties. Requires PostFX Layer component.
- 'requires' a list of component names as strings required by this component.
Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n
+ - 'Enable look modification' Toggle active state of the component True/False
+ - 'Color Grading LUT' Asset.id for the LUT used for affecting level look.
: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': 'Look Modification',
'requires': [AtomComponentProperties.postfx_layer()],
+ 'Enable look modification': 'Controller|Configuration|Enable look modification',
+ 'Color Grading LUT': 'Controller|Configuration|Color Grading LUT',
}
return properties[property]
@@ -380,7 +438,7 @@ class AtomComponentProperties:
'name': 'PostFX Shape Weight Modifier',
'requires': [AtomComponentProperties.postfx_layer()],
'shapes': ['Axis Aligned Box Shape', 'Box Shape', 'Capsule Shape', 'Compound Shape', 'Cylinder Shape',
- 'Disk Shape', 'Polygon Prism Shape', 'Quad Shape', 'Sphere Shape', 'Vegetation Reference Shape'],
+ 'Disk Shape', 'Polygon Prism Shape', 'Quad Shape', 'Sphere Shape', 'Shape Reference'],
}
return properties[property]
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded.py
new file mode 100644
index 0000000000..ddcd5c3c46
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DiffuseGlobalIlluminationAdded.py
@@ -0,0 +1,109 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Level component addition success",
+ "UNDO Level component addition failed")
+ creation_redo = (
+ "REDO Level component addition success",
+ "REDO Level component addition failed")
+ diffuse_global_illumination_component = (
+ "Level has a Diffuse Global Illumination component",
+ "Level failed to find Diffuse Global Illumination component")
+ diffuse_global_illumination_quality = (
+ "Quality Level set",
+ "Quality Level could not be set")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+
+
+def AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity():
+ """
+ Summary:
+ Tests the Diffuse Global Illumination level component can be added to the level entity and is stable.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Add Diffuse Global Illumination level component to the level entity.
+ 2) UNDO the level component addition.
+ 3) REDO the level component addition.
+ 4) Set Quality Level property to Low
+ 5) Enter/Exit game mode.
+ 6) Look for errors and asserts.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.editor_entity_utils import EditorLevelEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties, GLOBAL_ILLUMINATION_QUALITY
+
+ 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")
+
+ # Test steps begin.
+ # 1. Add Diffuse Global Illumination level component to the level entity.
+ diffuse_global_illumination_component = EditorLevelEntity.add_component(
+ AtomComponentProperties.diffuse_global_illumination())
+ Report.critical_result(
+ Tests.diffuse_global_illumination_component,
+ EditorLevelEntity.has_component(AtomComponentProperties.diffuse_global_illumination()))
+
+ # 2. UNDO the level component addition.
+ # -> UNDO component addition.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo,
+ not EditorLevelEntity.has_component(AtomComponentProperties.diffuse_global_illumination()))
+
+ # 3. REDO the level component addition.
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo,
+ EditorLevelEntity.has_component(AtomComponentProperties.diffuse_global_illumination()))
+
+ # 4. Set Quality Level property to Low
+ diffuse_global_illumination_component.set_component_property_value(
+ AtomComponentProperties.diffuse_global_illumination('Quality Level', GLOBAL_ILLUMINATION_QUALITY['Low']))
+ quality = diffuse_global_illumination_component.get_component_property_value(
+ AtomComponentProperties.diffuse_global_illumination('Quality Level'))
+ Report.result(diffuse_global_illumination_quality, quality == GLOBAL_ILLUMINATION_QUALITY['Low'])
+
+ # 5. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 6. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponentsLevel_DiffuseGlobalIllumination_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DisplayMapperAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DisplayMapperAdded.py
new file mode 100644
index 0000000000..c050dd76d4
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponentsLevel_DisplayMapperAdded.py
@@ -0,0 +1,124 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+
+class Tests:
+ creation_undo = (
+ "UNDO level component addition success",
+ "UNDO level component addition failed")
+ creation_redo = (
+ "REDO Level component addition success",
+ "REDO Level component addition failed")
+ display_mapper_component = (
+ "Level has a Display Mapper component",
+ "Level failed to find Display Mapper component")
+ ldr_color_grading_lut = (
+ "LDR color Grading LUT asset set",
+ "LDR color Grading LUT asset could not be set")
+ enable_ldr_color_grading_lut = (
+ "Enable LDR color grading LUT set",
+ "Enable LDR color grading LUT could not be set")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+
+
+def AtomEditorComponentsLevel_DisplayMapper_AddedToEntity():
+ """
+ Summary:
+ Tests the Display Mapper level component can be added to the level entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Add Display Mapper level component to the level entity.
+ 2) UNDO the level component addition.
+ 3) REDO the level component addition.
+ 4) Set LDR color Grading LUT asset.
+ 5) Set Enable LDR color grading LUT property True
+ 6) Enter/Exit game mode.
+ 7) Look for errors and asserts.
+
+ :return: None
+ """
+ import os
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.asset_utils import Asset
+ from editor_python_test_tools.editor_entity_utils import EditorLevelEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
+
+ 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")
+
+ # Test steps begin.
+ # 1. Add Display Mapper level component to the level entity.
+ display_mapper_component = EditorLevelEntity.add_component(AtomComponentProperties.display_mapper())
+ Report.critical_result(
+ Tests.display_mapper_component,
+ EditorLevelEntity.has_component(AtomComponentProperties.display_mapper()))
+
+ # 2. UNDO the level component addition.
+ # -> UNDO component addition.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not EditorLevelEntity.has_component(AtomComponentProperties.display_mapper()))
+
+ # 3. REDO the level component addition.
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, EditorLevelEntity.has_component(AtomComponentProperties.display_mapper()))
+
+ # 4. Set LDR color Grading LUT asset.
+ display_mapper_asset_path = os.path.join("TestData", "test.lightingpreset.azasset")
+ display_mapper_asset = Asset.find_asset_by_path(display_mapper_asset_path, False)
+ display_mapper_component.set_component_property_value(
+ AtomComponentProperties.display_mapper('LDR color Grading LUT'), display_mapper_asset.id)
+ Report.result(
+ Tests.ldr_color_grading_lut,
+ display_mapper_component.get_component_property_value(
+ AtomComponentProperties.display_mapper('LDR color Grading LUT')) == display_mapper_asset.id)
+
+ # 5. Set Enable LDR color grading LUT property True
+ display_mapper_component.set_component_property_value(
+ AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True)
+ Report.result(
+ Test.enable_ldr_color_grading_lut,
+ display_mapper_component.get_component_property_value(
+ AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True)
+
+ # 6. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 7. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponentsLevel_DisplayMapper_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py
deleted file mode 100644
index bbc8463152..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py
+++ /dev/null
@@ -1,238 +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.math as math
-import azlmbr.bus as bus
-import azlmbr.paths
-import azlmbr.asset as asset
-import azlmbr.entity as entity
-import azlmbr.legacy.general as general
-import azlmbr.editor as editor
-import azlmbr.render as render
-
-sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
-
-import editor_python_test_tools.hydra_editor_utils as hydra
-from editor_python_test_tools.utils import TestHelper
-
-
-def run():
- """
- Summary:
- The below common tests are done for each of the components.
- 1) Addition of component to the entity
- 2) UNDO/REDO of addition of component
- 3) Enter/Exit game mode
- 4) Hide/Show entity containing component
- 5) Deletion of component
- 6) UNDO/REDO of deletion of component
- Some additional tests for specific components include
- 1) Assigning value to some properties of each component
- 2) Verifying if the component is activated only when the required components are added
-
- Expected Result:
- 1) Component can be added to an entity.
- 2) The addition of component can be undone and redone.
- 3) Game mode can be entered/exited without issue.
- 4) Entity with component can be hidden/shown.
- 5) Component can be deleted.
- 6) The deletion of component can be undone and redone.
- 7) Component is activated only when the required components are added
- 8) Values can be assigned to the properties of the component
-
- :return: None
- """
-
- def create_entity_undo_redo_component_addition(component_name):
- new_entity = hydra.Entity(f"{component_name}")
- new_entity.create_entity(math.Vector3(512.0, 512.0, 34.0), [component_name])
- general.log(f"{component_name}_test: Component added to the entity: "
- f"{hydra.has_components(new_entity.id, [component_name])}")
-
- # undo component addition
- general.undo()
- TestHelper.wait_for_condition(lambda: not hydra.has_components(new_entity.id, [component_name]), 2.0)
- general.log(f"{component_name}_test: Component removed after UNDO: "
- f"{not hydra.has_components(new_entity.id, [component_name])}")
-
- # redo component addition
- general.redo()
- TestHelper.wait_for_condition(lambda: hydra.has_components(new_entity.id, [component_name]), 2.0)
- general.log(f"{component_name}_test: Component added after REDO: "
- f"{hydra.has_components(new_entity.id, [component_name])}")
-
- return new_entity
-
- def verify_enter_exit_game_mode(component_name):
- general.enter_game_mode()
- TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0)
- general.log(f"{component_name}_test: Entered game mode: {general.is_in_game_mode()}")
- general.exit_game_mode()
- TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 2.0)
- general.log(f"{component_name}_test: Exit game mode: {not general.is_in_game_mode()}")
-
- def verify_hide_unhide_entity(component_name, entity_obj):
-
- def is_entity_hidden(entity_id):
- return editor.EditorEntityInfoRequestBus(bus.Event, "IsHidden", entity_id)
-
- editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", entity_obj.id, False)
- general.idle_wait_frames(1)
- general.log(f"{component_name}_test: Entity is hidden: {is_entity_hidden(entity_obj.id)}")
- editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", entity_obj.id, True)
- general.idle_wait_frames(1)
- general.log(f"{component_name}_test: Entity is shown: {not is_entity_hidden(entity_obj.id)}")
-
- def verify_deletion_undo_redo(component_name, entity_obj):
- editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", entity_obj.id)
- TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 2.0)
- general.log(f"{component_name}_test: Entity deleted: {not hydra.find_entity_by_name(entity_obj.name)}")
-
- general.undo()
- TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 2.0)
- general.log(f"{component_name}_test: UNDO entity deletion works: "
- f"{hydra.find_entity_by_name(entity_obj.name) is not None}")
-
- general.redo()
- TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 2.0)
- general.log(f"{component_name}_test: REDO entity deletion works: "
- f"{not hydra.find_entity_by_name(entity_obj.name)}")
-
- def verify_required_component_addition(entity_obj, components_to_add, component_name):
-
- def is_component_enabled(entity_componentid_pair):
- return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", entity_componentid_pair)
-
- general.log(
- f"{component_name}_test: Entity disabled initially: "
- f"{not is_component_enabled(entity_obj.components[0])}")
- for component in components_to_add:
- entity_obj.add_component(component)
- TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 2.0)
- general.log(
- f"{component_name}_test: Entity enabled after adding "
- f"required components: {is_component_enabled(entity_obj.components[0])}"
- )
-
- def verify_set_property(entity_obj, path, value):
- entity_obj.get_set_test(0, path, value)
-
- # Verify cubemap generation
- def verify_cubemap_generation(component_name, entity_obj):
- # Initially Check if the component has Reflection Probe component
- if not hydra.has_components(entity_obj.id, ["Reflection Probe"]):
- raise ValueError(f"Given entity {entity_obj.name} has no Reflection Probe component")
- render.EditorReflectionProbeBus(azlmbr.bus.Event, "BakeReflectionProbe", entity_obj.id)
-
- def get_value():
- hydra.get_component_property_value(entity_obj.components[0], "Cubemap|Baked Cubemap Path")
-
- TestHelper.wait_for_condition(lambda: get_value() != "", 20.0)
- general.log(f"{component_name}_test: Cubemap is generated: {get_value() != ''}")
-
- # Wait for Editor idle loop before executing Python hydra scripts.
- TestHelper.init_idle()
-
- # Delete all existing entities initially
- search_filter = azlmbr.entity.SearchFilter()
- all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
- editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
-
- class ComponentTests:
- """Test launcher for each component."""
- def __init__(self, component_name, *additional_tests):
- self.component_name = component_name
- self.additional_tests = additional_tests
- self.run_component_tests()
-
- def run_component_tests(self):
- # Run common and additional tests
- entity_obj = create_entity_undo_redo_component_addition(self.component_name)
-
- # Enter/Exit game mode test
- verify_enter_exit_game_mode(self.component_name)
-
- # Any additional tests are executed here
- for test in self.additional_tests:
- test(entity_obj)
-
- # Hide/Unhide entity test
- verify_hide_unhide_entity(self.component_name, entity_obj)
-
- # Deletion/Undo/Redo test
- verify_deletion_undo_redo(self.component_name, entity_obj)
-
- # DepthOfField Component
- camera_entity = hydra.Entity("camera_entity")
- camera_entity.create_entity(math.Vector3(512.0, 512.0, 34.0), ["Camera"])
- depth_of_field = "DepthOfField"
- ComponentTests(
- depth_of_field,
- lambda entity_obj: verify_required_component_addition(entity_obj, ["PostFX Layer"], depth_of_field),
- lambda entity_obj: verify_set_property(
- entity_obj, "Controller|Configuration|Camera Entity", camera_entity.id))
-
- # Decal Component
- material_asset_path = os.path.join("AutomatedTesting", "Materials", "basic_grey.material")
- material_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False)
- ComponentTests(
- "Decal", lambda entity_obj: verify_set_property(
- entity_obj, "Controller|Configuration|Material", material_asset))
-
- # Directional Light Component
- ComponentTests(
- "Directional Light",
- lambda entity_obj: verify_set_property(
- entity_obj, "Controller|Configuration|Shadow|Camera", camera_entity.id))
-
- # Exposure Control Component
- ComponentTests(
- "Exposure Control", lambda entity_obj: verify_required_component_addition(
- entity_obj, ["PostFX Layer"], "Exposure Control"))
-
- # Global Skylight (IBL) Component
- diffuse_image_path = os.path.join("LightingPresets", "greenwich_park_02_4k_iblskyboxcm.exr.streamingimage")
- diffuse_image_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", diffuse_image_path, math.Uuid(), False)
- specular_image_path = os.path.join("LightingPresets", "greenwich_park_02_4k_iblskyboxcm.exr.streamingimage")
- specular_image_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", specular_image_path, math.Uuid(), False)
- ComponentTests(
- "Global Skylight (IBL)",
- lambda entity_obj: verify_set_property(
- entity_obj, "Controller|Configuration|Diffuse Image", diffuse_image_asset),
- lambda entity_obj: verify_set_property(
- entity_obj, "Controller|Configuration|Specular Image", specular_image_asset))
-
- # Physical Sky Component
- ComponentTests("Physical Sky")
-
- # PostFX Layer Component
- ComponentTests("PostFX Layer")
-
- # PostFX Radius Weight Modifier Component
- ComponentTests("PostFX Radius Weight Modifier")
-
- # Light Component
- ComponentTests("Light")
-
- # Display Mapper Component
- ComponentTests("Display Mapper")
-
- # Reflection Probe Component
- reflection_probe = "Reflection Probe"
- ComponentTests(
- reflection_probe,
- lambda entity_obj: verify_required_component_addition(entity_obj, ["Box Shape"], reflection_probe),
- lambda entity_obj: verify_cubemap_generation(reflection_probe, entity_obj),)
-
-if __name__ == "__main__":
- run()
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py
new file mode 100644
index 0000000000..56b22eb20d
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py
@@ -0,0 +1,189 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ bloom_creation = (
+ "Bloom Entity successfully created",
+ "Bloom Entity failed to be created")
+ bloom_component = (
+ "Entity has a Bloom component",
+ "Entity failed to find Bloom component")
+ bloom_disabled = (
+ "Bloom component disabled",
+ "Bloom component was not disabled")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ bloom_enabled = (
+ "Bloom component enabled",
+ "Bloom component was not enabled")
+ enable_bloom_parameter_enabled = (
+ "Enable Bloom parameter enabled",
+ "Enable Bloom parameter was not enabled")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_Bloom_AddedToEntity():
+ """
+ Summary:
+ Tests the Bloom component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create an Bloom entity with no components.
+ 2) Add Bloom component to Bloom entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify Bloom component not enabled.
+ 6) Add PostFX Layer component since it is required by the Bloom component.
+ 7) Verify Bloom component is enabled.
+ 8) Enable the "Enable Bloom" parameter.
+ 9) Enter/Exit game mode.
+ 10) Test IsHidden.
+ 11) Test IsVisible.
+ 12) Delete Bloom entity.
+ 13) UNDO deletion.
+ 14) REDO deletion.
+ 15) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create an Bloom entity with no components.
+ bloom_entity = EditorEntity.create_editor_entity(AtomComponentProperties.bloom())
+ Report.critical_result(Tests.bloom_creation, bloom_entity.exists())
+
+ # 2. Add Bloom component to Bloom entity.
+ bloom_component = bloom_entity.add_component(AtomComponentProperties.bloom())
+ Report.critical_result(Tests.bloom_component, bloom_entity.has_component(AtomComponentProperties.bloom()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not bloom_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, bloom_entity.exists())
+
+ # 5. Verify Bloom component not enabled.
+ Report.result(Tests.bloom_disabled, not bloom_component.is_enabled())
+
+ # 6. Add PostFX Layer component since it is required by the Bloom component.
+ bloom_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ bloom_entity.has_component(AtomComponentProperties.postfx_layer()))
+
+ # 7. Verify Bloom component is enabled.
+ Report.result(Tests.bloom_enabled, bloom_component.is_enabled())
+
+ # 8. Enable the "Enable Bloom" parameter.
+ bloom_component.set_component_property_value(AtomComponentProperties.bloom('Enable Bloom'), True)
+ Report.result(
+ Tests.enable_bloom_parameter_enabled,
+ bloom_component.get_component_property_value(AtomComponentProperties.bloom('Enable Bloom')) is True)
+
+ # 9. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 10. Test IsHidden.
+ bloom_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, bloom_entity.is_hidden() is True)
+
+ # 11. Test IsVisible.
+ bloom_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, bloom_entity.is_visible() is True)
+
+ # 12. Delete Bloom entity.
+ bloom_entity.delete()
+ Report.result(Tests.entity_deleted, not bloom_entity.exists())
+
+ # 13. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, bloom_entity.exists())
+
+ # 14. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not bloom_entity.exists())
+
+ # 15. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_Bloom_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py
index fa02b75fe2..e840cf3cf1 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DecalAdded.py
@@ -5,25 +5,52 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- decal_creation = ("Decal Entity successfully created", "Decal Entity failed to be created")
- decal_component = ("Entity has a Decal component", "Entity failed to find Decal component")
- material_property_set = ("Material property set on Decal component", "Couldn't set Material property on Decal component")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ camera_creation = (
+ "Camera Entity successfully created",
+ "Camera Entity failed to be created")
+ camera_component_added = (
+ "Camera component was added to entity",
+ "Camera component failed to be added to entity")
+ camera_component_check = (
+ "Entity has a Camera component",
+ "Entity failed to find Camera component")
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ decal_creation = (
+ "Decal Entity successfully created",
+ "Decal Entity failed to be created")
+ decal_component = (
+ "Entity has a Decal component",
+ "Entity failed to find Decal component")
+ material_property_set = (
+ "Material property set on Decal component",
+ "Couldn't set Material property on Decal component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_Decal_AddedToEntity():
@@ -51,35 +78,33 @@ def AtomEditorComponents_Decal_AddedToEntity():
9) Delete Decal entity.
10) UNDO deletion.
11) REDO deletion.
- 12) Look for errors.
+ 12) Look for errors and asserts.
:return: None
"""
import os
- import azlmbr.asset as asset
- import azlmbr.bus as bus
import azlmbr.legacy.general as general
- import azlmbr.math as math
+ 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 as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Decal entity with no components.
- decal_name = "Decal"
- decal_entity = EditorEntity.create_editor_entity_at(math.Vector3(512.0, 512.0, 34.0), decal_name)
+ decal_entity = EditorEntity.create_editor_entity(AtomComponentProperties.decal())
Report.critical_result(Tests.decal_creation, decal_entity.exists())
# 2. Add Decal component to Decal entity.
- decal_component = decal_entity.add_component(decal_name)
- Report.critical_result(Tests.decal_component, decal_entity.has_component(decal_name))
+ decal_component = decal_entity.add_component(AtomComponentProperties.decal())
+ Report.critical_result(Tests.decal_component, decal_entity.has_component(AtomComponentProperties.decal()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -106,9 +131,9 @@ def AtomEditorComponents_Decal_AddedToEntity():
Report.result(Tests.creation_redo, decal_entity.exists())
# 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden.
decal_entity.set_visibility_state(False)
@@ -120,13 +145,11 @@ def AtomEditorComponents_Decal_AddedToEntity():
Report.result(Tests.is_visible, decal_entity.is_visible() is True)
# 8. Set Material property on Decal component.
- decal_material_property_path = "Controller|Configuration|Material"
- decal_material_asset_path = os.path.join("AutomatedTesting", "Materials", "basic_grey.material")
- decal_material_asset = asset.AssetCatalogRequestBus(
- bus.Broadcast, "GetAssetIdByPath", decal_material_asset_path, math.Uuid(), False)
- decal_component.set_component_property_value(decal_material_property_path, decal_material_asset)
- get_material_property = decal_component.get_component_property_value(decal_material_property_path)
- Report.result(Tests.material_property_set, get_material_property == decal_material_asset)
+ decal_material_asset_path = os.path.join("materials", "basic_grey.azmaterial")
+ decal_material_asset = Asset.find_asset_by_path(decal_material_asset_path, False)
+ decal_component.set_component_property_value(AtomComponentProperties.decal('Material'), decal_material_asset.id)
+ get_material_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Material'))
+ Report.result(Tests.material_property_set, get_material_property == decal_material_asset.id)
# 9. Delete Decal entity.
decal_entity.delete()
@@ -141,9 +164,12 @@ def AtomEditorComponents_Decal_AddedToEntity():
general.redo()
Report.result(Tests.deletion_redo, not decal_entity.exists())
- # 12. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 12. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py
new file mode 100644
index 0000000000..71163ece94
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py
@@ -0,0 +1,193 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ deferred_fog_creation = (
+ "Deferred Fog Entity successfully created",
+ "Deferred Fog Entity failed to be created")
+ deferred_fog_component = (
+ "Entity has a Deferred Fog component",
+ "Entity failed to find Deferred Fog component")
+ deferred_fog_disabled = (
+ "Deferred Fog component disabled",
+ "Deferred Fog component was not disabled")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ deferred_fog_enabled = (
+ "Deferred Fog component enabled",
+ "Deferred Fog component was not enabled")
+ enable_deferred_fog_parameter_enabled = (
+ "Enable Deferred Fog parameter enabled",
+ "Enable Deferred Fog parameter was not enabled")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_DeferredFog_AddedToEntity():
+ """
+ Summary:
+ Tests the Deferred Fog component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create an Deferred Fog entity with no components.
+ 2) Add Deferred Fog component to Deferred Fog entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify Deferred Fog component not enabled.
+ 6) Add PostFX Layer component since it is required by the Deferred Fog component.
+ 7) Verify Deferred Fog component is enabled.
+ 8) Enable the "Enable Deferred Fog" parameter.
+ 9) Enter/Exit game mode.
+ 10) Test IsHidden.
+ 11) Test IsVisible.
+ 12) Delete Deferred Fog entity.
+ 13) UNDO deletion.
+ 14) REDO deletion.
+ 15) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create an Deferred Fog entity with no components.
+ deferred_fog_entity = EditorEntity.create_editor_entity(AtomComponentProperties.deferred_fog())
+ Report.critical_result(Tests.deferred_fog_creation, deferred_fog_entity.exists())
+
+ # 2. Add Deferred Fog component to Deferred Fog entity.
+ deferred_fog_component = deferred_fog_entity.add_component(
+ AtomComponentProperties.deferred_fog())
+ Report.critical_result(
+ Tests.deferred_fog_component,
+ deferred_fog_entity.has_component(AtomComponentProperties.deferred_fog()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not deferred_fog_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, deferred_fog_entity.exists())
+
+ # 5. Verify Deferred Fog component not enabled.
+ Report.result(Tests.deferred_fog_disabled, not deferred_fog_component.is_enabled())
+
+ # 6. Add PostFX Layer component since it is required by the Deferred Fog component.
+ deferred_fog_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ deferred_fog_entity.has_component(AtomComponentProperties.postfx_layer()))
+
+ # 7. Verify Deferred Fog component is enabled.
+ Report.result(Tests.deferred_fog_enabled, deferred_fog_component.is_enabled())
+
+ # 8. Enable the "Enable Deferred Fog" parameter.
+ deferred_fog_component.set_component_property_value(
+ AtomComponentProperties.deferred_fog('Enable Deferred Fog'), True)
+ Report.result(Tests.enable_deferred_fog_parameter_enabled,
+ deferred_fog_component.get_component_property_value(
+ AtomComponentProperties.deferred_fog('Enable Deferred Fog')) is True)
+
+ # 9. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 10. Test IsHidden.
+ deferred_fog_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, deferred_fog_entity.is_hidden() is True)
+
+ # 11. Test IsVisible.
+ deferred_fog_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, deferred_fog_entity.is_visible() is True)
+
+ # 12. Delete Deferred Fog entity.
+ deferred_fog_entity.delete()
+ Report.result(Tests.entity_deleted, not deferred_fog_entity.exists())
+
+ # 13. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, deferred_fog_entity.exists())
+
+ # 14. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not deferred_fog_entity.exists())
+
+ # 15. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_DeferredFog_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py
index 80284902ea..e2c5f9c77d 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DepthOfFieldAdded.py
@@ -5,28 +5,61 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to Camera entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- camera_property_set = ("DepthOfField Entity set Camera Entity", "DepthOfField Entity could not set Camera Entity")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- depth_of_field_creation = ("DepthOfField Entity successfully created", "DepthOfField Entity failed to be created")
- depth_of_field_component = ("Entity has a DepthOfField component", "Entity failed to find DepthOfField component")
- depth_of_field_disabled = ("DepthOfField component disabled", "DepthOfField component was not disabled.")
- post_fx_component = ("Entity has a Post FX Layer component", "Entity did not have a Post FX Layer component")
- depth_of_field_enabled = ("DepthOfField component enabled", "DepthOfField component was not enabled.")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ camera_creation = (
+ "Camera Entity successfully created",
+ "Camera Entity failed to be created")
+ camera_component_added = (
+ "Camera component was added to Camera entity",
+ "Camera component failed to be added to entity")
+ camera_component_check = (
+ "Entity has a Camera component",
+ "Entity failed to find Camera component")
+ camera_property_set = (
+ "DepthOfField Entity set Camera Entity",
+ "DepthOfField Entity could not set Camera Entity")
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ depth_of_field_creation = (
+ "DepthOfField Entity successfully created",
+ "DepthOfField Entity failed to be created")
+ depth_of_field_component = (
+ "Entity has a DepthOfField component",
+ "Entity failed to find DepthOfField component")
+ depth_of_field_disabled = (
+ "DepthOfField component disabled",
+ "DepthOfField component was not disabled.")
+ post_fx_component = (
+ "Entity has a Post FX Layer component",
+ "Entity did not have a Post FX Layer component")
+ depth_of_field_enabled = (
+ "DepthOfField component enabled",
+ "DepthOfField component was not enabled.")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_DepthOfField_AddedToEntity():
@@ -59,33 +92,32 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
14) Delete DepthOfField entity.
15) UNDO deletion.
16) REDO deletion.
- 17) Look for errors.
+ 17) Look for errors and asserts.
:return: None
"""
import azlmbr.legacy.general as general
- import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity
- from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a DepthOfField entity with no components.
- depth_of_field_name = "DepthOfField"
- depth_of_field_entity = EditorEntity.create_editor_entity_at(
- math.Vector3(512.0, 512.0, 34.0), depth_of_field_name)
+ depth_of_field_entity = EditorEntity.create_editor_entity(AtomComponentProperties.depth_of_field())
Report.critical_result(Tests.depth_of_field_creation, depth_of_field_entity.exists())
# 2. Add a DepthOfField component to DepthOfField entity.
- depth_of_field_component = depth_of_field_entity.add_component(depth_of_field_name)
- Report.critical_result(Tests.depth_of_field_component, depth_of_field_entity.has_component(depth_of_field_name))
+ depth_of_field_component = depth_of_field_entity.add_component(AtomComponentProperties.depth_of_field())
+ Report.critical_result(Tests.depth_of_field_component,
+ depth_of_field_entity.has_component(AtomComponentProperties.depth_of_field()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -115,17 +147,16 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
Report.result(Tests.depth_of_field_disabled, not depth_of_field_component.is_enabled())
# 6. Add Post FX Layer component since it is required by the DepthOfField component.
- post_fx_layer = "PostFX Layer"
- depth_of_field_entity.add_component(post_fx_layer)
- Report.result(Tests.post_fx_component, depth_of_field_entity.has_component(post_fx_layer))
+ depth_of_field_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(Tests.post_fx_component, depth_of_field_entity.has_component(AtomComponentProperties.postfx_layer()))
# 7. Verify DepthOfField component is enabled.
Report.result(Tests.depth_of_field_enabled, depth_of_field_component.is_enabled())
# 8. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
# 9. Test IsHidden.
depth_of_field_entity.set_visibility_state(False)
@@ -137,19 +168,20 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
Report.result(Tests.is_visible, depth_of_field_entity.is_visible() is True)
# 11. Add Camera entity.
- camera_name = "Camera"
- camera_entity = EditorEntity.create_editor_entity_at(math.Vector3(512.0, 512.0, 34.0), camera_name)
+ camera_entity = EditorEntity.create_editor_entity(AtomComponentProperties.camera())
Report.result(Tests.camera_creation, camera_entity.exists())
# 12. Add Camera component to Camera entity.
- camera_entity.add_component(camera_name)
- Report.result(Tests.camera_component_added, camera_entity.has_component(camera_name))
+ camera_entity.add_component(AtomComponentProperties.camera())
+ Report.result(Tests.camera_component_added, camera_entity.has_component(AtomComponentProperties.camera()))
# 13. Set the DepthOfField components's Camera Entity to the newly created Camera entity.
- depth_of_field_camera_property_path = "Controller|Configuration|Camera Entity"
- depth_of_field_component.set_component_property_value(depth_of_field_camera_property_path, camera_entity.id)
- camera_entity_set = depth_of_field_component.get_component_property_value(depth_of_field_camera_property_path)
- Report.result(Tests.camera_property_set, camera_entity.id == camera_entity_set)
+ depth_of_field_component.set_component_property_value(
+ AtomComponentProperties.depth_of_field('Camera Entity'), camera_entity.id)
+ Report.result(
+ Tests.camera_property_set,
+ camera_entity.id == depth_of_field_component.get_component_property_value(
+ AtomComponentProperties.depth_of_field('Camera Entity')))
# 14. Delete DepthOfField entity.
depth_of_field_entity.delete()
@@ -163,9 +195,12 @@ def AtomEditorComponents_DepthOfField_AddedToEntity():
general.redo()
Report.result(Tests.deletion_redo, not depth_of_field_entity.exists())
- # 17. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 17. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DiffuseProbeGridAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DiffuseProbeGridAdded.py
new file mode 100644
index 0000000000..f42c091057
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DiffuseProbeGridAdded.py
@@ -0,0 +1,187 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ diffuse_probe_grid_creation = (
+ "Diffuse Probe Grid Entity successfully created",
+ "Diffuse Probe Grid Entity failed to be created")
+ diffuse_probe_grid_component = (
+ "Entity has a Diffuse Probe Grid component",
+ "Entity failed to find Diffuse Probe Grid component")
+ diffuse_probe_grid_disabled = (
+ "Diffuse Probe Grid component disabled",
+ "Diffuse Probe Grid component was not disabled")
+ diffuse_probe_grid_enabled = (
+ "Diffuse Probe Grid component enabled",
+ "Diffuse Probe Grid component was not enabled")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_DiffuseProbeGrid_AddedToEntity():
+ """
+ Summary:
+ Tests the Diffuse Probe Grid component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create a Diffuse Probe Grid entity with no components.
+ 2) Add a Diffuse Probe Grid component to Diffuse Probe Grid entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify Diffuse Probe Grid component not enabled.
+ 6) Add Shape component since it is required by the Diffuse Probe Grid component.
+ 7) Verify Diffuse Probe Grid component is enabled.
+ 8) Enter/Exit game mode.
+ 9) Test IsHidden.
+ 10) Test IsVisible.
+ 11) Delete Diffuse Probe Grid entity.
+ 12) UNDO deletion.
+ 13) REDO deletion.
+ 14) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create a Diffuse Probe Grid entity with no components.
+ diffuse_probe_grid_entity = EditorEntity.create_editor_entity(AtomComponentProperties.diffuse_probe_grid())
+ Report.critical_result(Tests.diffuse_probe_grid_creation, diffuse_probe_grid_entity.exists())
+
+ # 2. Add a Diffuse Probe Grid component to Diffuse Probe Grid entity.
+ diffuse_probe_grid_component = diffuse_probe_grid_entity.add_component(
+ AtomComponentProperties.diffuse_probe_grid())
+ Report.critical_result(
+ Tests.diffuse_probe_grid_component,
+ diffuse_probe_grid_entity.has_component(AtomComponentProperties.diffuse_probe_grid()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not diffuse_probe_grid_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, diffuse_probe_grid_entity.exists())
+
+ # 5. Verify Diffuse Probe Grid component not enabled.
+ Report.result(Tests.diffuse_probe_grid_disabled, not diffuse_probe_grid_component.is_enabled())
+
+ # 6. Add Shape component since it is required by the Diffuse Probe Grid component.
+ for shape in AtomComponentProperties.diffuse_probe_grid('shapes'):
+ diffuse_probe_grid_entity.add_component(shape)
+ test_shape = (
+ f"Entity has a {shape} component",
+ f"Entity did not have a {shape} component")
+ Report.result(test_shape, diffuse_probe_grid_entity.has_component(shape))
+
+ # 7. Check if required shape allows Diffuse Probe Grid to be enabled
+ Report.result(Tests.diffuse_probe_grid_enabled, diffuse_probe_grid_component.is_enabled())
+
+ # Undo to remove each added shape except the last one and verify Diffuse Probe Grid is not enabled.
+ if not (shape == AtomComponentProperties.diffuse_probe_grid('shapes')[-1]):
+ general.undo()
+ TestHelper.wait_for_condition(lambda: not diffuse_probe_grid_entity.has_component(shape), 1.0)
+ Report.result(Tests.diffuse_probe_grid_disabled, not diffuse_probe_grid_component.is_enabled())
+
+ # 8. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 9. Test IsHidden.
+ diffuse_probe_grid_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, diffuse_probe_grid_entity.is_hidden() is True)
+
+ # 10. Test IsVisible.
+ diffuse_probe_grid_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, diffuse_probe_grid_entity.is_visible() is True)
+
+ # 11. Delete Diffuse Probe Grid entity.
+ diffuse_probe_grid_entity.delete()
+ Report.result(Tests.entity_deleted, not diffuse_probe_grid_entity.exists())
+
+ # 12. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, diffuse_probe_grid_entity.exists())
+
+ # 13. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not diffuse_probe_grid_entity.exists())
+
+ # 14. Look for errors or asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_DiffuseProbeGrid_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py
index 048e132df4..f3ffc0f366 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DirectionalLightAdded.py
@@ -5,25 +5,52 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- directional_light_creation = ("Directional Light Entity successfully created", "Directional Light Entity failed to be created")
- directional_light_component = ("Entity has a Directional Light component", "Entity failed to find Directional Light component")
- shadow_camera_check = ("Directional Light component Shadow camera set", "Directional Light component Shadow camera was not set")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ camera_creation = (
+ "Camera Entity successfully created",
+ "Camera Entity failed to be created")
+ camera_component_added = (
+ "Camera component was added to entity",
+ "Camera component failed to be added to entity")
+ camera_component_check = (
+ "Entity has a Camera component",
+ "Entity failed to find Camera component")
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ directional_light_creation = (
+ "Directional Light Entity successfully created",
+ "Directional Light Entity failed to be created")
+ directional_light_component = (
+ "Entity has a Directional Light component",
+ "Entity failed to find Directional Light component")
+ shadow_camera_check = (
+ "Directional Light component Shadow camera set",
+ "Directional Light component Shadow camera was not set")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_DirectionalLight_AddedToEntity():
@@ -53,34 +80,33 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
11) Delete Directional Light entity.
12) UNDO deletion.
13) REDO deletion.
- 14) Look for errors.
+ 14) Look for errors and asserts.
:return: None
"""
import azlmbr.legacy.general as general
- import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity
- from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Directional Light entity with no components.
- directional_light_name = "Directional Light"
- directional_light_entity = EditorEntity.create_editor_entity_at(
- math.Vector3(512.0, 512.0, 34.0), directional_light_name)
+ directional_light_entity = EditorEntity.create_editor_entity(AtomComponentProperties.directional_light())
Report.critical_result(Tests.directional_light_creation, directional_light_entity.exists())
# 2. Add Directional Light component to Directional Light entity.
- directional_light_component = directional_light_entity.add_component(directional_light_name)
+ directional_light_component = directional_light_entity.add_component(AtomComponentProperties.directional_light())
Report.critical_result(
- Tests.directional_light_component, directional_light_entity.has_component(directional_light_name))
+ Tests.directional_light_component,
+ directional_light_entity.has_component(AtomComponentProperties.directional_light()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -107,9 +133,9 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
Report.result(Tests.creation_redo, directional_light_entity.exists())
# 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden.
directional_light_entity.set_visibility_state(False)
@@ -121,19 +147,20 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
Report.result(Tests.is_visible, directional_light_entity.is_visible() is True)
# 8. Add Camera entity.
- camera_name = "Camera"
- camera_entity = EditorEntity.create_editor_entity_at(math.Vector3(512.0, 512.0, 34.0), camera_name)
+ camera_entity = EditorEntity.create_editor_entity(AtomComponentProperties.camera())
Report.result(Tests.camera_creation, camera_entity.exists())
# 9. Add Camera component to Camera entity.
- camera_entity.add_component(camera_name)
- Report.result(Tests.camera_component_added, camera_entity.has_component(camera_name))
+ camera_entity.add_component(AtomComponentProperties.camera())
+ Report.result(Tests.camera_component_added, camera_entity.has_component(AtomComponentProperties.camera()))
# 10. Set the Directional Light component property Shadow|Camera to the Camera entity.
- shadow_camera_property_path = "Controller|Configuration|Shadow|Camera"
- directional_light_component.set_component_property_value(shadow_camera_property_path, camera_entity.id)
- shadow_camera_set = directional_light_component.get_component_property_value(shadow_camera_property_path)
- Report.result(Tests.shadow_camera_check, camera_entity.id == shadow_camera_set)
+ directional_light_component.set_component_property_value(
+ AtomComponentProperties.directional_light('Camera'), camera_entity.id)
+ Report.result(
+ Tests.shadow_camera_check,
+ camera_entity.id == directional_light_component.get_component_property_value(
+ AtomComponentProperties.directional_light('Camera')))
# 11. Delete DirectionalLight entity.
directional_light_entity.delete()
@@ -147,9 +174,12 @@ def AtomEditorComponents_DirectionalLight_AddedToEntity():
general.redo()
Report.result(Tests.deletion_redo, not directional_light_entity.exists())
- # 14. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 14. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py
index 39d7acf4f4..558d69046e 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DisplayMapperAdded.py
@@ -5,24 +5,47 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
+
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- display_mapper_creation = ("Display Mapper Entity successfully created", "Display Mapper Entity failed to be created")
- display_mapper_component = ("Entity has a Display Mapper component", "Entity failed to find Display Mapper component")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ display_mapper_creation = (
+ "Display Mapper Entity successfully created",
+ "Display Mapper Entity failed to be created")
+ display_mapper_component = (
+ "Entity has a Display Mapper component",
+ "Entity failed to find Display Mapper component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ ldr_color_grading_lut = (
+ "LDR color Grading LUT asset set",
+ "LDR color Grading LUT asset could not be set")
+ enable_ldr_color_grading_lut = (
+ "Enable LDR color grading LUT set",
+ "Enable LDR color grading LUT could not be set")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_DisplayMapper_AddedToEntity():
@@ -43,39 +66,43 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
2) Add Display Mapper component to Display Mapper entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
- 5) Enter/Exit game mode.
- 6) Test IsHidden.
- 7) Test IsVisible.
- 8) Delete Display Mapper entity.
- 9) UNDO deletion.
- 10) REDO deletion.
- 11) Look for errors.
+ 5) Set LDR color Grading LUT asset.
+ 6) Set Enable LDR color grading LUT property True
+ 7) Enter/Exit game mode.
+ 8) Test IsHidden.
+ 9) Test IsVisible.
+ 10) Delete Display Mapper entity.
+ 11) UNDO deletion.
+ 12) REDO deletion.
+ 13) Look for errors and asserts.
:return: None
"""
+ import os
import azlmbr.legacy.general as general
- import azlmbr.math as math
+ 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 as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Display Mapper entity with no components.
- display_mapper = "Display Mapper"
- display_mapper_entity = EditorEntity.create_editor_entity_at(
- math.Vector3(512.0, 512.0, 34.0), f"{display_mapper}")
+ display_mapper_entity = EditorEntity.create_editor_entity(AtomComponentProperties.display_mapper())
Report.critical_result(Tests.display_mapper_creation, display_mapper_entity.exists())
# 2. Add Display Mapper component to Display Mapper entity.
- display_mapper_entity.add_component(display_mapper)
- Report.critical_result(Tests.display_mapper_component, display_mapper_entity.has_component(display_mapper))
+ display_mapper_component = display_mapper_entity.add_component(AtomComponentProperties.display_mapper())
+ Report.critical_result(
+ Tests.display_mapper_component,
+ display_mapper_entity.has_component(AtomComponentProperties.display_mapper()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -101,35 +128,56 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, display_mapper_entity.exists())
- # 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
- general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ # 5. Set LDR color Grading LUT asset.
+ display_mapper_asset_path = os.path.join("TestData", "test.lightingpreset.azasset")
+ display_mapper_asset = Asset.find_asset_by_path(display_mapper_asset_path, False)
+ display_mapper_component.set_component_property_value(
+ AtomComponentProperties.display_mapper("LDR color Grading LUT"), display_mapper_asset.id)
+ Report.result(
+ Tests.ldr_color_grading_lut,
+ display_mapper_component.get_component_property_value(
+ AtomComponentProperties.display_mapper("LDR color Grading LUT")) == display_mapper_asset.id)
- # 6. Test IsHidden.
+ # 6. Set Enable LDR color grading LUT property True
+ display_mapper_component.set_component_property_value(
+ AtomComponentProperties.display_mapper('Enable LDR color grading LUT'), True)
+ Report.result(
+ Tests.enable_ldr_color_grading_lut,
+ display_mapper_component.get_component_property_value(
+ AtomComponentProperties.display_mapper('Enable LDR color grading LUT')) is True)
+
+ # 7. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 8. Test IsHidden.
display_mapper_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, display_mapper_entity.is_hidden() is True)
- # 7. Test IsVisible.
+ # 9. Test IsVisible.
display_mapper_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, display_mapper_entity.is_visible() is True)
- # 8. Delete Display Mapper entity.
+ # 10. Delete Display Mapper entity.
display_mapper_entity.delete()
Report.result(Tests.entity_deleted, not display_mapper_entity.exists())
- # 9. UNDO deletion.
+ # 11. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, display_mapper_entity.exists())
- # 10. REDO deletion.
+ # 12. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not display_mapper_entity.exists())
- # 11. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 13. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py
new file mode 100644
index 0000000000..dddcca64fa
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py
@@ -0,0 +1,158 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ entity_reference_creation = (
+ "Entity Reference Entity successfully created",
+ "Entity Reference Entity failed to be created")
+ entity_reference_component = (
+ "Entity has an Entity Reference component",
+ "Entity failed to find Entity Reference component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_EntityReference_AddedToEntity():
+ """
+ Summary:
+ Tests the Entity Reference component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create an Entity Reference entity with no components.
+ 2) Add Entity Reference component to Entity Reference entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Enter/Exit game mode.
+ 6) Test IsHidden.
+ 7) Test IsVisible.
+ 8) Delete Entity Reference entity.
+ 9) UNDO deletion.
+ 10) REDO deletion.
+ 11) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create an Entity Reference entity with no components.
+ entity_reference_entity = EditorEntity.create_editor_entity(AtomComponentProperties.entity_reference())
+ Report.critical_result(Tests.entity_reference_creation, entity_reference_entity.exists())
+
+ # 2. Add Entity Reference component to Entity Reference entity.
+ entity_reference_component = entity_reference_entity.add_component(
+ AtomComponentProperties.entity_reference())
+ Report.critical_result(
+ Tests.entity_reference_component,
+ entity_reference_entity.has_component(AtomComponentProperties.entity_reference()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not entity_reference_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, entity_reference_entity.exists())
+
+ # 5. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 6. Test IsHidden.
+ entity_reference_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, entity_reference_entity.is_hidden() is True)
+
+ # 7. Test IsVisible.
+ entity_reference_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, entity_reference_entity.is_visible() is True)
+
+ # 8. Delete Entity Reference entity.
+ entity_reference_entity.delete()
+ Report.result(Tests.entity_deleted, not entity_reference_entity.exists())
+
+ # 9. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, entity_reference_entity.exists())
+
+ # 10. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not entity_reference_entity.exists())
+
+ # 11. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_EntityReference_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py
index 23a84435f7..6fa9660539 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ExposureControlAdded.py
@@ -5,25 +5,58 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- exposure_control_creation = ("ExposureControl Entity successfully created", "ExposureControl Entity failed to be created")
- exposure_control_component = ("Entity has a Exposure Control component", "Entity failed to find Exposure Control component")
- post_fx_component = ("Entity has a Post FX Layer component", "Entity did not have a Post FX Layer component")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ camera_creation = (
+ "Camera Entity successfully created",
+ "Camera Entity failed to be created")
+ camera_component_added = (
+ "Camera component was added to entity",
+ "Camera component failed to be added to entity")
+ camera_component_check = (
+ "Entity has a Camera component",
+ "Entity failed to find Camera component")
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ exposure_control_creation = (
+ "ExposureControl Entity successfully created",
+ "ExposureControl Entity failed to be created")
+ exposure_control_component = (
+ "Entity has a Exposure Control component",
+ "Entity failed to find Exposure Control component")
+ exposure_control_disabled = (
+ "DepthOfField component disabled",
+ "DepthOfField component was not disabled.")
+ post_fx_component = (
+ "Entity has a Post FX Layer component",
+ "Entity did not have a Post FX Layer component")
+ exposure_control_enabled = (
+ "DepthOfField component enabled",
+ "DepthOfField component was not enabled.")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_ExposureControl_AddedToEntity():
@@ -44,41 +77,42 @@ def AtomEditorComponents_ExposureControl_AddedToEntity():
2) Add Exposure Control component to Exposure Control entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
- 5) Enter/Exit game mode.
- 6) Test IsHidden.
- 7) Test IsVisible.
- 8) Add Post FX Layer component.
- 9) Delete Exposure Control entity.
- 10) UNDO deletion.
- 11) REDO deletion.
- 12) Look for errors.
+ 5) Verify Exposure Control component not enabled.
+ 6) Add Post FX Layer component since it is required by the Exposure Control component.
+ 7) Verify Exposure Control component is enabled.
+ 8) Enter/Exit game mode.
+ 9) Test IsHidden.
+ 10) Test IsVisible.
+ 11) Delete Exposure Control entity.
+ 12) UNDO deletion.
+ 13) REDO deletion.
+ 14) Look for errors and asserts.
:return: None
"""
import azlmbr.legacy.general as general
- import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity
- from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Creation of Exposure Control entity with no components.
- exposure_control_name = "Exposure Control"
- exposure_control_entity = EditorEntity.create_editor_entity_at(
- math.Vector3(512.0, 512.0, 34.0), f"{exposure_control_name}")
+ exposure_control_entity = EditorEntity.create_editor_entity(AtomComponentProperties.exposure_control())
Report.critical_result(Tests.exposure_control_creation, exposure_control_entity.exists())
# 2. Add Exposure Control component to Exposure Control entity.
- exposure_control_entity.add_component(exposure_control_name)
+ exposure_control_component = exposure_control_entity.add_component(AtomComponentProperties.exposure_control())
Report.critical_result(
- Tests.exposure_control_component, exposure_control_entity.has_component(exposure_control_name))
+ Tests.exposure_control_component,
+ exposure_control_entity.has_component(AtomComponentProperties.exposure_control()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -104,40 +138,49 @@ def AtomEditorComponents_ExposureControl_AddedToEntity():
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, exposure_control_entity.exists())
- # 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
- general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ # 5. Verify Exposure Control component not enabled.
+ Report.result(Tests.exposure_control_disabled, not exposure_control_component.is_enabled())
- # 6. Test IsHidden.
+ # 6. Add Post FX Layer component since it is required by the Exposure Control component.
+ exposure_control_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(Tests.post_fx_component,
+ exposure_control_entity.has_component(AtomComponentProperties.postfx_layer()))
+
+ # 7. Verify Exposure Control component is enabled.
+ Report.result(Tests.exposure_control_enabled, exposure_control_component.is_enabled())
+
+ # 8. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 9. Test IsHidden.
exposure_control_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, exposure_control_entity.is_hidden() is True)
- # 7. Test IsVisible.
+ # 10. Test IsVisible.
exposure_control_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, exposure_control_entity.is_visible() is True)
- # 8. Add Post FX Layer component.
- post_fx_layer_name = "PostFX Layer"
- exposure_control_entity.add_component(post_fx_layer_name)
- Report.result(Tests.post_fx_component, exposure_control_entity.has_component(post_fx_layer_name))
-
- # 9. Delete ExposureControl entity.
+ # 11. Delete ExposureControl entity.
exposure_control_entity.delete()
Report.result(Tests.entity_deleted, not exposure_control_entity.exists())
- # 10. UNDO deletion.
+ # 12. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, exposure_control_entity.exists())
- # 11. REDO deletion.
+ # 13. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not exposure_control_entity.exists())
- # 12. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 14. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py
index 64bbfb1c4d..7f0c38e289 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GlobalSkylightIBLAdded.py
@@ -5,26 +5,55 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- global_skylight_creation = ("Global Skylight (IBL) Entity successfully created", "Global Skylight (IBL) Entity failed to be created")
- global_skylight_component = ("Entity has a Global Skylight (IBL) component", "Entity failed to find Global Skylight (IBL) component")
- diffuse_image_set = ("Entity has the Diffuse Image set", "Entity did not the Diffuse Image set")
- specular_image_set = ("Entity has the Specular Image set", "Entity did not the Specular Image set")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ camera_creation = (
+ "Camera Entity successfully created",
+ "Camera Entity failed to be created")
+ camera_component_added = (
+ "Camera component was added to entity",
+ "Camera component failed to be added to entity")
+ camera_component_check = (
+ "Entity has a Camera component",
+ "Entity failed to find Camera component")
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ global_skylight_creation = (
+ "Global Skylight (IBL) Entity successfully created",
+ "Global Skylight (IBL) Entity failed to be created")
+ global_skylight_component = (
+ "Entity has a Global Skylight (IBL) component",
+ "Entity failed to find Global Skylight (IBL) component")
+ diffuse_image_set = (
+ "Entity has the Diffuse Image set",
+ "Entity did not the Diffuse Image set")
+ specular_image_set = (
+ "Entity has the Specular Image set",
+ "Entity did not the Specular Image set")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
@@ -60,29 +89,28 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
import os
import azlmbr.legacy.general as general
- import azlmbr.math as math
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 as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Global Skylight (IBL) entity with no components.
- global_skylight_name = "Global Skylight (IBL)"
- global_skylight_entity = EditorEntity.create_editor_entity_at(
- math.Vector3(512.0, 512.0, 34.0), global_skylight_name)
+ global_skylight_entity = EditorEntity.create_editor_entity(AtomComponentProperties.global_skylight())
Report.critical_result(Tests.global_skylight_creation, global_skylight_entity.exists())
# 2. Add Global Skylight (IBL) component to Global Skylight (IBL) entity.
- global_skylight_component = global_skylight_entity.add_component(global_skylight_name)
+ global_skylight_component = global_skylight_entity.add_component(AtomComponentProperties.global_skylight())
Report.critical_result(
- Tests.global_skylight_component, global_skylight_entity.has_component(global_skylight_name))
+ Tests.global_skylight_component,
+ global_skylight_entity.has_component(AtomComponentProperties.global_skylight()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -109,9 +137,9 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
Report.result(Tests.creation_redo, global_skylight_entity.exists())
# 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden.
global_skylight_entity.set_visibility_state(False)
@@ -126,19 +154,21 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
diffuse_image_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
diffuse_image_asset = Asset.find_asset_by_path(diffuse_image_path, False)
global_skylight_component.set_component_property_value(
- global_skylight_diffuse_image_property, diffuse_image_asset.id)
- diffuse_image_set = global_skylight_component.get_component_property_value(
- global_skylight_diffuse_image_property)
- Report.result(Tests.diffuse_image_set, diffuse_image_set == diffuse_image_asset.id)
+ AtomComponentProperties.global_skylight('Diffuse Image'), diffuse_image_asset.id)
+ Report.result(
+ Tests.diffuse_image_set,
+ diffuse_image_asset.id == global_skylight_component.get_component_property_value(
+ AtomComponentProperties.global_skylight('Diffuse Image')))
# 9. Set the Specular Image asset on the Global Light (IBL) entity.
specular_image_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
specular_image_asset = Asset.find_asset_by_path(specular_image_path, False)
global_skylight_component.set_component_property_value(
- global_skylight_specular_image_property, specular_image_asset.id)
- specular_image_added = global_skylight_component.get_component_property_value(
- global_skylight_specular_image_property)
- Report.result(Tests.specular_image_set, specular_image_added == specular_image_asset.id)
+ AtomComponentProperties.global_skylight('Specular Image'), specular_image_asset.id)
+ Report.result(
+ Tests.specular_image_set,
+ specular_image_asset.id == global_skylight_component.get_component_property_value(
+ AtomComponentProperties.global_skylight('Specular Image')))
# 10. Delete Global Skylight (IBL) entity.
global_skylight_entity.delete()
@@ -152,9 +182,12 @@ def AtomEditorComponents_GlobalSkylightIBL_AddedToEntity():
general.redo()
Report.result(Tests.deletion_redo, not global_skylight_entity.exists())
- # 13. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 13. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GridAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GridAdded.py
new file mode 100644
index 0000000000..a77a1f50a4
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_GridAdded.py
@@ -0,0 +1,158 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ grid_entity_creation = (
+ "Grid Entity successfully created",
+ "Grid Entity failed to be created")
+ grid_component_added = (
+ "Entity has a Grid component",
+ "Entity failed to find Grid component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_Grid_AddedToEntity():
+ """
+ Summary:
+ Tests the Grid component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create a Grid entity with no components.
+ 2) Add a Grid component to Grid entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Enter/Exit game mode.
+ 6) Test IsHidden.
+ 7) Test IsVisible.
+ 8) Delete Grid entity.
+ 9) UNDO deletion.
+ 10) REDO deletion.
+ 11) Look for errors.
+
+ :return: None
+ """
+
+ import os
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create a Grid entity with no components.
+ grid_entity = EditorEntity.create_editor_entity(AtomComponentProperties.grid())
+ Report.critical_result(Tests.grid_entity_creation, grid_entity.exists())
+
+ # 2. Add a Grid component to Grid entity.
+ grid_component = grid_entity.add_component(AtomComponentProperties.grid())
+ Report.critical_result(
+ Tests.grid_component_added,
+ grid_entity.has_component(AtomComponentProperties.grid()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not grid_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, grid_entity.exists())
+
+ # 5. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 6. Test IsHidden.
+ grid_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, grid_entity.is_hidden() is True)
+
+ # 7. Test IsVisible.
+ grid_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, grid_entity.is_visible() is True)
+
+ # 8. Delete Grid entity.
+ grid_entity.delete()
+ Report.result(Tests.entity_deleted, not grid_entity.exists())
+
+ # 9. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, grid_entity.exists())
+
+ # 10. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not grid_entity.exists())
+
+ # 11. Look for errors or asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_Grid_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRColorGradingAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRColorGradingAdded.py
new file mode 100644
index 0000000000..4972079fcd
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRColorGradingAdded.py
@@ -0,0 +1,192 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ hdr_color_grading_creation = (
+ "HDR Color Grading Entity successfully created",
+ "HDR Color Grading Entity failed to be created")
+ hdr_color_grading_component = (
+ "Entity has an HDR Color Grading component",
+ "Entity failed to find HDR Color Grading component")
+ hdr_color_grading_disabled = (
+ "HDR Color Grading component disabled",
+ "HDR Color Grading component was not disabled")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ hdr_color_grading_enabled = (
+ "HDR Color Grading component enabled",
+ "HDR Color Grading component was not enabled")
+ enable_hdr_color_grading_parameter_enabled = (
+ "Enable HDR Color Grading parameter enabled",
+ "Enable HDR Color Grading parameter was not enabled")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_HDRColorGrading_AddedToEntity():
+ """
+ Summary:
+ Tests the HDR Color Grading component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create an HDR Color Grading entity with no components.
+ 2) Add HDR Color Grading component to HDR Color Grading entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify HDR Color Grading component not enabled.
+ 6) Add PostFX Layer component since it is required by the HDR Color Grading component.
+ 7) Verify HDR Color Grading component is enabled.
+ 8) Enable the "Enable HDR Color Grading" parameter.
+ 9) Enter/Exit game mode.
+ 10) Test IsHidden.
+ 11) Test IsVisible.
+ 12) Delete HDR Color Grading entity.
+ 13) UNDO deletion.
+ 14) REDO deletion.
+ 15) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create an HDR Color Grading entity with no components.
+ hdr_color_grading_entity = EditorEntity.create_editor_entity(AtomComponentProperties.hdr_color_grading())
+ Report.critical_result(Tests.hdr_color_grading_creation, hdr_color_grading_entity.exists())
+
+ # 2. Add HDR Color Grading component to HDR Color Grading entity.
+ hdr_color_grading_component = hdr_color_grading_entity.add_component(
+ AtomComponentProperties.hdr_color_grading())
+ Report.critical_result(
+ Tests.hdr_color_grading_component,
+ hdr_color_grading_entity.has_component(AtomComponentProperties.hdr_color_grading()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not hdr_color_grading_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, hdr_color_grading_entity.exists())
+
+ # 5. Verify HDR Color Grading component not enabled.
+ Report.result(Tests.hdr_color_grading_disabled, not hdr_color_grading_component.is_enabled())
+
+ # 6. Add PostFX Layer component since it is required by the HDR Color Grading component.
+ hdr_color_grading_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ hdr_color_grading_entity.has_component(AtomComponentProperties.postfx_layer()))
+
+ # 7. Verify HDR Color Grading component is enabled.
+ Report.result(Tests.hdr_color_grading_enabled, hdr_color_grading_component.is_enabled())
+
+ # 8. Enable the "Enable HDR Color Grading" parameter.
+ hdr_color_grading_component.set_component_property_value(
+ AtomComponentProperties.hdr_color_grading('Enable HDR color grading'), True)
+ Report.result(Tests.enable_hdr_color_grading_parameter_enabled,
+ hdr_color_grading_component.get_component_property_value(
+ AtomComponentProperties.hdr_color_grading('Enable HDR color grading')) is True)
+
+ # 9. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 10. Test IsHidden.
+ hdr_color_grading_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, hdr_color_grading_entity.is_hidden() is True)
+
+ # 11. Test IsVisible.
+ hdr_color_grading_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, hdr_color_grading_entity.is_visible() is True)
+
+ # 12. Delete HDR Color Grading entity.
+ hdr_color_grading_entity.delete()
+ Report.result(Tests.entity_deleted, not hdr_color_grading_entity.exists())
+
+ # 13. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, hdr_color_grading_entity.exists())
+
+ # 14. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not hdr_color_grading_entity.exists())
+
+ # 15. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_HDRColorGrading_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRiSkyboxAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRiSkyboxAdded.py
new file mode 100644
index 0000000000..0f96bc5424
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HDRiSkyboxAdded.py
@@ -0,0 +1,177 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ hdri_skybox_entity_creation = (
+ "HDRi Skybox successfully created",
+ "HDRi Skybox failed to be created")
+ hdri_skybox_component = (
+ "Entity has an HDRi Skybox component",
+ "Entity failed to find HDRi Skybox component")
+ cubemap_property_set = (
+ "Cubemap property set on HDRi Skybox component",
+ "Couldn't set Cubemap property on HDRi Skybox component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_HDRiSkybox_AddedToEntity():
+ """
+ Summary:
+ Tests the HDRi Skybox component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create an HDRi Skybox with no components.
+ 2) Add an HDRi Skybox component to HDRi Skybox.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Enter/Exit game mode.
+ 6) Test IsHidden.
+ 7) Test IsVisible.
+ 8) Delete HDRi Skybox.
+ 9) UNDO deletion.
+ 10) REDO deletion.
+ 11) Look for errors.
+
+ :return: None
+ """
+
+ import os
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.asset_utils import Asset
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create an HDRi Skybox with no components.
+ hdri_skybox_entity = EditorEntity.create_editor_entity(
+ AtomComponentProperties.hdri_skybox())
+ Report.critical_result(Tests.hdri_skybox_entity_creation,
+ hdri_skybox_entity.exists())
+
+ # 2. Add an HDRi Skybox component to HDRi Skybox.
+ hdri_skybox_component = hdri_skybox_entity.add_component(
+ AtomComponentProperties.hdri_skybox())
+ Report.critical_result(
+ Tests.hdri_skybox_component,
+ hdri_skybox_entity.has_component(AtomComponentProperties.hdri_skybox()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not hdri_skybox_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, hdri_skybox_entity.exists())
+
+
+ # 5. Set Cubemap Texture on HDRi Skybox component.
+ skybox_cubemap_asset_path = os.path.join("LightingPresets", "default_iblskyboxcm.exr.streamingimage")
+ skybox_cubemap_material_asset = Asset.find_asset_by_path(skybox_cubemap_asset_path, False)
+ hdri_skybox_component.set_component_property_value(
+ AtomComponentProperties.hdri_skybox('Cubemap Texture'), skybox_cubemap_material_asset.id)
+ get_cubemap_property = hdri_skybox_component.get_component_property_value(
+ AtomComponentProperties.hdri_skybox('Cubemap Texture'))
+ Report.result(Tests.cubemap_property_set, get_cubemap_property == skybox_cubemap_material_asset.id)
+
+
+ # 6. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 7. Test IsHidden.
+ hdri_skybox_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, hdri_skybox_entity.is_hidden() is True)
+
+ # 8. Test IsVisible.
+ hdri_skybox_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, hdri_skybox_entity.is_visible() is True)
+
+ # 9. Delete hdri_skybox entity.
+ hdri_skybox_entity.delete()
+ Report.result(Tests.entity_deleted, not hdri_skybox_entity.exists())
+
+ # 10. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, hdri_skybox_entity.exists())
+
+ # 11. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not hdri_skybox_entity.exists())
+
+ # 12. Look for errors or asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_HDRiSkybox_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py
index 8b1432f1f7..249671556d 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LightAdded.py
@@ -5,24 +5,49 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- light_creation = ("Light Entity successfully created", "Light Entity failed to be created")
- light_component = ("Entity has a Light component", "Entity failed to find Light component")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ camera_creation = (
+ "Camera Entity successfully created",
+ "Camera Entity failed to be created")
+ camera_component_added = (
+ "Camera component was added to entity",
+ "Camera component failed to be added to entity")
+ camera_component_check = (
+ "Entity has a Camera component",
+ "Entity failed to find Camera component")
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ light_creation = (
+ "Light Entity successfully created",
+ "Light Entity failed to be created")
+ light_component = (
+ "Entity has a Light component",
+ "Entity failed to find Light component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_Light_AddedToEntity():
@@ -55,26 +80,25 @@ def AtomEditorComponents_Light_AddedToEntity():
"""
import azlmbr.legacy.general as general
- import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity
- from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Light entity with no components.
- light_name = "Light"
- light_entity = EditorEntity.create_editor_entity_at(math.Vector3(512.0, 512.0, 34.0), light_name)
+ light_entity = EditorEntity.create_editor_entity(AtomComponentProperties.light())
Report.critical_result(Tests.light_creation, light_entity.exists())
# 2. Add Light component to the Light entity.
- light_entity.add_component(light_name)
- Report.critical_result(Tests.light_component, light_entity.has_component(light_name))
+ light_component = light_entity.add_component(AtomComponentProperties.light())
+ Report.critical_result(Tests.light_component, light_entity.has_component(AtomComponentProperties.light()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -101,9 +125,9 @@ def AtomEditorComponents_Light_AddedToEntity():
Report.result(Tests.creation_redo, light_entity.exists())
# 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden.
light_entity.set_visibility_state(False)
@@ -126,9 +150,12 @@ def AtomEditorComponents_Light_AddedToEntity():
general.redo()
Report.result(Tests.deletion_redo, not light_entity.exists())
- # 11. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 11. Look for errors asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LookModificationAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LookModificationAdded.py
new file mode 100644
index 0000000000..afb8033426
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_LookModificationAdded.py
@@ -0,0 +1,211 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ look_modification_creation = (
+ "Look Modification Entity successfully created",
+ "Look Modification Entity failed to be created")
+ look_modification_component = (
+ "Entity has a Look Modification component",
+ "Entity failed to find Look Modification component")
+ look_modification_disabled = (
+ "Look Modification component disabled",
+ "Look Modification component was not disabled")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ look_modification_enabled = (
+ "Look Modification component enabled",
+ "Look Modification component was not enabled")
+ enable_look_modification_parameter_enabled = (
+ "Enable look modification parameter enabled",
+ "Enable look modification parameter was not enabled")
+ color_grading_lut_set = (
+ "Entity has the Color Grading LUT set",
+ "Entity did not the Color Grading LUT set")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_LookModification_AddedToEntity():
+ """
+ Summary:
+ Tests the Look Modification component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create an Look Modification entity with no components.
+ 2) Add Look Modification component to Look Modification entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify Look Modification component not enabled.
+ 6) Add PostFX Layer component since it is required by the Look Modification component.
+ 7) Verify Look Modification component is enabled.
+ 8) Enable the "Enable Look Modification" parameter.
+ 9) Add LUT asset to the Color Grading LUT parameter.
+ 9) Enter/Exit game mode.
+ 10) Test IsHidden.
+ 11) Test IsVisible.
+ 12) Delete Look Modification entity.
+ 13) UNDO deletion.
+ 14) REDO deletion.
+ 15) Look for errors.
+
+ :return: None
+ """
+
+ import os
+
+ import azlmbr.legacy.general as general
+
+ from editor_python_test_tools.asset_utils import Asset
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create an Look Modification entity with no components.
+ look_modification_entity = EditorEntity.create_editor_entity(AtomComponentProperties.look_modification())
+ Report.critical_result(Tests.look_modification_creation, look_modification_entity.exists())
+
+ # 2. Add Look Modification component to Look Modification entity.
+ look_modification_component = look_modification_entity.add_component(
+ AtomComponentProperties.look_modification())
+ Report.critical_result(
+ Tests.look_modification_component,
+ look_modification_entity.has_component(AtomComponentProperties.look_modification()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not look_modification_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, look_modification_entity.exists())
+
+ # 5. Verify Look Modification component not enabled.
+ Report.result(Tests.look_modification_disabled, not look_modification_component.is_enabled())
+
+ # 6. Add PostFX Layer component since it is required by the Look Modification component.
+ look_modification_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ look_modification_entity.has_component(AtomComponentProperties.postfx_layer()))
+
+ # 7. Verify Look Modification component is enabled.
+ Report.result(Tests.look_modification_enabled, look_modification_component.is_enabled())
+
+ # 8. Enable the "Enable look modification" parameter.
+ look_modification_component.set_component_property_value(
+ AtomComponentProperties.look_modification('Enable look modification'), True)
+ Report.result(Tests.enable_look_modification_parameter_enabled,
+ look_modification_component.get_component_property_value(
+ AtomComponentProperties.look_modification('Enable look modification')) is True)
+
+ # 9. Set the Color Grading LUT asset on the Look Modification entity.
+ color_grading_lut_path = os.path.join("ColorGrading", "TestData", "Photoshop", "inv-Log2-48nits",
+ "test_3dl_32_lut.azasset")
+ color_grading_lut_asset = Asset.find_asset_by_path(color_grading_lut_path, False)
+ look_modification_component.set_component_property_value(
+ AtomComponentProperties.look_modification('Color Grading LUT'), color_grading_lut_asset.id)
+ Report.result(
+ Tests.color_grading_lut_set,
+ color_grading_lut_asset.id == look_modification_component.get_component_property_value(
+ AtomComponentProperties.look_modification('Color Grading LUT')))
+
+ # 10. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 11. Test IsHidden.
+ look_modification_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, look_modification_entity.is_hidden() is True)
+
+ # 12. Test IsVisible.
+ look_modification_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, look_modification_entity.is_visible() is True)
+
+ # 13. Delete Look Modification entity.
+ look_modification_entity.delete()
+ Report.result(Tests.entity_deleted, not look_modification_entity.exists())
+
+ # 14. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, look_modification_entity.exists())
+
+ # 15. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not look_modification_entity.exists())
+
+ # 16. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_LookModification_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py
index 32cd5471f2..c613bb23e7 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py
@@ -96,6 +96,7 @@ def AtomEditorComponents_Material_AddedToEntity():
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
with Tracer() as error_tracer:
# Test setup begins.
@@ -105,15 +106,14 @@ def AtomEditorComponents_Material_AddedToEntity():
# Test steps begin.
# 1. Create a Material entity with no components.
- material_name = "Material"
- material_entity = EditorEntity.create_editor_entity(material_name)
+ material_entity = EditorEntity.create_editor_entity(AtomComponentProperties.material())
Report.critical_result(Tests.material_creation, material_entity.exists())
# 2. Add a Material component to Material entity.
- material_component = material_entity.add_component(material_name)
+ material_component = material_entity.add_component(AtomComponentProperties.material())
Report.critical_result(
Tests.material_component,
- material_entity.has_component(material_name))
+ material_entity.has_component(AtomComponentProperties.material()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -143,9 +143,8 @@ def AtomEditorComponents_Material_AddedToEntity():
Report.result(Tests.material_disabled, not material_component.is_enabled())
# 6. Add Actor component since it is required by the Material component.
- actor_name = "Actor"
- material_entity.add_component(actor_name)
- Report.result(Tests.actor_component, material_entity.has_component(actor_name))
+ material_entity.add_component(AtomComponentProperties.actor())
+ Report.result(Tests.actor_component, material_entity.has_component(AtomComponentProperties.actor()))
# 7. Verify Material component is enabled.
Report.result(Tests.material_enabled, material_component.is_enabled())
@@ -153,15 +152,14 @@ def AtomEditorComponents_Material_AddedToEntity():
# 8. UNDO component addition.
general.undo()
general.idle_wait_frames(1)
- Report.result(Tests.actor_undo, not material_entity.has_component(actor_name))
+ Report.result(Tests.actor_undo, not material_entity.has_component(AtomComponentProperties.actor()))
# 9. Verify Material component not enabled.
Report.result(Tests.material_disabled, not material_component.is_enabled())
# 10. Add Mesh component since it is required by the Material component.
- mesh_name = "Mesh"
- material_entity.add_component(mesh_name)
- Report.result(Tests.mesh_component, material_entity.has_component(mesh_name))
+ material_entity.add_component(AtomComponentProperties.mesh())
+ Report.result(Tests.mesh_component, material_entity.has_component(AtomComponentProperties.mesh()))
# 11. Verify Material component is enabled.
Report.result(Tests.material_enabled, material_component.is_enabled())
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py
index 82d3b89309..9d56753961 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py
@@ -81,7 +81,7 @@ def AtomEditorComponents_Mesh_AddedToEntity():
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 as Atom
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
@@ -91,14 +91,14 @@ def AtomEditorComponents_Mesh_AddedToEntity():
# Test steps begin.
# 1. Create a Mesh entity with no components.
- mesh_entity = EditorEntity.create_editor_entity(Atom.mesh())
+ mesh_entity = EditorEntity.create_editor_entity(AtomComponentProperties.mesh())
Report.critical_result(Tests.mesh_entity_creation, mesh_entity.exists())
# 2. Add a Mesh component to Mesh entity.
- mesh_component = mesh_entity.add_component(Atom.mesh())
+ mesh_component = mesh_entity.add_component(AtomComponentProperties.mesh())
Report.critical_result(
Tests.mesh_component_added,
- mesh_entity.has_component(Atom.mesh()))
+ mesh_entity.has_component(AtomComponentProperties.mesh()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -127,9 +127,9 @@ def AtomEditorComponents_Mesh_AddedToEntity():
# 5. Set Mesh component asset property
model_path = os.path.join('Objects', 'shaderball', 'shaderball_default_1m.azmodel')
model = Asset.find_asset_by_path(model_path)
- mesh_component.set_component_property_value(Atom.mesh('Mesh Asset'), model.id)
+ mesh_component.set_component_property_value(AtomComponentProperties.mesh('Mesh Asset'), model.id)
Report.result(Tests.mesh_asset_specified,
- mesh_component.get_component_property_value(Atom.mesh('Mesh Asset')) == model.id)
+ mesh_component.get_component_property_value(AtomComponentProperties.mesh('Mesh Asset')) == model.id)
# 6. Enter/Exit game mode.
TestHelper.enter_game_mode(Tests.enter_game_mode)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_OcclusionCullingPlaneAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_OcclusionCullingPlaneAdded.py
new file mode 100644
index 0000000000..4226ae3dfe
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_OcclusionCullingPlaneAdded.py
@@ -0,0 +1,159 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ occlusion_culling_plane_entity_creation = (
+ "Occlusion Culling Plane Entity successfully created",
+ "Occlusion Culling Plane Entity failed to be created")
+ occlusion_culling_plane_component_added = (
+ "Entity has a Occlusion Culling Plane component",
+ "Entity failed to find Occlusion Culling Plane component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_OcclusionCullingPlane_AddedToEntity():
+ """
+ Summary:
+ Tests the occlusion culling plane component can be added to an entity and has the expected functionality.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create a Occlusion Culling Plane entity with no components.
+ 2) Add a Occlusion Culling Plane component to Occlusion Culling Plane entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Enter/Exit game mode.
+ 6) Test IsHidden.
+ 7) Test IsVisible.
+ 8) Delete Occlusion Culling Plane entity.
+ 9) UNDO deletion.
+ 10) REDO deletion.
+ 11) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create a occlusion culling plane entity with no components.
+ occlusion_culling_plane_entity = EditorEntity.create_editor_entity(
+ AtomComponentProperties.occlusion_culling_plane())
+ Report.critical_result(Tests.occlusion_culling_plane_entity_creation,
+ occlusion_culling_plane_entity.exists())
+
+ # 2. Add a occlusion culling plane component to occlusion culling plane entity.
+ occlusion_culling_plane_component = occlusion_culling_plane_entity.add_component(
+ AtomComponentProperties.occlusion_culling_plane())
+ Report.critical_result(
+ Tests.occlusion_culling_plane_component_added,
+ occlusion_culling_plane_entity.has_component(AtomComponentProperties.occlusion_culling_plane()))
+
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not occlusion_culling_plane_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, occlusion_culling_plane_entity.exists())
+
+ # 5. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 6. Test IsHidden.
+ occlusion_culling_plane_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, occlusion_culling_plane_entity.is_hidden() is True)
+
+ # 7. Test IsVisible.
+ occlusion_culling_plane_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, occlusion_culling_plane_entity.is_visible() is True)
+
+ # 8. Delete occlusion_culling_plane entity.
+ occlusion_culling_plane_entity.delete()
+ Report.result(Tests.entity_deleted, not occlusion_culling_plane_entity.exists())
+
+ # 9. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, occlusion_culling_plane_entity.exists())
+
+ # 10. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not occlusion_culling_plane_entity.exists())
+
+ # 11. Look for errors or asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_OcclusionCullingPlane_AddedToEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py
index 04441d5b2c..fa8c626016 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PhysicalSkyAdded.py
@@ -5,24 +5,49 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- physical_sky_creation = ("Physical Sky Entity successfully created", "Physical Sky Entity failed to be created")
- physical_sky_component = ("Entity has a Physical Sky component", "Entity failed to find Physical Sky component")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ camera_creation = (
+ "Camera Entity successfully created",
+ "Camera Entity failed to be created")
+ camera_component_added = (
+ "Camera component was added to entity",
+ "Camera component failed to be added to entity")
+ camera_component_check = (
+ "Entity has a Camera component",
+ "Entity failed to find Camera component")
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ physical_sky_creation = (
+ "Physical Sky Entity successfully created",
+ "Physical Sky Entity failed to be created")
+ physical_sky_component = (
+ "Entity has a Physical Sky component",
+ "Entity failed to find Physical Sky component")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_PhysicalSky_AddedToEntity():
@@ -49,32 +74,33 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
8) Delete Physical Sky entity.
9) UNDO deletion.
10) REDO deletion.
- 11) Look for errors.
+ 11) Look for errors and asserts.
:return: None
"""
import azlmbr.legacy.general as general
- import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity
- from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Physical Sky entity with no components.
- physical_sky_name = "Physical Sky"
- physical_sky_entity = EditorEntity.create_editor_entity_at(math.Vector3(512.0, 512.0, 34.0), physical_sky_name)
+ physical_sky_entity = EditorEntity.create_editor_entity(AtomComponentProperties.physical_sky())
Report.critical_result(Tests.physical_sky_creation, physical_sky_entity.exists())
# 2. Add Physical Sky component to Physical Sky entity.
- physical_sky_entity.add_component(physical_sky_name)
- Report.critical_result(Tests.physical_sky_component, physical_sky_entity.has_component(physical_sky_name))
+ physical_sky_component = physical_sky_entity.add_component(AtomComponentProperties.physical_sky())
+ Report.critical_result(
+ Tests.physical_sky_component,
+ physical_sky_entity.has_component(AtomComponentProperties.physical_sky()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -101,9 +127,9 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
Report.result(Tests.creation_redo, physical_sky_entity.exists())
# 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
# 6. Test IsHidden.
physical_sky_entity.set_visibility_state(False)
@@ -126,9 +152,12 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
general.redo()
Report.result(Tests.deletion_redo, not physical_sky_entity.exists())
- # 11. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 11. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py
index d38e96739d..6e4ae2d9ac 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded.py
@@ -86,6 +86,7 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
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
with Tracer() as error_tracer:
# Test setup begins.
@@ -95,15 +96,15 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
# Test steps begin.
# 1. Create a PostFX Gradient Weight Modifier entity with no components.
- postfx_gradient_weight_name = "PostFX Gradient Weight Modifier"
- postfx_gradient_weight_entity = EditorEntity.create_editor_entity(postfx_gradient_weight_name)
+ postfx_gradient_weight_entity = EditorEntity.create_editor_entity(AtomComponentProperties.postfx_gradient())
Report.critical_result(Tests.postfx_gradient_weight_creation, postfx_gradient_weight_entity.exists())
# 2. Add a PostFX Gradient Weight Modifier component to PostFX Gradient Weight Modifier entity.
- postfx_gradient_weight_component = postfx_gradient_weight_entity.add_component(postfx_gradient_weight_name)
+ postfx_gradient_weight_component = postfx_gradient_weight_entity.add_component(
+ AtomComponentProperties.postfx_gradient())
Report.critical_result(
Tests.postfx_gradient_weight_component,
- postfx_gradient_weight_entity.has_component(postfx_gradient_weight_name))
+ postfx_gradient_weight_entity.has_component(AtomComponentProperties.postfx_gradient()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -133,9 +134,10 @@ def AtomEditorComponents_PostFXGradientWeightModifier_AddedToEntity():
Report.result(Tests.postfx_gradient_weight_disabled, not postfx_gradient_weight_component.is_enabled())
# 6. Add PostFX Layer component since it is required by the PostFX Gradient Weight Modifier component.
- postfx_layer_name = "PostFX Layer"
- postfx_gradient_weight_entity.add_component(postfx_layer_name)
- Report.result(Tests.postfx_layer_component, postfx_gradient_weight_entity.has_component(postfx_layer_name))
+ postfx_gradient_weight_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ postfx_gradient_weight_entity.has_component(AtomComponentProperties.postfx_layer()))
# 7. Verify PostFX Gradient Weight Modifier component is enabled.
Report.result(Tests.postfx_gradient_weight_enabled, postfx_gradient_weight_component.is_enabled())
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py
index 8c2dee416b..efef4c0a43 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXLayerAdded.py
@@ -70,12 +70,11 @@ def AtomEditorComponents_postfx_layer_AddedToEntity():
:return: None
"""
- import os
-
import azlmbr.legacy.general as general
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
with Tracer() as error_tracer:
# Test setup begins.
@@ -85,13 +84,14 @@ def AtomEditorComponents_postfx_layer_AddedToEntity():
# Test steps begin.
# 1. Create a PostFX Layer entity with no components.
- postfx_layer_name = "PostFX Layer"
- postfx_layer_entity = EditorEntity.create_editor_entity(postfx_layer_name)
+ postfx_layer_entity = EditorEntity.create_editor_entity(AtomComponentProperties.postfx_layer())
Report.critical_result(Tests.postfx_layer_entity_creation, postfx_layer_entity.exists())
# 2. Add a PostFX Layer component to PostFX Layer entity.
- postfx_layer_component = postfx_layer_entity.add_component(postfx_layer_name)
- Report.critical_result(Tests.postfx_layer_component_added, postfx_layer_entity.has_component(postfx_layer_name))
+ postfx_layer_component = postfx_layer_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.critical_result(
+ Tests.postfx_layer_component_added,
+ postfx_layer_entity.has_component(AtomComponentProperties.postfx_layer()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py
index 8914ab9e7e..228ddfcdc5 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded.py
@@ -5,24 +5,49 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-# fmt: off
class Tests:
- camera_creation = ("Camera Entity successfully created", "Camera Entity failed to be created")
- camera_component_added = ("Camera component was added to entity", "Camera component failed to be added to entity")
- camera_component_check = ("Entity has a Camera component", "Entity failed to find Camera component")
- creation_undo = ("UNDO Entity creation success", "UNDO Entity creation failed")
- creation_redo = ("REDO Entity creation success", "REDO Entity creation failed")
- postfx_radius_weight_creation = ("PostFX Radius Weight Modifier Entity successfully created", "PostFX Radius Weight Modifier Entity failed to be created")
- postfx_radius_weight_component = ("Entity has a PostFX Radius Weight Modifier component", "Entity failed to find PostFX Radius Weight Modifier component")
- enter_game_mode = ("Entered game mode", "Failed to enter game mode")
- exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
- is_visible = ("Entity is visible", "Entity was not visible")
- is_hidden = ("Entity is hidden", "Entity was not hidden")
- entity_deleted = ("Entity deleted", "Entity was not deleted")
- deletion_undo = ("UNDO deletion success", "UNDO deletion failed")
- deletion_redo = ("REDO deletion success", "REDO deletion failed")
- no_error_occurred = ("No errors detected", "Errors were detected")
-# fmt: on
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ postfx_radius_weight_creation = (
+ "PostFX Radius Weight Modifier Entity successfully created",
+ "PostFX Radius Weight Modifier Entity failed to be created")
+ postfx_radius_weight_component = (
+ "Entity has a PostFX Radius Weight Modifier component",
+ "Entity failed to find PostFX Radius Weight Modifier component")
+ postfx_radius_weight_disabled = (
+ "PostFX Radius Weight Modifier component disabled",
+ "PostFX Radius Weight Modifier component was not disabled.")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ postfx_radius_weight_enabled = (
+ "PostFX Radius Weight Modifier component enabled",
+ "PostFX Radius Weight Modifier component was not enabled.")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity():
@@ -43,40 +68,42 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity():
2) Add Post FX Radius Weight Modifier component to Post FX Radius Weight Modifier entity.
3) UNDO the entity creation and component addition.
4) REDO the entity creation and component addition.
- 5) Enter/Exit game mode.
- 6) Test IsHidden.
- 7) Test IsVisible.
- 8) Delete PostFX Radius Weight Modifier entity.
- 9) UNDO deletion.
- 10) REDO deletion.
- 11) Look for errors.
+ 5) Verify PostFX Radius Weight Modifier component not enabled.
+ 6) Add PostFX Layer component since it is required by the PostFX Radius Weight Modifier component.
+ 7) Verify PostFX Radius Weight Modifier component is enabled.
+ 8) Enter/Exit game mode.
+ 9) Test IsHidden.
+ 10) Test IsVisible.
+ 11) Delete PostFX Radius Weight Modifier entity.
+ 12) UNDO deletion.
+ 13) REDO deletion.
+ 14) Look for errors.
:return: None
"""
import azlmbr.legacy.general as general
- import azlmbr.math as math
from editor_python_test_tools.editor_entity_utils import EditorEntity
- from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Post FX Radius Weight Modifier entity with no components.
- postfx_radius_weight_name = "PostFX Radius Weight Modifier"
- postfx_radius_weight_entity = EditorEntity.create_editor_entity_at(
- math.Vector3(512.0, 512.0, 34.0), postfx_radius_weight_name)
+ postfx_radius_weight_entity = EditorEntity.create_editor_entity(AtomComponentProperties.postfx_radius())
Report.critical_result(Tests.postfx_radius_weight_creation, postfx_radius_weight_entity.exists())
# 2. Add Post FX Radius Weight Modifier component to Post FX Radius Weight Modifier entity.
- postfx_radius_weight_entity.add_component(postfx_radius_weight_name)
+ postfx_radius_component = postfx_radius_weight_entity.add_component(AtomComponentProperties.postfx_radius())
Report.critical_result(
- Tests.postfx_radius_weight_component, postfx_radius_weight_entity.has_component(postfx_radius_weight_name))
+ Tests.postfx_radius_weight_component,
+ postfx_radius_weight_entity.has_component(AtomComponentProperties.postfx_radius()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -102,35 +129,50 @@ def AtomEditorComponents_PostFXRadiusWeightModifier_AddedToEntity():
general.idle_wait_frames(1)
Report.result(Tests.creation_redo, postfx_radius_weight_entity.exists())
- # 5. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
- general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ # 5. Verify PostFX Radius Weight Modifier component not enabled.
+ Report.result(Tests.postfx_radius_weight_disabled, not postfx_radius_component.is_enabled())
- # 6. Test IsHidden.
+ # 6. Add PostFX Layer component since it is required by the PostFX Radius Weight Modifier component.
+ postfx_radius_weight_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ postfx_radius_weight_entity.has_component(AtomComponentProperties.postfx_layer()))
+
+ # 7. Verify PostFX Radius Weight Modifier component is enabled.
+ Report.result(Tests.postfx_radius_weight_enabled, postfx_radius_component.is_enabled())
+
+ # 8. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 9. Test IsHidden.
postfx_radius_weight_entity.set_visibility_state(False)
Report.result(Tests.is_hidden, postfx_radius_weight_entity.is_hidden() is True)
- # 7. Test IsVisible.
+ # 10. Test IsVisible.
postfx_radius_weight_entity.set_visibility_state(True)
general.idle_wait_frames(1)
Report.result(Tests.is_visible, postfx_radius_weight_entity.is_visible() is True)
- # 8. Delete PostFX Radius Weight Modifier entity.
+ # 11. Delete PostFX Radius Weight Modifier entity.
postfx_radius_weight_entity.delete()
Report.result(Tests.entity_deleted, not postfx_radius_weight_entity.exists())
- # 9. UNDO deletion.
+ # 12. UNDO deletion.
general.undo()
Report.result(Tests.deletion_undo, postfx_radius_weight_entity.exists())
- # 10. REDO deletion.
+ # 13. REDO deletion.
general.redo()
Report.result(Tests.deletion_redo, not postfx_radius_weight_entity.exists())
- # 11. Look for errors.
- helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
- Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
+ # 14. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ for assert_info in error_tracer.asserts:
+ Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
if __name__ == "__main__":
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py
index 4c98bcd130..0a37ac6bf7 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded.py
@@ -92,6 +92,7 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
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
with Tracer() as error_tracer:
# Test setup begins.
@@ -101,15 +102,14 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
# Test steps begin.
# 1. Create a PostFx Shape Weight Modifier entity with no components.
- postfx_shape_weight_name = "PostFX Shape Weight Modifier"
- postfx_shape_weight_entity = EditorEntity.create_editor_entity(postfx_shape_weight_name)
+ postfx_shape_weight_entity = EditorEntity.create_editor_entity(AtomComponentProperties.postfx_shape())
Report.critical_result(Tests.postfx_shape_weight_creation, postfx_shape_weight_entity.exists())
# 2. Add a PostFx Shape Weight Modifier component to PostFx Shape Weight Modifier entity.
- postfx_shape_weight_component = postfx_shape_weight_entity.add_component(postfx_shape_weight_name)
+ postfx_shape_weight_component = postfx_shape_weight_entity.add_component(AtomComponentProperties.postfx_shape())
Report.critical_result(
Tests.postfx_shape_weight_component,
- postfx_shape_weight_entity.has_component(postfx_shape_weight_name))
+ postfx_shape_weight_entity.has_component(AtomComponentProperties.postfx_shape()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -139,16 +139,16 @@ def AtomEditorComponents_postfx_shape_weight_AddedToEntity():
Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
# 6. Add PostFX Layer component since it is required by the PostFx Shape Weight Modifier component.
- postfx_layer_name = "PostFX Layer"
- postfx_shape_weight_entity.add_component(postfx_layer_name)
- Report.result(Tests.postfx_layer_component, postfx_shape_weight_entity.has_component(postfx_layer_name))
+ postfx_shape_weight_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ postfx_shape_weight_entity.has_component(AtomComponentProperties.postfx_layer()))
# 7. Verify PostFx Shape Weight Modifier component is NOT enabled since it also requires a shape.
Report.result(Tests.postfx_shape_weight_disabled, not postfx_shape_weight_component.is_enabled())
# 8. Add a required shape looping over a list and checking if it enables PostFX Shape Weight Modifier.
- for shape in ['Axis Aligned Box Shape', 'Box Shape', 'Capsule Shape', 'Compound Shape', 'Cylinder Shape',
- 'Disk Shape', 'Polygon Prism Shape', 'Quad Shape', 'Sphere Shape', 'Vegetation Reference Shape']:
+ for shape in AtomComponentProperties.postfx_shape('shapes'):
postfx_shape_weight_entity.add_component(shape)
test_shape = (
f"Entity has a {shape} component",
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py
index 9b13eb2c7e..70adf9143a 100644
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_ReflectionProbeAdded.py
@@ -87,30 +87,28 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
"""
import azlmbr.legacy.general as general
- import azlmbr.math as math
import azlmbr.render as render
from editor_python_test_tools.editor_entity_utils import EditorEntity
- from editor_python_test_tools.utils import Report, Tracer, TestHelper as helper
+ from editor_python_test_tools.utils import Report, Tracer, TestHelper
+ from Atom.atom_utils.atom_constants import AtomComponentProperties
with Tracer() as error_tracer:
# Test setup begins.
# Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level.
- helper.init_idle()
- helper.open_level("", "Base")
+ TestHelper.init_idle()
+ TestHelper.open_level("", "Base")
# Test steps begin.
# 1. Create a Reflection Probe entity with no components.
- reflection_probe_name = "Reflection Probe"
- reflection_probe_entity = EditorEntity.create_editor_entity_at(
- math.Vector3(512.0, 512.0, 34.0), reflection_probe_name)
+ reflection_probe_entity = EditorEntity.create_editor_entity(AtomComponentProperties.reflection_probe())
Report.critical_result(Tests.reflection_probe_creation, reflection_probe_entity.exists())
# 2. Add a Reflection Probe component to Reflection Probe entity.
- reflection_probe_component = reflection_probe_entity.add_component(reflection_probe_name)
+ reflection_probe_component = reflection_probe_entity.add_component(AtomComponentProperties.reflection_probe())
Report.critical_result(
Tests.reflection_probe_component,
- reflection_probe_entity.has_component(reflection_probe_name))
+ reflection_probe_entity.has_component(AtomComponentProperties.reflection_probe()))
# 3. UNDO the entity creation and component addition.
# -> UNDO component addition.
@@ -139,18 +137,27 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
# 5. Verify Reflection Probe component not enabled.
Report.result(Tests.reflection_probe_disabled, not reflection_probe_component.is_enabled())
- # 6. Add Box Shape component since it is required by the Reflection Probe component.
- box_shape = "Box Shape"
- reflection_probe_entity.add_component(box_shape)
- Report.result(Tests.box_shape_component, reflection_probe_entity.has_component(box_shape))
+ # 6. Add Shape component since it is required by the Reflection Probe component.
+ for shape in AtomComponentProperties.reflection_probe('shapes'):
+ reflection_probe_entity.add_component(shape)
+ test_shape = (
+ f"Entity has a {shape} component",
+ f"Entity did not have a {shape} component")
+ Report.result(test_shape, reflection_probe_entity.has_component(shape))
- # 7. Verify Reflection Probe component is enabled.
- Report.result(Tests.reflection_probe_enabled, reflection_probe_component.is_enabled())
+ # 7. Check if required shape allows Reflection Probe to be enabled
+ Report.result(Tests.reflection_probe_enabled, reflection_probe_component.is_enabled())
+
+ # Undo to remove each added shape except the last one and verify Reflection Probe is not enabled.
+ if not (shape == AtomComponentProperties.reflection_probe('shapes')[-1]):
+ general.undo()
+ TestHelper.wait_for_condition(lambda: not reflection_probe_entity.has_component(shape), 1.0)
+ Report.result(Tests.reflection_probe_disabled, not reflection_probe_component.is_enabled())
# 8. Enter/Exit game mode.
- helper.enter_game_mode(Tests.enter_game_mode)
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
general.idle_wait_frames(1)
- helper.exit_game_mode(Tests.exit_game_mode)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
# 9. Test IsHidden.
reflection_probe_entity.set_visibility_state(False)
@@ -165,8 +172,9 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
render.EditorReflectionProbeBus(azlmbr.bus.Event, "BakeReflectionProbe", reflection_probe_entity.id)
Report.result(
Tests.reflection_map_generated,
- helper.wait_for_condition(
- lambda: reflection_probe_component.get_component_property_value("Cubemap|Baked Cubemap Path") != "",
+ TestHelper.wait_for_condition(
+ lambda: reflection_probe_component.get_component_property_value(
+ AtomComponentProperties.reflection_probe('Baked Cubemap Path')) != "",
20.0))
# 12. Delete Reflection Probe entity.
@@ -182,7 +190,7 @@ def AtomEditorComponents_ReflectionProbe_AddedToEntity():
Report.result(Tests.deletion_redo, not reflection_probe_entity.exists())
# 15. Look for errors or asserts.
- helper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ 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:
diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_SSAOAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_SSAOAdded.py
new file mode 100644
index 0000000000..15f40f8b70
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_SSAOAdded.py
@@ -0,0 +1,182 @@
+"""
+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:
+ creation_undo = (
+ "UNDO Entity creation success",
+ "UNDO Entity creation failed")
+ creation_redo = (
+ "REDO Entity creation success",
+ "REDO Entity creation failed")
+ ssao_creation = (
+ "SSAO Entity successfully created",
+ "SSAO Entity failed to be created")
+ ssao_component = (
+ "Entity has a SSAO component",
+ "Entity failed to find SSAO component")
+ ssao_disabled = (
+ "SSAO component disabled",
+ "SSAO component was not disabled.")
+ postfx_layer_component = (
+ "Entity has a PostFX Layer component",
+ "Entity did not have an PostFX Layer component")
+ ssao_enabled = (
+ "SSAO component enabled",
+ "SSAO component was not enabled.")
+ enter_game_mode = (
+ "Entered game mode",
+ "Failed to enter game mode")
+ exit_game_mode = (
+ "Exited game mode",
+ "Couldn't exit game mode")
+ is_visible = (
+ "Entity is visible",
+ "Entity was not visible")
+ is_hidden = (
+ "Entity is hidden",
+ "Entity was not hidden")
+ entity_deleted = (
+ "Entity deleted",
+ "Entity was not deleted")
+ deletion_undo = (
+ "UNDO deletion success",
+ "UNDO deletion failed")
+ deletion_redo = (
+ "REDO deletion success",
+ "REDO deletion failed")
+
+
+def AtomEditorComponents_SSAO_AddedToEntity():
+ """
+ Summary:
+ Tests the SSAO component can be added to an entity and has the expected functionality.
+ Screen Space Ambient Occlusion (SSAO) is a PostFX shadow lighting effect.
+
+ Test setup:
+ - Wait for Editor idle loop.
+ - Open the "Base" level.
+
+ Expected Behavior:
+ The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components.
+ Creation and deletion undo/redo should also work.
+
+ Test Steps:
+ 1) Create a SSAO entity with no components.
+ 2) Add SSAO component to SSAO entity.
+ 3) UNDO the entity creation and component addition.
+ 4) REDO the entity creation and component addition.
+ 5) Verify SSAO component not enabled.
+ 6) Add PostFX Layer component since it is required by the SSAO component.
+ 7) Verify SSAO component is enabled.
+ 8) Enter/Exit game mode.
+ 9) Test IsHidden.
+ 10) Test IsVisible.
+ 11) Delete SSAO entity.
+ 12) UNDO deletion.
+ 13) REDO deletion.
+ 14) Look for errors.
+
+ :return: None
+ """
+
+ import azlmbr.legacy.general as general
+
+ 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
+
+ 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")
+
+ # Test steps begin.
+ # 1. Create a SSAO entity with no components.
+ ssao_entity = EditorEntity.create_editor_entity(AtomComponentProperties.ssao())
+ Report.critical_result(Tests.ssao_creation, ssao_entity.exists())
+
+ # 2. Add SSAO component to SSAO entity.
+ ssao_component = ssao_entity.add_component(AtomComponentProperties.ssao())
+ Report.critical_result(
+ Tests.ssao_component,
+ ssao_entity.has_component(AtomComponentProperties.ssao()))
+ ssao_component.get_property_tree()
+ # 3. UNDO the entity creation and component addition.
+ # -> UNDO component addition.
+ general.undo()
+ # -> UNDO naming entity.
+ general.undo()
+ # -> UNDO selecting entity.
+ general.undo()
+ # -> UNDO entity creation.
+ general.undo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_undo, not ssao_entity.exists())
+
+ # 4. REDO the entity creation and component addition.
+ # -> REDO entity creation.
+ general.redo()
+ # -> REDO selecting entity.
+ general.redo()
+ # -> REDO naming entity.
+ general.redo()
+ # -> REDO component addition.
+ general.redo()
+ general.idle_wait_frames(1)
+ Report.result(Tests.creation_redo, ssao_entity.exists())
+
+ # 5. Verify SSAO component not enabled.
+ Report.result(Tests.ssao_disabled, not ssao_component.is_enabled())
+
+ # 6. Add PostFX Layer component since it is required by the SSAO component.
+ ssao_entity.add_component(AtomComponentProperties.postfx_layer())
+ Report.result(
+ Tests.postfx_layer_component,
+ ssao_entity.has_component(AtomComponentProperties.postfx_layer()))
+
+ # 7. Verify SSAO component is enabled.
+ Report.result(Tests.ssao_enabled, ssao_component.is_enabled())
+
+ # 8. Enter/Exit game mode.
+ TestHelper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ TestHelper.exit_game_mode(Tests.exit_game_mode)
+
+ # 9. Test IsHidden.
+ ssao_entity.set_visibility_state(False)
+ Report.result(Tests.is_hidden, ssao_entity.is_hidden() is True)
+
+ # 10. Test IsVisible.
+ ssao_entity.set_visibility_state(True)
+ general.idle_wait_frames(1)
+ Report.result(Tests.is_visible, ssao_entity.is_visible() is True)
+
+ # 11. Delete SSAO entity.
+ ssao_entity.delete()
+ Report.result(Tests.entity_deleted, not ssao_entity.exists())
+
+ # 12. UNDO deletion.
+ general.undo()
+ Report.result(Tests.deletion_undo, ssao_entity.exists())
+
+ # 13. REDO deletion.
+ general.redo()
+ Report.result(Tests.deletion_redo, not ssao_entity.exists())
+
+ # 14. Look for errors and asserts.
+ TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
+ for error_info in error_tracer.errors:
+ Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
+ 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(AtomEditorComponents_SSAO_AddedToEntity)
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 3bf4c46a57..0000000000
--- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_GPUTest_BasicLevelSetup.py
+++ /dev/null
@@ -1,220 +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.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
-
-sys.path.append(os.path.join(azlmbr.paths.projectroot, "Gem", "PythonTests"))
-
-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, & saves the level.
- :return: None
- """
- 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)
-
- return True
-
- # Wait for Editor idle loop before executing Python hydra scripts.
- general.idle_enable(True)
-
- # Open the auto_test level.
- new_level_name = "auto_test" # Specified in class TestAllComponentsIndepthTests()
- heightmap_resolution = 512
- heightmap_meters_per_pixel = 1
- terrain_texture_resolution = 412
- use_terrain = False
-
- # Return codes are ECreateLevelResult defined in CryEdit.h
- return_code = general.create_level_no_prompt(
- new_level_name, heightmap_resolution, heightmap_meters_per_pixel, terrain_texture_resolution, use_terrain)
- if return_code == 1:
- general.log(f"{new_level_name} level already exists")
- elif return_code == 2:
- general.log("Failed to create directory")
- elif return_code == 3:
- general.log("Directory length is too long")
- elif return_code != 0:
- general.log("Unknown error, failed to create level")
- else:
- general.log(f"{new_level_name} level created successfully")
-
- # Basic setup for newly created level.
- 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)
- 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)
- # Work around to add the correct Atom Mesh component
- 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("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)
-
- # 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
- )
- 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)
- # Work around to add the correct Atom Mesh component
- 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)
-
- # 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)
- azlmbr.camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
-
- # Save level, enter game mode, take screenshot, & exit game mode.
- general.save_level()
- 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 1c3e6226c1..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 = "auto_test"
-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/Blast/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Blast/TestSuite_Main.py
index dbc4a1a456..a047d09d29 100644
--- a/AutomatedTesting/Gem/PythonTests/Blast/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/Blast/TestSuite_Main.py
@@ -23,28 +23,28 @@ from base import TestAutomationBase
class TestAutomation(TestAutomationBase):
def test_ActorSplitsAfterCollision(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterCollision as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterRadialDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterRadialDamage as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterCapsuleDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterCapsuleDamage as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterImpactSpreadDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterImpactSpreadDamage as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterShearDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterShearDamage as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterTriangleDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterTriangleDamage as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ActorSplitsAfterStressDamage(self, request, workspace, editor, launcher_platform):
from .tests import Blast_ActorSplitsAfterStressDamage as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index d2b7075e22..800f347359 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -62,5 +62,8 @@ add_subdirectory(Terrain)
## AWS ##
add_subdirectory(AWS)
+## Multiplayer ##
+add_subdirectory(Multiplayer)
+
## Integration tests for editor testing framework ##
add_subdirectory(editor_test_testing)
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test.py
index ed677ea185..a8ca721cca 100755
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ComponentUpdateListProperty_test.py
@@ -51,5 +51,6 @@ class TestComponentAssetListAutomation(object):
editor,
"ComponentUpdateListProperty_test_case.py",
expected_lines=expected_lines,
- cfg_args=[level]
+ cfg_args=[level],
+ enable_prefab_system=False,
)
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ObjectManagerCommands_test_case.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ObjectManagerCommands_test_case.py
index 9a308ab9c1..28b49bb4cb 100755
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ObjectManagerCommands_test_case.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/ObjectManagerCommands_test_case.py
@@ -67,30 +67,6 @@ if (editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'GetCurrentLevelName'
if(general.get_num_selected() == 0):
print("clear_selection works")
- general.hide_all_objects()
-
- if(general.is_object_hidden(objs_list[1])):
- print("hide_all_objects works")
-
- general.unhide_object(objs_list[1])
-
- if not(general.is_object_hidden(objs_list[1])):
- print("unhide_object works")
-
- general.hide_object(objs_list[1])
-
- if(general.is_object_hidden(objs_list[1])):
- print("hide_object works")
-
- general.unhide_all_objects()
-
- general.freeze_object(objs_list[1])
-
- if(general.is_object_frozen(objs_list[1])):
- print("freeze_object works")
-
- general.unfreeze_object(objs_list[1])
-
position = general.get_position(objs_list[1])
px1, py1, pz1 = fetch_vector3_parts(position)
general.set_position(objs_list[1], px1 + 10, py1 - 4, pz1 + 3)
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt
index 90afee39bc..bd9740f60f 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/README.txt
@@ -26,9 +26,9 @@ INSTALL
It is recommended to set up these these tools with O3DE's CMake build commands.
Assuming CMake is already setup on your operating system, below are some sample build commands:
cd /path/to/od3e/
- mkdir windows_vs2019
- cd windows_vs2019
- cmake .. -G "Visual Studio 16 2019" -A x64 -T host=x64 -DLY_3RDPARTY_PATH="%3RDPARTYPATH%" -DLY_PROJECTS=AutomatedTesting
+ mkdir windows
+ cd windows
+ cmake .. -G "Visual Studio 16 2019" -DLY_PROJECTS=AutomatedTesting
To manually install the project in development mode using your own installed Python interpreter:
cd /path/to/od3e/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools
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 844f8de903..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:
"""
@@ -107,6 +114,19 @@ class EditorComponent:
return type_ids
+def convert_to_azvector3(xyz) -> azlmbr.math.Vector3:
+ """
+ Converts a vector3-like element into a azlmbr.math.Vector3
+ """
+ if isinstance(xyz, Tuple) or isinstance(xyz, List):
+ assert len(xyz) == 3, ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
+ return math.Vector3(float(xyz[0]), float(xyz[1]), float(xyz[2]))
+ elif isinstance(xyz, type(math.Vector3())):
+ return xyz
+ else:
+ raise ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
+
+
class EditorEntity:
"""
Entity class is used to create and interact with Editor Entities.
@@ -119,13 +139,15 @@ class EditorEntity:
def __init__(self, id: azlmbr.entity.EntityId):
self.id: azlmbr.entity.EntityId = id
+ self.components: List[EditorComponent] = []
# 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])
@@ -133,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()
@@ -183,15 +205,6 @@ class EditorEntity:
:return: EditorEntity class object
"""
- def convert_to_azvector3(xyz) -> math.Vector3:
- if isinstance(xyz, Tuple) or isinstance(xyz, List):
- assert len(xyz) == 3, ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
- return math.Vector3(*xyz)
- elif isinstance(xyz, type(math.Vector3())):
- return xyz
- else:
- raise ValueError("vector must be a 3 element list/tuple or azlmbr.math.Vector3")
-
if parent_id is None:
parent_id = azlmbr.entity.EntityId()
@@ -206,7 +219,7 @@ class EditorEntity:
return entity
# Methods
- def set_name(self, entity_name: str):
+ def set_name(self, entity_name: str) -> None:
"""
Given entity_name, sets name to Entity
:param: entity_name: Name of the entity to set
@@ -275,7 +288,7 @@ class EditorEntity:
), f"Failure: Could not add component: '{new_comp.get_component_name()}' to entity: '{self.get_name()}'"
new_comp.id = add_component_outcome.GetValue()[0]
components.append(new_comp)
-
+ self.components.append(new_comp)
return components
def get_components_of_type(self, component_names: list) -> List[EditorComponent]:
@@ -324,7 +337,7 @@ class EditorEntity:
self.start_status = status
return status
- def set_start_status(self, desired_start_status: str):
+ def set_start_status(self, desired_start_status: str) -> None:
"""
Set an entity as active/inactive at beginning of runtime or it is editor-only,
given its entity id and the start status then return set success
@@ -382,18 +395,182 @@ class EditorEntity:
"""
return editor.EditorEntityInfoRequestBus(bus.Event, "IsVisible", self.id)
+ # World Transform Functions
+ def get_world_translation(self) -> azlmbr.math.Vector3:
+ """
+ Gets the world translation of the entity
+ """
+ return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
+
+ def set_world_translation(self, new_translation) -> None:
+ """
+ Sets the new world translation of the current entity
+ """
+ new_translation = convert_to_azvector3(new_translation)
+ azlmbr.components.TransformBus(azlmbr.bus.Event, "SetWorldTranslation", self.id, new_translation)
+
+ def get_world_rotation(self) -> azlmbr.math.Quaternion:
+ """
+ Gets the world rotation of the entity
+ """
+ return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldRotation", self.id)
+
+ def set_world_rotation(self, new_rotation):
+ """
+ Sets the new world rotation of the current entity
+ """
+ new_rotation = convert_to_azvector3(new_rotation)
+ azlmbr.components.TransformBus(azlmbr.bus.Event, "SetWorldRotation", self.id, new_rotation)
+
+ # Local Transform Functions
+ def get_local_uniform_scale(self) -> float:
+ """
+ Gets the local uniform scale of the entity
+ """
+ return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetLocalUniformScale", self.id)
+
def set_local_uniform_scale(self, scale_float) -> None:
"""
- Sets the "SetLocalUniformScale" value on the entity.
+ Sets the local uniform scale value(relative to the parent) on the entity.
:param scale_float: value for "SetLocalUniformScale" to set to.
:return: None
"""
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", self.id, scale_float)
- def set_local_rotation(self, vector3_rotation) -> None:
+ def get_local_rotation(self) -> azlmbr.math.Quaternion:
"""
- Sets the "SetLocalRotation" value on the entity.
- :param vector3_rotation: The math.Vector3 value to use for rotation on the entity (uses radians).
+ Gets the local rotation of the entity
+ """
+ return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetLocalRotation", self.id)
+
+ def set_local_rotation(self, new_rotation) -> None:
+ """
+ Sets the set the local rotation(relative to the parent) of the current entity.
+ :param new_rotation: The math.Vector3 value to use for rotation on the entity (uses radians).
:return: None
"""
- azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", self.id, vector3_rotation)
+ new_rotation = convert_to_azvector3(new_rotation)
+ azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", self.id, new_rotation)
+
+ def get_local_translation(self) -> azlmbr.math.Vector3:
+ """
+ Gets the local translation of the current entity.
+ :return: The math.Vector3 value of the local translation.
+ """
+ return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetLocalTranslation", self.id)
+
+ def set_local_translation(self, new_translation) -> None:
+ """
+ Sets the local translation(relative to the parent) of the current entity.
+ :param new_translation: The math.Vector3 value to use for translation on the entity.
+ :return: None
+ """
+ new_translation = convert_to_azvector3(new_translation)
+ azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalTranslation", self.id, new_translation)
+
+ # Use this only when prefab system is enabled as it will fail otherwise.
+ def focus_on_owning_prefab(self) -> None:
+ """
+ Focuses on the owning prefab instance of the given entity.
+ :param entity: The entity used to fetch the owning prefab to focus on.
+ """
+
+ assert self.id.isValid(), "A valid entity id is required to focus on its owning prefab."
+ focus_prefab_result = azlmbr.prefab.PrefabFocusPublicRequestBus(bus.Broadcast, "FocusOnOwningPrefab", self.id)
+ assert focus_prefab_result.IsSuccess(), f"Prefab operation 'FocusOnOwningPrefab' failed. Error: {focus_prefab_result.GetError()}"
+
+
+class EditorLevelEntity:
+ """
+ EditorLevel class used to add and fetch level components.
+ Level entity is a special entity that you do not create/destroy independently of larger systems of level creation.
+ This collects a number of staticmethods that do not rely on entityId since Level entity is found internally by
+ EditorLevelComponentAPIBus requests.
+ """
+
+ @staticmethod
+ def get_type_ids(component_names: list) -> list:
+ """
+ Used to get type ids of given components list for EntityType Level
+ :param: component_names: List of components to get type ids
+ :return: List of type ids of given components.
+ """
+ type_ids = editor.EditorComponentAPIBus(
+ bus.Broadcast, "FindComponentTypeIdsByEntityType", component_names, azlmbr.entity.EntityType().Level
+ )
+ return type_ids
+
+ @staticmethod
+ def add_component(component_name: str) -> EditorComponent:
+ """
+ Used to add new component to Level.
+ :param component_name: String of component name to add.
+ :return: Component object of newly added component.
+ """
+ component = EditorLevelEntity.add_components([component_name])[0]
+ return component
+
+ @staticmethod
+ def add_components(component_names: list) -> List[EditorComponent]:
+ """
+ Used to add multiple components
+ :param: component_names: List of components to add to level
+ :return: List of newly added components to the level
+ """
+ components = []
+ type_ids = EditorLevelEntity.get_type_ids(component_names)
+ for type_id in type_ids:
+ new_comp = EditorComponent()
+ new_comp.type_id = type_id
+ add_component_outcome = editor.EditorLevelComponentAPIBus(
+ bus.Broadcast, "AddComponentsOfType", [type_id]
+ )
+ assert (
+ add_component_outcome.IsSuccess()
+ ), f"Failure: Could not add component: '{new_comp.get_component_name()}' to level"
+ new_comp.id = add_component_outcome.GetValue()[0]
+ components.append(new_comp)
+ return components
+
+ @staticmethod
+ def get_components_of_type(component_names: list) -> List[EditorComponent]:
+ """
+ Used to get components of type component_name that already exists on the level
+ :param component_names: List of names of components to check
+ :return: List of Level Component objects of given component name
+ """
+ component_list = []
+ type_ids = EditorLevelEntity.get_type_ids(component_names)
+ for type_id in type_ids:
+ component = EditorComponent()
+ component.type_id = type_id
+ get_component_of_type_outcome = editor.EditorLevelComponentAPIBus(
+ bus.Broadcast, "GetComponentOfType", type_id
+ )
+ assert (
+ get_component_of_type_outcome.IsSuccess()
+ ), f"Failure: Level does not have component:'{component.get_component_name()}'"
+ component.id = get_component_of_type_outcome.GetValue()
+ component_list.append(component)
+
+ return component_list
+
+ @staticmethod
+ def has_component(component_name: str) -> bool:
+ """
+ Used to verify if the level has the specified component
+ :param component_name: Name of component to check for
+ :return: True, if level has specified component. Else, False
+ """
+ type_ids = EditorLevelEntity.get_type_ids([component_name])
+ return editor.EditorLevelComponentAPIBus(bus.Broadcast, "HasComponentOfType", type_ids[0])
+
+ @staticmethod
+ def count_components_of_type(component_name: str) -> int:
+ """
+ Used to get a count of the specified level component attached to the level
+ :param component_name: Name of component to check for
+ :return: integer count of occurences of level component attached to level or zero if none are present
+ """
+ type_ids = EditorLevelEntity.get_type_ids([component_name])
+ return editor.EditorLevelComponentAPIBus(bus.Broadcast, "CountComponentsOfType", type_ids[0])
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/hydra_test_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py
index 510d1b1149..ee36a640f0 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py
@@ -29,7 +29,7 @@ def teardown_editor(editor):
def launch_and_validate_results(request, test_directory, editor, editor_script, expected_lines, unexpected_lines=[],
halt_on_unexpected=False, run_python="--runpythontest", auto_test_mode=True, null_renderer=True, cfg_args=[],
- timeout=300, log_file_name="Editor.log"):
+ timeout=300, log_file_name="Editor.log", enable_prefab_system=True):
"""
Runs the Editor with the specified script, and monitors for expected log lines.
:param request: Special fixture providing information of the requesting test function.
@@ -45,17 +45,22 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
:param cfg_args: Additional arguments for CFG, such as LevelName.
:param timeout: Length of time for test to run. Default is 60.
:param log_file_name: Name of the log file created by the editor. Defaults to 'Editor.log'
+ :param enable_prefab_system: Flag to determine whether to use new prefab system or use deprecated slice system. Defaults to True.
"""
test_case = os.path.join(test_directory, editor_script)
request.addfinalizer(lambda: teardown_editor(editor))
logger.debug("Running automated test: {}".format(editor_script))
editor.args.extend(["--skipWelcomeScreenDialog", "--regset=/Amazon/Settings/EnableSourceControl=false",
- "--regset=/Amazon/Preferences/EnablePrefabSystem=false", run_python, test_case,
+ run_python, test_case,
f"--pythontestcase={request.node.name}", "--runpythonargs", " ".join(cfg_args)])
if auto_test_mode:
editor.args.extend(["--autotest_mode"])
if null_renderer:
editor.args.extend(["-rhi=Null"])
+ if enable_prefab_system:
+ editor.args.extend(["--regset=/Amazon/Preferences/EnablePrefabSystem=true"])
+ else:
+ editor.args.extend(["--regset=/Amazon/Preferences/EnablePrefabSystem=false"])
with editor.start():
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py
index 10a6ab1ef4..76c2a42c0a 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/prefab_utils.py
@@ -138,6 +138,14 @@ class PrefabInstance:
self.container_entity = reparented_container_entity
current_instance_prefab.instances.add(self)
+ def get_direct_child_entities(self):
+ """
+ Returns the entities only contained in the current prefab instance.
+ This function does not return entities contained in other child instances
+ """
+ return self.container_entity.get_children()
+
+
# This is a helper class which contains some of the useful information about a prefab template.
class Prefab:
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 1b094b1cfa..f277148bc8 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
@@ -14,7 +14,10 @@ from typing import Callable, Tuple
import azlmbr
import azlmbr.legacy.general as general
+import azlmbr.multiplayer as multiplayer
import azlmbr.debug
+import ly_test_tools.environment.waiter as waiter
+import ly_test_tools.environment.process_utils as process_utils
class FailFast(Exception):
@@ -31,6 +34,38 @@ class TestHelper:
# JIRA: SPEC-2880
# general.idle_wait_frames(1)
+ @staticmethod
+ def create_level(level_name: str) -> bool:
+ """
+ :param level_name: The name of the level to be created
+ :return: True if ECreateLevelResult returns 0, False otherwise with logging to report reason
+ """
+ Report.info(f"Creating level {level_name}")
+
+ # Use these hardcoded values to pass expected values for old terrain system until new create_level API is
+ # available
+ heightmap_resolution = 1024
+ heightmap_meters_per_pixel = 1
+ terrain_texture_resolution = 4096
+ use_terrain = False
+
+ result = general.create_level_no_prompt(level_name, heightmap_resolution, heightmap_meters_per_pixel,
+ terrain_texture_resolution, use_terrain)
+
+ # Result codes are ECreateLevelResult defined in CryEdit.h
+ if result == 1:
+ Report.info(f"{level_name} level already exists")
+ elif result == 2:
+ Report.info("Failed to create directory")
+ elif result == 3:
+ Report.info("Directory length is too long")
+ elif result != 0:
+ Report.info("Unknown error, failed to create level")
+ else:
+ Report.info(f"{level_name} level created successfully")
+
+ return result == 0
+
@staticmethod
def open_level(directory : str, level : str):
# type: (str, str) -> None
@@ -53,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.
@@ -66,6 +100,55 @@ class TestHelper:
TestHelper.wait_for_condition(lambda : general.is_in_game_mode(), 1.0)
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) -> 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"
+
+ :return: None
+ """
+
+ # looks for an expected line in a list of tracers lines
+ # lines: the tracer list of lines to search. options are section_tracer.warnings, section_tracer.errors, section_tracer.asserts, section_tracer.prints
+ # return: true if the line is found, otherwise false
+ def find_expected_line(expected_line, lines):
+ found_lines = [printInfo.message.strip() for printInfo in lines]
+ return expected_line in found_lines
+
+ def wait_for_critical_expected_line(expected_line, lines, time_out):
+ TestHelper.wait_for_condition(lambda : find_expected_line(expected_line, lines), time_out)
+ Report.critical_result(("Found expected line: " + expected_line, "Failed to find expected line: " + expected_line), find_expected_line(expected_line, lines))
+
+ def wait_for_critical_unexpected_line(unexpected_line, lines, time_out):
+ TestHelper.wait_for_condition(lambda : find_expected_line(unexpected_line, lines), time_out)
+ Report.critical_result(("Unexpected line not found: " + unexpected_line, "Unexpected line found: " + unexpected_line), not find_expected_line(unexpected_line, lines))
+
+
+ Report.info("Entering game mode")
+ if sv_default_player_spawn_asset :
+ general.set_cvar("sv_defaultPlayerSpawnAsset", sv_default_player_spawn_asset)
+
+ with Tracer() as section_tracer:
+ # enter game-mode.
+ # game-mode in multiplayer will also launch ServerLauncher.exe and connect to the editor
+ multiplayer.PythonEditorFuncs_enter_game_mode()
+
+ # make sure the server launcher binary exists
+ wait_for_critical_unexpected_line("LaunchEditorServer failed! The ServerLauncher binary is missing!", section_tracer.errors, 0.5)
+
+ # make sure the server launcher is running
+ waiter.wait_for(lambda: process_utils.process_exists("AutomatedTesting.ServerLauncher", ignore_extensions=True), timeout=5.0, exc=AssertionError("AutomatedTesting.ServerLauncher has NOT launched!"), interval=1.0)
+
+ # make sure the editor connects to the editor-server and sends the level data packet
+ wait_for_critical_expected_line("Editor is sending the editor-server the level data packet.", section_tracer.prints, 5.0)
+
+ # make sure the editor finally connects to the editor-server network simulation
+ wait_for_critical_expected_line("Editor-server ready. Editor has successfully connected to the editor-server's network simulation.", section_tracer.prints, 5.0)
+
+ TestHelper.wait_for_condition(lambda : multiplayer.PythonEditorFuncs_is_in_game_mode(), 5.0)
+ Report.critical_result(msgtuple_success_fail, multiplayer.PythonEditorFuncs_is_in_game_mode())
+
@staticmethod
def exit_game_mode(msgtuple_success_fail : Tuple[str, str]):
# type: (tuple) -> None
diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt
new file mode 100644
index 0000000000..367de4da9a
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt
@@ -0,0 +1,23 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+ ly_add_pytest(
+ NAME AutomatedTesting::MultiplayerTests_Sandbox
+ TEST_SUITE sandbox
+ TEST_SERIAL
+ PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
+ RUNTIME_DEPENDENCIES
+ Legacy::Editor
+ AZ::AssetProcessor
+ AutomatedTesting.Assets
+ AutomatedTesting.ServerLauncher
+ COMPONENT
+ Multiplayer
+ )
+endif()
diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Main.py
new file mode 100644
index 0000000000..450c760786
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Main.py
@@ -0,0 +1,28 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+
+"""
+
+# This suite consists of all test cases that are under development and have not been verified yet.
+# Once they are verified, please move them to TestSuite_Active.py
+
+import pytest
+import os
+import sys
+
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
+
+from base import TestAutomationBase
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+class TestAutomation(TestAutomationBase):
+ def _run_prefab_test(self, request, workspace, editor, test_module, batch_mode=True, autotest_mode=True):
+ self._run_test(request, workspace, editor, test_module,
+ batch_mode=batch_mode,
+ autotest_mode=autotest_mode)
+
diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py
new file mode 100644
index 0000000000..8f50d4d36d
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py
@@ -0,0 +1,34 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+
+"""
+
+# This suite consists of all test cases that are under development and have not been verified yet.
+# Once they are verified, please move them to TestSuite_Active.py
+
+import pytest
+import os
+import sys
+
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
+
+from base import TestAutomationBase
+
+@pytest.mark.SUITE_sandbox
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+class TestAutomation(TestAutomationBase):
+ def _run_prefab_test(self, request, workspace, editor, test_module, batch_mode=True, autotest_mode=True):
+ self._run_test(request, workspace, editor, test_module,
+ batch_mode=batch_mode,
+ autotest_mode=autotest_mode)
+
+ ## Seems to be flaky, need to investigate
+ def test_Multiplayer_AutoComponent_NetworkInput(self, request, workspace, editor, launcher_platform):
+ from .tests import Multiplayer_AutoComponent_NetworkInput as test_module
+ self._run_prefab_test(request, workspace, editor, test_module)
+
diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/__init__.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/__init__.py
new file mode 100644
index 0000000000..f5193b300e
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/__init__.py
@@ -0,0 +1,6 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/tests/Multiplayer_AutoComponent_NetworkInput.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/tests/Multiplayer_AutoComponent_NetworkInput.py
new file mode 100644
index 0000000000..7b56213313
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/tests/Multiplayer_AutoComponent_NetworkInput.py
@@ -0,0 +1,115 @@
+"""
+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
+"""
+
+
+# Test Case Title : Check that network input can be created, received by the authority, and processed
+
+
+# fmt: off
+class Tests():
+ enter_game_mode = ("Entered game mode", "Failed to enter game mode")
+ exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
+ find_network_player = ("Found network player", "Couldn't find network player")
+ found_lines = ("Expected log lines were found", "Expected log lines were not found")
+ found_unexpected_lines = ("Unexpected log lines were not found", "Unexpected log lines were found")
+# fmt: on
+
+
+def Multiplayer_AutoComponent_NetworkInput():
+ r"""
+ Summary:
+ Runs a test to make sure that network input can be sent from the autonomous player, received by the authority, and processed
+
+ Level Description:
+ - Dynamic
+ 1. Although the level is empty, when the server and editor connect the server will spawn and replicate the player network prefab.
+ a. The player network prefab has a NetworkTestPlayerComponent.AutoComponent and a script canvas attached which will listen for the CreateInput and ProcessInput events.
+ Print logs occur upon triggering the CreateInput and ProcessInput events along with their values; we are testing to make sure the expected events are values are recieved.
+ - Static
+ 1. This is an empty level. All the logic occurs on the Player.network.spawnable (see the above Dynamic description)
+
+
+ Expected Outcome:
+ We should see editor logs stating that network input has been created and processed.
+ However, if the script receives unexpected values for the Process event we will see print logs for bad data as well.
+
+ :return:
+ """
+ import azlmbr.legacy.general as general
+ from editor_python_test_tools.utils import Report
+ from editor_python_test_tools.utils import Tracer
+
+ from editor_python_test_tools.utils import TestHelper as helper
+ from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
+
+
+ def find_expected_line(expected_line):
+ found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints]
+ return expected_line in found_lines
+
+ def find_unexpected_line(expected_line):
+ return not find_expected_line(expected_line)
+
+ unexpected_lines = [
+ 'AutoComponent_NetworkInput received bad fwdback!',
+ 'AutoComponent_NetworkInput received bad leftright!',
+
+ ]
+ expected_lines = [
+ 'AutoComponent_NetworkInput ProcessInput called!',
+ 'AutoComponent_NetworkInput CreateInput called!',
+ ]
+
+ expected_lines_server = [
+ '(Script) - AutoComponent_NetworkInput ProcessInput called!',
+ ]
+
+ level_name = "AutoComponent_NetworkInput"
+ player_prefab_name = "Player"
+ player_prefab_path = f"levels/multiplayer/{level_name}/{player_prefab_name}.network.spawnable"
+
+ helper.init_idle()
+
+
+ # 1) Open Level
+ helper.open_level("Multiplayer", level_name)
+
+ with Tracer() as section_tracer:
+ # 2) Enter game mode
+ helper.multiplayer_enter_game_mode(Tests.enter_game_mode, player_prefab_path.lower())
+
+ # 3) Make sure the network player was spawned
+ player_id = general.find_game_entity(player_prefab_name)
+ Report.critical_result(Tests.find_network_player, player_id.IsValid())
+
+ # 4) Check the editor logs for expected and unexpected log output
+ EXPECTEDLINE_WAIT_TIME_SECONDS = 1.0
+ for expected_line in expected_lines :
+ helper.wait_for_condition(lambda: find_expected_line(expected_line), EXPECTEDLINE_WAIT_TIME_SECONDS)
+ Report.result(Tests.found_lines, find_expected_line(expected_line))
+
+ general.idle_wait_frames(1)
+ for unexpected_line in unexpected_lines :
+ Report.result(Tests.found_unexpected_lines, find_unexpected_line(unexpected_line))
+
+ # 5) Check the ServerLauncher logs for expected log output
+ # Since the editor has started a server launcher, the RemoteConsole with the default port=4600 will automatically be able to read the server logs
+ server_console = RemoteConsole()
+ server_console.start()
+ for line in expected_lines_server:
+ assert server_console.expect_log_line(line, EXPECTEDLINE_WAIT_TIME_SECONDS), f"Expected line not found: {line}"
+ server_console.stop()
+
+
+ # Exit game mode
+ helper.exit_game_mode(Tests.exit_game_mode)
+
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(Multiplayer_AutoComponent_NetworkInput)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_InDevelopment.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_InDevelopment.py
index 9e3a9cb4ff..09d8f5635f 100755
--- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_InDevelopment.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_InDevelopment.py
@@ -26,158 +26,158 @@ class TestAutomation(TestAutomationBase):
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnRagdollBones")
def test_Material_LibraryCrudOperationsReflectOnRagdollBones(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnRagdollBones as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Material_RagdollBones(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_RagdollBones as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c15308221_material_componentsinsyncwithlibrary.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_ComponentsInSyncWithLibrary")
def test_Material_ComponentsInSyncWithLibrary(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_ComponentsInSyncWithLibrary as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# BUG: LY-107723")
def test_ScriptCanvas_SetKinematicTargetTransform(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_SetKinematicTargetTransform as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
@fm.file_revert("c4925579_material_addmodifydeleteonterrain.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnTerrain")
def test_Material_LibraryCrudOperationsReflectOnTerrain(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnTerrain as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
def test_Terrain_TerrainTexturePainterWorks(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_TerrainTexturePainterWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
def test_Material_CanBeAssignedToTerrain(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_CanBeAssignedToTerrain as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
def test_Material_DefaultLibraryConsistentOnAllFeatures(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultLibraryConsistentOnAllFeatures as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Failing, PhysXTerrain
@fm.file_revert("all_ones_1.physmaterial", r"AutomatedTesting\Levels\Physics\Material_DefaultMaterialLibraryChangesWork")
@fm.file_override("default.physxconfiguration", "Material_DefaultMaterialLibraryChangesWork.physxconfiguration", "AutomatedTesting")
def test_Material_DefaultMaterialLibraryChangesWork(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultMaterialLibraryChangesWork as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_SameCollisionGroupSameLayerCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_SameCollisionGroupSameLayerCollide as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Ragdoll_OldRagdollSerializationNoErrors(self, request, workspace, editor, launcher_platform):
from .tests.ragdoll import Ragdoll_OldRagdollSerializationNoErrors as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_override("default.physxconfiguration", "ScriptCanvas_OverlapNode.physxconfiguration")
def test_ScriptCanvas_OverlapNode(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_OverlapNode as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Material_StaticFriction(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_StaticFriction as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c4888315_material_addmodifydeleteoncollider.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCollider")
def test_Material_LibraryCrudOperationsReflectOnCollider(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCollider as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c15563573_material_addmodifydeleteoncharactercontroller.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCharacterController")
def test_Material_LibraryCrudOperationsReflectOnCharacterController(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCharacterController as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c4888315_material_addmodifydeleteoncollider.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCollider")
def test_Material_LibraryCrudOperationsReflectOnCollider(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCollider as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c15563573_material_addmodifydeleteoncharactercontroller.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCharacterController")
def test_Material_LibraryCrudOperationsReflectOnCharacterController(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryCrudOperationsReflectOnCharacterController as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("c4044455_material_librarychangesinstantly.physmaterial",
r"AutomatedTesting\Levels\Physics\C4044455_Material_LibraryChangesInstantly")
def test_Material_LibraryChangesReflectInstantly(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryChangesReflectInstantly as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@fm.file_revert("Material_LibraryUpdatedAcrossLevels.physmaterial",
r"AutomatedTesting\Levels\Physics\Material_LibraryUpdatedAcrossLevels")
def test_Material_LibraryUpdatedAcrossLevels(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryUpdatedAcrossLevels as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RigidBody_LinearDampingAffectsMotion(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_LinearDampingAffectsMotion as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_CollisionAgainstRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_CollisionAgainstRigidBody as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeCollider_CylinderShapeCollides(self, request, workspace, editor, launcher_platform):
from .tests.collider import ShapeCollider_CylinderShapeCollides as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Physics_WorldBodyBusWorksOnEditorComponents(self, request, workspace, editor, launcher_platform):
from .tests import Physics_WorldBodyBusWorksOnEditorComponents as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_PxMeshErrorIfNoMesh(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshErrorIfNoMesh as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_ImpulsesBoxShapedRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ImpulsesBoxShapedRigidBody as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_SpawnSecondTerrainComponentWarning(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_SpawnSecondTerrainComponentWarning as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_AddPhysTerrainComponent(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_AddPhysTerrainComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_CanAddMultipleTerrainComponents(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_CanAddMultipleTerrainComponents as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_MultipleTerrainComponentsWarning(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_MultipleTerrainComponentsWarning as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_MultipleTerrainComponentsWarning(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_MultipleTerrainComponentsWarning as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_HighValuesDirectionAxesWorkWithNoError(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_HighValuesDirectionAxesWorkWithNoError as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Terrain_MultipleResolutionsValid(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_MultipleResolutionsValid as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_SmallMagnitudeDeviationOnLargeForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SmallMagnitudeDeviationOnLargeForces as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py
index b64fbb5656..07ae5f6ca0 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py
@@ -30,33 +30,33 @@ class TestAutomation(TestAutomationBase):
def test_RigidBody_EnablingGravityWorksUsingNotificationsPoC(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_LocalSpaceForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_LocalSpaceForceOnRigidBodies as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_DynamicFriction.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_DynamicFriction(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DynamicFriction as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_SameCollisionGroupDiffLayersCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_SameCollisionGroupDiffLayersCollide as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_CharacterController_SwitchLevels(self, request, workspace, editor, launcher_platform):
from .tests.character_controller import CharacterController_SwitchLevels as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Ragdoll_AddPhysxRagdollComponentWorks(self, request, workspace, editor, launcher_platform):
from .tests.ragdoll import Ragdoll_AddPhysxRagdollComponentWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_MultipleRaycastNode(self, request, workspace, editor, launcher_platform):
@@ -64,31 +64,43 @@ class TestAutomation(TestAutomationBase):
# Fixme: This test previously relied on unexpected lines log reading with is now not supported.
# Now the log reading must be done inside the test, preferably with the Tracer() utility
# unexpected_lines = ["Assert"] + test_module.Lines.unexpected
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_DiffCollisionGroupDiffCollidingLayersNotCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_DiffCollisionGroupDiffCollidingLayersNotCollide as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_HingeLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeLeadFollowerCollide as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_PxMeshConvexMeshCollides(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshConvexMeshCollides as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_CylinderShapeCollides(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_CylinderShapeCollides as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_C15425929_Undo_Redo(self, request, workspace, editor, launcher_platform):
from .tests import Physics_UndoRedoWorksOnEntityWithPhysComponents as test_module
- self._run_test(request, workspace, editor, test_module)
\ No newline at end of file
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+
+ @pytest.mark.GROUP_tick
+ @pytest.mark.xfail(reason="Test still under development.")
+ def test_Tick_InterpolatedRigidBodyMotionIsSmooth(self, request, workspace, editor, launcher_platform):
+ from .tests.tick import Tick_InterpolatedRigidBodyMotionIsSmooth as test_module
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+
+ @pytest.mark.GROUP_tick
+ @pytest.mark.xfail(reason="Test still under development.")
+ def test_Tick_CharacterGameplayComponentMotionIsSmooth(self, request, workspace, editor, launcher_platform):
+ from .tests.tick import Tick_CharacterGameplayComponentMotionIsSmooth as test_module
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py
index 63d3b58249..b25b4340e8 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main_Optimized.py
@@ -53,6 +53,24 @@ class EditorSingleTest_WithFileOverrides(EditorSingleTest):
for f in original_file_list:
fm._restore_file(f, file_list[f])
+@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
+@pytest.mark.SUITE_main
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+class TestAutomationWithPrefabSystemEnabled(EditorTestSuite):
+
+ @staticmethod
+ def get_number_parallel_editors():
+ return 16
+
+ class C4982801_PhysXColliderShape_CanBeSelected(EditorSharedTest):
+ from .tests.collider import Collider_BoxShapeEditing as test_module
+
+ class C4982800_PhysXColliderShape_CanBeSelected(EditorSharedTest):
+ from .tests.collider import Collider_SphereShapeEditing as test_module
+
+ class C4982802_PhysXColliderShape_CanBeSelected(EditorSharedTest):
+ from .tests.collider import Collider_CapsuleShapeEditing as test_module
@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
@pytest.mark.SUITE_main
@@ -60,6 +78,8 @@ class EditorSingleTest_WithFileOverrides(EditorSingleTest):
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
+ enable_prefab_system = False
+
@staticmethod
def get_number_parallel_editors():
return 16
@@ -286,15 +306,6 @@ class TestAutomation(EditorTestSuite):
class C19723164_ShapeCollider_WontCrashEditor(EditorSharedTest):
from .tests.shape_collider import ShapeCollider_LargeNumberOfShapeCollidersWontCrashEditor as test_module
- class C4982800_PhysXColliderShape_CanBeSelected(EditorSharedTest):
- from .tests.collider import Collider_SphereShapeEditting as test_module
-
- class C4982801_PhysXColliderShape_CanBeSelected(EditorSharedTest):
- from .tests.collider import Collider_BoxShapeEditting as test_module
-
- class C4982802_PhysXColliderShape_CanBeSelected(EditorSharedTest):
- from .tests.collider import Collider_CapsuleShapeEditting as test_module
-
class C12905528_ForceRegion_WithNonTriggerCollider(EditorSharedTest):
from .tests.force_region import ForceRegion_WithNonTriggerColliderWarning as test_module
# Fixme: expected_lines = ["[Warning] (PhysX Force Region) - Please ensure collider component marked as trigger exists in entity"]
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py
index e5dd9adbb9..6daf852708 100755
--- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py
@@ -31,223 +31,223 @@ class TestAutomation(TestAutomationBase):
@revert_physics_config
def test_Terrain_NoPhysTerrainComponentNoCollision(self, request, workspace, editor, launcher_platform):
from .tests.terrain import Terrain_NoPhysTerrainComponentNoCollision as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_InitialLinearVelocity(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_InitialLinearVelocity as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_StartGravityEnabledWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_StartGravityEnabledWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_KinematicModeWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_KinematicModeWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_LinearDampingForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_LinearDampingForceOnRigidBodies as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SimpleDragForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SimpleDragForceOnRigidBodies as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_CapsuleShapedForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_CapsuleShapedForce as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ImpulsesCapsuleShapedRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ImpulsesCapsuleShapedRigidBody as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_MomentOfInertiaManualSetting(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_MomentOfInertiaManualSetting as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_COM_ManualSettingWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_COM_ManualSettingWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_AddRigidBodyComponent(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_AddRigidBodyComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SplineForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SplineForceOnRigidBodies as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_RestitutionCombine.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_RestitutionCombine(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_RestitutionCombine as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_FrictionCombine.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_FrictionCombine(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_FrictionCombine as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_ColliderPositionOffset(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_ColliderPositionOffset as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_AngularDampingAffectsRotation(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_AngularDampingAffectsRotation as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether(self, request, workspace, editor, launcher_platform):
from .tests import Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_MultipleForcesInSameComponentCombineForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_MultipleForcesInSameComponentCombineForces as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ImpulsesPxMeshShapedRigidBody(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ImpulsesPxMeshShapedRigidBody as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_TriggerEvents(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_TriggerEvents as test_module
# FIXME: expected_lines = test_module.LogLines.expected_lines
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroPointForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroPointForceDoesNothing as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroWorldSpaceForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroWorldSpaceForceDoesNothing as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroLinearDampingDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroLinearDampingDoesNothing as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_MovingForceRegionChangesNetForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_MovingForceRegionChangesNetForce as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_CollisionEvents(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_CollisionEvents as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_DirectionHasNoAffectOnTotalForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_DirectionHasNoAffectOnTotalForce as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_StartAsleepWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_StartAsleepWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SliceFileInstantiates(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SliceFileInstantiates as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroLocalSpaceForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroLocalSpaceForceDoesNothing as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroSimpleDragForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroSimpleDragForceDoesNothing as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_COM_ComputingWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_COM_ComputingWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_MassDifferentValuesWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_MassDifferentValuesWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_RestitutionCombinePriorityOrder.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_RestitutionCombinePriorityOrder(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_RestitutionCombinePriorityOrder as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_SplineRegionWithModifiedTransform(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SplineRegionWithModifiedTransform as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_ShapeCast(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_ShapeCast as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_InitialAngularVelocity(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_InitialAngularVelocity as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ZeroSplineForceDoesNothing(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ZeroSplineForceDoesNothing as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Physics_DynamicSliceWithPhysNotSpawnsStaticSlice(self, request, workspace, editor, launcher_platform):
from .tests import Physics_DynamicSliceWithPhysNotSpawnsStaticSlice as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_PositionOffset(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_PositionOffset as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_FrictionCombinePriorityOrder.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_FrictionCombinePriorityOrder(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_FrictionCombinePriorityOrder as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(
reason="Something with the CryRenderer disabling is causing this test to fail now.")
@revert_physics_config
def test_Ragdoll_LevelSwitchDoesNotCrash(self, request, workspace, editor, launcher_platform):
from .tests.ragdoll import Ragdoll_LevelSwitchDoesNotCrash as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_MultipleComponentsCombineForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_MultipleComponentsCombineForces as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Marking the test as an expected failure due to sporadic failure on Automated Review: LYN-2580
# The test still runs, but a failure of the test doesn't result in the test run failing
@@ -258,102 +258,102 @@ class TestAutomation(TestAutomationBase):
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_PerFaceMaterialGetsCorrectMaterial(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_PerFaceMaterialGetsCorrectMaterial as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(
reason="This test will sometimes fail as the ball will continue to roll before the timeout is reached.")
@revert_physics_config
def test_RigidBody_SleepWhenBelowKineticThreshold(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_SleepWhenBelowKineticThreshold as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_COM_NotIncludesTriggerShapes(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_COM_NotIncludesTriggerShapes as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Material_NoEffectIfNoColliderShape(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_NoEffectIfNoColliderShape as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_TriggerPassThrough(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_TriggerPassThrough as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_SetGravityWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_SetGravityWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_CharacterController.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_CharacterController(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_CharacterController as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Material_EmptyLibraryUsesDefault(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_EmptyLibraryUsesDefault as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_NoQuiverOnHighLinearDampingForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_NoQuiverOnHighLinearDampingForce as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_RigidBody_ComputeInertiaWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_ComputeInertiaWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ScriptCanvas_PostPhysicsUpdate(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_PostPhysicsUpdate as test_module
# Fixme: unexpected_lines = ["Assert"] + test_module.Lines.unexpected
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_NoneCollisionGroupSameLayerNotCollide.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_NoneCollisionGroupSameLayerNotCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_NoneCollisionGroupSameLayerNotCollide as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_SameCollisionGroupSameCustomLayerCollide.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_SameCollisionGroupSameCustomLayerCollide(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_SameCollisionGroupSameCustomLayerCollide as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxdefaultsceneconfiguration.setreg','ScriptCanvas_PostUpdateEvent.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_ScriptCanvas_PostUpdateEvent(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_PostUpdateEvent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Material_Restitution.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Material_Restitution(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_Restitution as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxdefaultsceneconfiguration.setreg', 'ScriptCanvas_PreUpdateEvent.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_ScriptCanvas_PreUpdateEvent(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_PreUpdateEvent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_PxMeshShapedForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_PxMeshShapedForce as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# Marking the Test as expected to fail using the xfail decorator due to sporadic failure on Automated Review: SPEC-3146
# The test still runs, but a failure of the test doesn't result in the test run failing
@@ -361,173 +361,173 @@ class TestAutomation(TestAutomationBase):
@revert_physics_config
def test_RigidBody_MaxAngularVelocityWorks(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_MaxAngularVelocityWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_HingeSoftLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeSoftLimitsConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_BallSoftLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallSoftLimitsConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Joints_BallLeadFollowerCollide(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallLeadFollowerCollide as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_AddingNewGroupWorks.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_AddingNewGroupWorks(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_AddingNewGroupWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_InactiveWhenNoShapeComponent(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_InactiveWhenNoShapeComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_CheckDefaultShapeSettingIsPxMesh(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_CheckDefaultShapeSettingIsPxMesh as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_LargeNumberOfShapeCollidersWontCrashEditor(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_LargeNumberOfShapeCollidersWontCrashEditor as test_module
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
+
+ @revert_physics_config
+ def test_Collider_SphereShapeEditing(self, request, workspace, editor, launcher_platform):
+ from .tests.collider import Collider_SphereShapeEditing as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
- def test_Collider_SphereShapeEditting(self, request, workspace, editor, launcher_platform):
- from .tests.collider import Collider_SphereShapeEditting as test_module
+ def test_Collider_BoxShapeEditing(self, request, workspace, editor, launcher_platform):
+ from .tests.collider import Collider_BoxShapeEditing as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
- def test_Collider_BoxShapeEditting(self, request, workspace, editor, launcher_platform):
- from .tests.collider import Collider_BoxShapeEditting as test_module
- self._run_test(request, workspace, editor, test_module)
-
- @revert_physics_config
- def test_Collider_CapsuleShapeEditting(self, request, workspace, editor, launcher_platform):
- from .tests.collider import Collider_CapsuleShapeEditting as test_module
+ def test_Collider_CapsuleShapeEditing(self, request, workspace, editor, launcher_platform):
+ from .tests.collider import Collider_CapsuleShapeEditing as test_module
self._run_test(request, workspace, editor, test_module)
def test_ForceRegion_WithNonTriggerColliderWarning(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_WithNonTriggerColliderWarning as test_module
# Fixme: expected_lines = ["[Warning] (PhysX Force Region) - Please ensure collider component marked as trigger exists in entity"]
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_WorldSpaceForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_WorldSpaceForceOnRigidBodies as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_PointForceOnRigidBodies(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_PointForceOnRigidBodies as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_SphereShapedForce(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_SphereShapedForce as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ForceRegion_RotationalOffset(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_RotationalOffset as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Material_LibraryClearingAssignsDefault(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_LibraryClearingAssignsDefault as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_AddColliderComponent(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_AddColliderComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(
reason="This will fail due to this issue ATOM-15487.")
def test_Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_MultipleSurfaceSlots(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_MultipleSurfaceSlots as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RigidBody_EnablingGravityWorksPoC(self, request, workspace, editor, launcher_platform):
from .tests.rigid_body import RigidBody_EnablingGravityWorksPoC as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
@fm.file_override('physxsystemconfiguration.setreg','Collider_CollisionGroupsWorkflow.setreg_override',
'AutomatedTesting/Registry', search_subdirs=True)
def test_Collider_CollisionGroupsWorkflow(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_CollisionGroupsWorkflow as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Collider_ColliderRotationOffset(self, request, workspace, editor, launcher_platform):
from .tests.collider import Collider_ColliderRotationOffset as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ForceRegion_ParentChildForcesCombineForces(self, request, workspace, editor, launcher_platform):
from .tests.force_region import ForceRegion_ParentChildForcesCombineForces as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_ShapeCollider_CanBeAddedWitNoWarnings(self, request, workspace, editor, launcher_platform):
from .tests.shape_collider import ShapeCollider_CanBeAddedWitNoWarnings as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Physics_UndoRedoWorksOnEntityWithPhysComponents(self, request, workspace, editor, launcher_platform):
from .tests import Physics_UndoRedoWorksOnEntityWithPhysComponents as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_Fixed2BodiesConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_Fixed2BodiesConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_Hinge2BodiesConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_Hinge2BodiesConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_Ball2BodiesConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_Ball2BodiesConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_FixedBreakable(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_FixedBreakable as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_HingeBreakable(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeBreakable as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_BallBreakable(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallBreakable as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_HingeNoLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_HingeNoLimitsConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_BallNoLimitsConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_BallNoLimitsConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Joints_GlobalFrameConstrained(self, request, workspace, editor, launcher_platform):
from .tests.joints import Joints_GlobalFrameConstrained as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@revert_physics_config
def test_Material_DefaultLibraryUpdatedAcrossLevels(self, request, workspace, editor, launcher_platform):
@@ -537,7 +537,7 @@ class TestAutomation(TestAutomationBase):
search_subdirs=True)
def levels_before(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultLibraryUpdatedAcrossLevels_before as test_module_0
- self._run_test(request, workspace, editor, test_module_0)
+ self._run_test(request, workspace, editor, test_module_0, enable_prefab_system=False)
# File override replaces the previous physxconfiguration file with another where the only difference is the default material library
@fm.file_override("physxsystemconfiguration.setreg",
@@ -546,7 +546,7 @@ class TestAutomation(TestAutomationBase):
search_subdirs=True)
def levels_after(self, request, workspace, editor, launcher_platform):
from .tests.material import Material_DefaultLibraryUpdatedAcrossLevels_after as test_module_1
- self._run_test(request, workspace, editor, test_module_1)
+ self._run_test(request, workspace, editor, test_module_1, enable_prefab_system=False)
levels_before(self, request, workspace, editor, launcher_platform)
levels_after(self, request, workspace, editor, launcher_platform)
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Sandbox.py
index 81fdc747d5..9b104ccfcf 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Sandbox.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Sandbox.py
@@ -32,7 +32,7 @@ class TestAutomation(TestAutomationBase):
def test_ScriptCanvas_GetCollisionNameReturnsName(self, request, workspace, editor, launcher_platform):
from .tests.script_canvas import ScriptCanvas_GetCollisionNameReturnsName as test_module
# Fixme: expected_lines=["Layer Name: Right"]
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
## Seems to be flaky, need to investigate
def test_ScriptCanvas_GetCollisionNameReturnsNothingWhenHasToggledLayer(self, request, workspace, editor, launcher_platform):
@@ -42,4 +42,4 @@ class TestAutomation(TestAutomationBase):
# Fixme: for group in collision_groups:
# Fixme: unexpected_lines.append(f"GroupName: {group}")
# Fixme: expected_lines=["GroupName: "]
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Utils.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Utils.py
index 61c2816f50..3e00b684c0 100755
--- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Utils.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Utils.py
@@ -30,11 +30,11 @@ class TestUtils(TestAutomationBase):
expected_lines = []
unexpected_lines = ["Assert"]
- self._run_test(request, workspace, editor, physmaterial_editor_test_module, expected_lines, unexpected_lines)
+ self._run_test(request, workspace, editor, physmaterial_editor_test_module, expected_lines, unexpected_lines, enable_prefab_system=False)
def test_UtilTest_Tracer_PicksErrorsAndWarnings(self, request, workspace, launcher_platform, editor):
from .utils import UtilTest_Tracer_PicksErrorsAndWarnings as testcase_module
- self._run_test(request, workspace, editor, testcase_module, [], [])
+ self._run_test(request, workspace, editor, testcase_module, [], [], enable_prefab_system=False)
def test_FileManagement_FindingFiles(self, workspace, launcher_platform):
"""
@@ -263,4 +263,4 @@ class TestUtils(TestAutomationBase):
expected_lines = []
unexpected_lines = ["Assert"]
- self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines)
+ self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditting.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditing.py
similarity index 97%
rename from AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditting.py
rename to AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditing.py
index 68ff0b4edc..a6730c8559 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditting.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditing.py
@@ -19,7 +19,7 @@ class Tests():
# fmt: on
-def Collider_BoxShapeEditting():
+def Collider_BoxShapeEditing():
"""
Summary:
Adding PhysX Collider and Shape components to test entity, then attempting to modify the shape's dimensions
@@ -73,7 +73,7 @@ def Collider_BoxShapeEditting():
helper.init_idle()
# 1) Load the empty level
- helper.open_level("Physics", "Base")
+ helper.open_level("", "Base")
# 2) Create the test entity
test_entity = Entity.create_editor_entity("Test Entity")
@@ -102,4 +102,4 @@ def Collider_BoxShapeEditting():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(Collider_BoxShapeEditting)
+ Report.start_test(Collider_BoxShapeEditing)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditting.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditing.py
similarity index 97%
rename from AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditting.py
rename to AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditing.py
index 7df12c68f0..12435cc54a 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditting.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditing.py
@@ -19,7 +19,7 @@ class Tests():
# fmt: on
-def Collider_CapsuleShapeEditting():
+def Collider_CapsuleShapeEditing():
"""
Summary:
Adding PhysX Collider and Shape components to test entity, then attempting to modify the shape's dimensions
@@ -74,7 +74,7 @@ def Collider_CapsuleShapeEditting():
helper.init_idle()
# 1) Load the empty level
- helper.open_level("Physics", "Base")
+ helper.open_level("", "Base")
# 2) Create the test entity
test_entity = Entity.create_editor_entity("Test Entity")
@@ -102,4 +102,4 @@ def Collider_CapsuleShapeEditting():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(Collider_CapsuleShapeEditting)
+ Report.start_test(Collider_CapsuleShapeEditing)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SphereShapeEditting.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SphereShapeEditing.py
similarity index 96%
rename from AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SphereShapeEditting.py
rename to AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SphereShapeEditing.py
index bffd041d92..ef91235411 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SphereShapeEditting.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SphereShapeEditing.py
@@ -19,7 +19,7 @@ class Tests():
# fmt: on
-def Collider_SphereShapeEditting():
+def Collider_SphereShapeEditing():
"""
Summary:
Adding PhysX Collider and Shape components to test entity, then attempting to modify the shape's dimensions
@@ -57,7 +57,7 @@ def Collider_SphereShapeEditting():
helper.init_idle()
# 1) Load the empty level
- helper.open_level("Physics", "Base")
+ helper.open_level("", "Base")
# 2) Create the test entity
test_entity = Entity.create_editor_entity("Test Entity")
@@ -90,4 +90,4 @@ def Collider_SphereShapeEditting():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(Collider_SphereShapeEditting)
+ Report.start_test(Collider_SphereShapeEditing)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py
new file mode 100644
index 0000000000..fe718d7247
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py
@@ -0,0 +1,99 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+
+Test Case Title : Verify that an entity with a character gameplay component moves smoothly.
+"""
+
+
+# fmt: off
+class Tests():
+ create_entity = ("Created test entity", "Failed to create test entity")
+ character_controller_added = ("Added PhysX Character Controller component", "Failed to add PhysX Character Controller component")
+ character_gameplay_added = ("Added PhysX Character Gameplay component", "Failed to add PhysX Character Gameplay component")
+ enter_game_mode = ("Entered game mode", "Failed to enter game mode")
+ exit_game_mode = ("Exited game mode", "Failed to exit game mode")
+ character_motion_smooth = ("Character motion passed smoothness threshold", "Failed to meet smoothness threshold for character motion")
+# fmt: on
+
+
+def Tick_CharacterGameplayComponentMotionIsSmooth():
+ """
+ Summary:
+ Create entity with PhysX Character Controller and PhysX Character Gameplay components.
+ Verify that the motion of the character controller under gravity is smooth.
+
+ Expected Behavior:
+ 1) The motion of the character controller under gravity is a smooth curve, rather than an erratic/jittery movement.
+
+ Test Steps:
+ 1) Load the empty level
+ 2) Create an entity
+ 3) Add a PhysX Character Controller Component and PhysX Character Gameplay component
+ 4) Enter game mode and collect data for the character controller's z co-ordinate and the time values for a series of frames
+ 5) Check if the motion of the character controller was sufficiently smooth
+
+ :return: None
+ """
+ # imports
+ import os
+ import azlmbr.legacy.general as general
+ import azlmbr.math as math
+ from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity
+ from editor_python_test_tools.utils import Report
+ from editor_python_test_tools.utils import TestHelper as helper
+ from editor_python_test_tools.asset_utils import Asset
+ import numpy as np
+
+ # constants
+ COEFFICIENT_OF_DETERMINATION_THRESHOLD = 1 - 1e-4 # curves with values below this are not considered sufficiently smooth
+
+ helper.init_idle()
+ # 1) Load the empty level
+ helper.open_level("", "Base")
+
+ # 2) Create an entity
+ test_entity = Entity.create_editor_entity("test_entity")
+ Report.result(Tests.create_entity, test_entity.id.IsValid())
+
+ azlmbr.components.TransformBus(
+ azlmbr.bus.Event, "SetWorldTranslation", test_entity.id, math.Vector3(0.0, 0.0, 0.0))
+
+ # 3) Add character controller and character gameplay components
+ character_controller_component = test_entity.add_component("PhysX Character Controller")
+ Report.result(Tests.character_controller_added, test_entity.has_component("PhysX Character Controller"))
+ character_gameplay_component = test_entity.add_component("PhysX Character Gameplay")
+ Report.result(Tests.character_gameplay_added, test_entity.has_component("PhysX Character Gameplay"))
+
+ # 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames
+ t = []
+ z = []
+ helper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ game_entity_id = general.find_game_entity("test_entity")
+ for frame in range(100):
+ t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds())
+ z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id))
+ general.idle_wait_frames(1)
+ helper.exit_game_mode(Tests.exit_game_mode)
+
+ # 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth)
+ # normalize the t and z data
+ t = np.array(t) - np.mean(t)
+ z = np.array(z) - np.mean(z)
+ # fit a polynomial to the z vs t curve
+ fit = np.poly1d(np.polyfit(t, z, 4))
+ residual = fit(t) - z
+ # calculate the coefficient of determination (a measure of how closely the polynomial curve fits the data)
+ # if the coefficient is very close to 1, then the curve fits the data very well, suggesting that the rigid body motion is smooth
+ # if the coefficient is significantly less than 1, then the z values vary more erratically relative to the smooth curve,
+ # indicating that the motion of the rigid body is not smooth
+ coefficient_of_determination = (1 - np.sum(residual * residual) / np.sum(z * z))
+ Report.result(Tests.character_motion_smooth, bool(coefficient_of_determination > COEFFICIENT_OF_DETERMINATION_THRESHOLD))
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(Tick_CharacterGameplayComponentMotionIsSmooth)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py
new file mode 100644
index 0000000000..19e79355d9
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py
@@ -0,0 +1,98 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+
+Test Case Title : Verify that a rigid body with "Interpolate motion" option selected moves smoothly.
+"""
+
+
+# fmt: off
+class Tests():
+ create_entity = ("Created test entity", "Failed to create test entity")
+ rigid_body_added = ("Added PhysX Rigid Body component", "Failed to add PhysX Rigid Body component")
+ enter_game_mode = ("Entered game mode", "Failed to enter game mode")
+ exit_game_mode = ("Exited game mode", "Failed to exit game mode")
+ rigid_body_smooth = ("Rigid body motion passed smoothness threshold", "Failed to meet smoothness threshold for rigid body motion")
+# fmt: on
+
+
+def Tick_InterpolatedRigidBodyMotionIsSmooth():
+ """
+ Summary:
+ Create entity with PhysX Rigid Body component and turn on the Interpolate motion setting.
+ Verify that the position of the rigid body varies smoothly with time.
+
+ Expected Behavior:
+ 1) The motion of the rigid body under gravity is a smooth curve, rather than an erratic/jittery movement.
+
+ Test Steps:
+ 1) Load the empty level
+ 2) Create an entity
+ 3) Add rigid body component
+ 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames
+ 5) Check if the motion of the rigid body was sufficiently smooth
+
+ :return: None
+ """
+ # imports
+ import os
+ import azlmbr.legacy.general as general
+ import azlmbr.math as math
+ from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity
+ from editor_python_test_tools.utils import Report
+ from editor_python_test_tools.utils import TestHelper as helper
+ from editor_python_test_tools.asset_utils import Asset
+ import numpy as np
+
+ # constants
+ COEFFICIENT_OF_DETERMINATION_THRESHOLD = 1 - 1e-4 # curves with values below this are not considered sufficiently smooth
+
+ helper.init_idle()
+ # 1) Load the empty level
+ helper.open_level("", "Base")
+
+ # 2) Create an entity
+ test_entity = Entity.create_editor_entity("test_entity")
+ Report.result(Tests.create_entity, test_entity.id.IsValid())
+
+ azlmbr.components.TransformBus(
+ azlmbr.bus.Event, "SetWorldTranslation", test_entity.id, math.Vector3(0.0, 0.0, 0.0))
+
+ # 3) Add rigid body component
+ rigid_body_component = test_entity.add_component("PhysX Rigid Body")
+ rigid_body_component.set_component_property_value("Configuration|Interpolate motion", True)
+ azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetLinearDamping", test_entity.id, 0.0)
+ Report.result(Tests.rigid_body_added, test_entity.has_component("PhysX Rigid Body"))
+
+ # 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames
+ t = []
+ z = []
+ helper.enter_game_mode(Tests.enter_game_mode)
+ general.idle_wait_frames(1)
+ game_entity_id = general.find_game_entity("test_entity")
+ for frame in range(100):
+ t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds())
+ z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id))
+ general.idle_wait_frames(1)
+ helper.exit_game_mode(Tests.exit_game_mode)
+
+ # 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth)
+ # normalize the t and z data
+ t = np.array(t) - np.mean(t)
+ z = np.array(z) - np.mean(z)
+ # fit a polynomial to the z vs t curve
+ fit = np.poly1d(np.polyfit(t, z, 4))
+ residual = fit(t) - z
+ # calculate the coefficient of determination (a measure of how closely the polynomial curve fits the data)
+ # if the coefficient is very close to 1, then the curve fits the data very well, suggesting that the rigid body motion is smooth
+ # if the coefficient is significantly less than 1, then the z values vary more erratically relative to the smooth curve,
+ # indicating that the motion of the rigid body is not smooth
+ coefficient_of_determination = (1 - np.sum(residual * residual) / np.sum(z * z))
+ Report.result(Tests.rigid_body_smooth, bool(coefficient_of_determination > COEFFICIENT_OF_DETERMINATION_THRESHOLD))
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(Tick_InterpolatedRigidBodyMotionIsSmooth)
diff --git a/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py b/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py
index 22a41de4ea..03287d0542 100644
--- a/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py
+++ b/AutomatedTesting/Gem/PythonTests/Physics/utils/FileManagement.py
@@ -98,38 +98,32 @@ class FileManagement:
"""
file_map = FileManagement._load_file_map()
backup_path = FileManagement.backup_folder_path
- backup_file_name = "{}.bak".format(file_name)
- backup_file = os.path.join(backup_path, backup_file_name)
# If backup directory DNE, make one
if not os.path.exists(backup_path):
os.mkdir(backup_path)
- # If "traditional" backup file exists, delete it (myFile.txt.bak)
- if os.path.exists(backup_file):
- fs.delete([backup_file], True, False)
- # Find my next storage name (myFile_1.txt.bak)
- backup_storage_file_name = FileManagement._next_available_name(backup_file_name, file_map)
- if backup_storage_file_name is None:
+
+ # Find my next storage name (myFile_1.txt)
+ backup_file_name = FileManagement._next_available_name(file_name, file_map)
+ if backup_file_name is None:
# If _next_available_name returns None, we have backed up MAX_BACKUPS of files name [file_name]
raise Exception(
"FileManagement class ran out of backups per name. Max: {}".format(FileManagement.MAX_BACKUPS)
)
- backup_storage_file = os.path.join(backup_path, backup_storage_file_name)
+
+ # If this backup file already exists, delete it.
+ backup_storage_file = "{}.bak".format(os.path.normpath(os.path.join(backup_path, backup_file_name)))
if os.path.exists(backup_storage_file):
- # This file should not exists, but if it does it's about to get clobbered!
- fs.unlock_file(backup_storage_file)
- # Create "traditional" backup file (myFile.txt.bak)
- fs.create_backup(os.path.join(file_path, file_name), backup_path)
- # Copy "traditional" backup file into storage backup (myFile_1.txt.bak)
- FileManagement._copy_file(backup_file_name, backup_path, backup_storage_file_name, backup_path)
- fs.lock_file(backup_storage_file)
- # Delete "traditional" back up file
- fs.unlock_file(backup_file)
- fs.delete([backup_file], True, False)
+ fs.delete([backup_storage_file], True, False)
+
+ # Create backup file (myFile_1.txt.bak)
+ original_file = os.path.normpath(os.path.join(file_path, file_name))
+ fs.create_backup(original_file, backup_path, backup_file_name)
+
# Update file map with new file
- file_map[os.path.join(file_path, file_name)] = backup_storage_file_name
+ file_map[original_file] = backup_file_name
FileManagement._save_file_map(file_map)
# Unlock original file to get it ready to be edited by the test
- fs.unlock_file(os.path.join(file_path, file_name))
+ fs.unlock_file(original_file)
@staticmethod
def _restore_file(file_name, file_path):
@@ -143,20 +137,15 @@ class FileManagement:
"""
file_map = FileManagement._load_file_map()
backup_path = FileManagement.backup_folder_path
- src_file = os.path.join(file_path, file_name)
+ src_file = os.path.normpath(os.path.join(file_path, file_name))
if src_file in file_map:
- backup_file = os.path.join(backup_path, file_map[src_file])
- if os.path.exists(backup_file):
- fs.unlock_file(backup_file)
- fs.unlock_file(src_file)
- # Make temporary copy of backed up file to restore from
- temp_file = "{}.bak".format(file_name)
- FileManagement._copy_file(file_map[src_file], backup_path, temp_file, backup_path)
- fs.restore_backup(src_file, backup_path)
- fs.lock_file(src_file)
- # Delete backup file
- fs.delete([os.path.join(backup_path, temp_file)], True, False)
+ backup_file_name = file_map[src_file]
+ backup_file = "{}.bak".format(os.path.join(backup_path, backup_file_name))
+
+ fs.unlock_file(src_file)
+ if fs.restore_backup(src_file, backup_path, backup_file_name):
fs.delete([backup_file], True, False)
+
# Remove from file map
del file_map[src_file]
FileManagement._save_file_map(file_map)
@@ -218,6 +207,7 @@ class FileManagement:
src_file_path = os.path.join(src_path, src_file)
if os.path.exists(target_file_path):
fs.unlock_file(target_file_path)
+ os.makedirs(target_path, exist_ok=True)
shutil.copyfile(src_file_path, target_file_path)
@staticmethod
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.py b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py
index 5337f0669c..6e1f94d358 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/TestSuite_Main.py
@@ -12,7 +12,6 @@ import pytest
import os
import sys
-from ly_test_tools import LAUNCHERS
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
from base import TestAutomationBase
@@ -24,34 +23,49 @@ class TestAutomation(TestAutomationBase):
def _run_prefab_test(self, request, workspace, editor, test_module, batch_mode=True, autotest_mode=True):
self._run_test(request, workspace, editor, test_module,
- extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"],
batch_mode=batch_mode,
autotest_mode=autotest_mode)
- def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform):
- from .tests import PrefabLevel_OpensLevelWithEntities as test_module
+ def test_OpenLevel_ContainingTwoEntities(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.open_level import OpenLevel_ContainingTwoEntities as test_module
self._run_prefab_test(request, workspace, editor, test_module)
- def test_PrefabBasicWorkflow_CreatePrefab(self, request, workspace, editor, launcher_platform):
- from .tests import PrefabBasicWorkflow_CreatePrefab as test_module
+ def test_CreatePrefab_WithSingleEntity(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.create_prefab import CreatePrefab_WithSingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
- def test_PrefabBasicWorkflow_InstantiatePrefab(self, request, workspace, editor, launcher_platform):
- from .tests import PrefabBasicWorkflow_InstantiatePrefab as test_module
+ def test_InstantiatePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
- def test_PrefabBasicWorkflow_CreateAndDeletePrefab(self, request, workspace, editor, launcher_platform):
- from .tests import PrefabBasicWorkflow_CreateAndDeletePrefab as test_module
+ def test_DeletePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
- def test_PrefabBasicWorkflow_CreateAndReparentPrefab(self, request, workspace, editor, launcher_platform):
- from .tests import PrefabBasicWorkflow_CreateAndReparentPrefab as test_module
+ def test_ReparentPrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.reparent_prefab import ReparentPrefab_UnderAnotherPrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
- def test_PrefabBasicWorkflow_CreateReparentAndDetachPrefab(self, request, workspace, editor, launcher_platform):
- from .tests import PrefabBasicWorkflow_CreateReparentAndDetachPrefab as test_module
+ def test_DetachPrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.detach_prefab import DetachPrefab_UnderAnotherPrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
- def test_PrefabBasicWorkflow_CreateAndDuplicatePrefab(self, request, workspace, editor, launcher_platform):
- from .tests import PrefabBasicWorkflow_CreateAndDuplicatePrefab as test_module
+ def test_DuplicatePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module
self._run_prefab_test(request, workspace, editor, test_module)
+
+ def test_CreatePrefab_UnderAnEntity(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.create_prefab import CreatePrefab_UnderAnEntity as test_module
+ self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
+
+ def test_CreatePrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.create_prefab import CreatePrefab_UnderAnotherPrefab as test_module
+ self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
+
+ def test_DeleteEntity_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.delete_entity import DeleteEntity_UnderAnotherPrefab as test_module
+ self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
+
+ def test_DeleteEntity_UnderLevelPrefab(self, request, workspace, editor, launcher_platform):
+ from Prefab.tests.delete_entity import DeleteEntity_UnderLevelPrefab as test_module
+ self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/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/create_prefab/CreatePrefab_UnderAnEntity.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnEntity.py
new file mode 100644
index 0000000000..5033c1da9c
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnEntity.py
@@ -0,0 +1,52 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+def CreatePrefab_UnderAnEntity():
+ """
+ Test description:
+ - Creates two entities, parent and child. Child entity has Parent entity as its parent.
+ - Creates a prefab of the child entity.
+ Test is successful if the new instanced prefab of the child has the parent entity id
+ """
+
+ CAR_PREFAB_FILE_NAME = 'car_prefab'
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.prefab_utils import Prefab
+
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
+
+ prefab_test_utils.open_base_tests_level()
+
+ # Creates a new Entity at the root level
+ # Asserts if creation didn't succeed
+ parent_entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0))
+ assert parent_entity.id.IsValid(), "Couldn't create parent entity"
+
+ child_entity = EditorEntity.create_editor_entity(parent_id=parent_entity.id)
+ assert child_entity.id.IsValid(), "Couldn't create child entity"
+ assert child_entity.get_world_translation().IsClose(parent_entity.get_world_translation()), f"Child entity position{child_entity.get_world_translation().ToString()}" \
+ f" is not located at the same position as the parent{parent_entity.get_world_translation().ToString()}"
+
+ # Asserts if prefab creation doesn't succeed
+ child_prefab, child_instance = Prefab.create_prefab([child_entity], CAR_PREFAB_FILE_NAME)
+ child_entity_on_child_instance = child_instance.get_direct_child_entities()[0]
+ assert child_instance.container_entity.get_parent_id().IsValid(), "Newly instanced entity has no parent"
+ assert child_instance.container_entity.get_parent_id() == parent_entity.id, "Newly instanced entity parent does not match the expected parent"
+ assert child_instance.container_entity.get_world_translation().IsClose(parent_entity.get_world_translation()), "Newly instanced entity position is not located at the same position as the parent"
+ # Move the parent position, it should update the child position
+ parent_entity.set_world_translation((200.0, 200.0, 200.0))
+ child_instance_translation = child_instance.container_entity.get_world_translation()
+ assert child_instance_translation.IsClose(azlmbr.math.Vector3(200.0, 200.0, 200.0)), f"Instance position position{child_instance_translation.ToString()} didn't get updated" \
+ f" to the same position as the parent{parent_entity.get_world_translation().ToString()}"
+ child_translation = child_entity_on_child_instance.get_world_translation()
+ assert child_translation.IsClose(azlmbr.math.Vector3(200.0, 200.0, 200.0)), f"Entity position{child_translation.ToString()} of the instance didn't get updated" \
+ f" to the same position as the parent{parent_entity.get_world_translation().ToString()}"
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(CreatePrefab_UnderAnEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnotherPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnotherPrefab.py
new file mode 100644
index 0000000000..429da49434
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_UnderAnotherPrefab.py
@@ -0,0 +1,57 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+def CreatePrefab_UnderAnotherPrefab():
+ """
+ Test description:
+ - Creates an entity with a physx collider
+ - Creates a prefab "Outer_prefab" and an instance based of that entity
+ - Creates a prefab "Inner_prefab" inside "Outer_prefab" based the entity contained inside of it
+ Checks that the entity is correctly handlded by the prefab system checking the name and that it contains the physx collider
+ """
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.prefab_utils import Prefab
+
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
+
+ prefab_test_utils.open_base_tests_level()
+
+ # Creates a new Entity at the root level
+ # Asserts if creation didn't succeed
+ entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0), name = "TestEntity")
+ assert entity.id.IsValid(), "Couldn't create entity"
+ entity.add_component("PhysX Collider")
+ assert entity.has_component("PhysX Collider"), "Attempted to add a PhysX Collider but no physx collider collider was found afterwards"
+
+ # Create a prefab based on that entity
+ outer_prefab, outer_instance = Prefab.create_prefab([entity], "Outer_prefab")
+ # The test should be now inside the outer prefab instance.
+ entity = outer_instance.get_direct_child_entities()[0]
+ # We track if that is the same entity by checking the name and if it still contains the component that we created before
+ assert entity.get_name() == "TestEntity", f"Entity name inside outer_prefab doesn't match the original name, original:'TestEntity' current:'{entity.get_name()}'"
+ assert entity.has_component("PhysX Collider"), "Entity name inside outer_prefab doesn't have the collider component it should"
+
+ # Now, create another prefab, based on the entity that is inside outer_prefab
+ inner_prefab, inner_instance = Prefab.create_prefab([entity], "Inner_prefab")
+ # The test entity should now be inside the inner prefab instance
+ entity = inner_instance.get_direct_child_entities()[0]
+ # We track if that is the same entity by checking the name and if it still contains the component that we created before
+ assert entity.get_name() == "TestEntity", f"Entity name inside inner_prefab doesn't match the original name, original:'TestEntity' current:'{entity.get_name()}'"
+ assert entity.has_component("PhysX Collider"), "Entity name inside inner_prefab doesn't have the collider component it should"
+
+ # Verify hierarchy of entities:
+ # Outer_prefab
+ # |- Inner_prefab
+ # | |- TestEntity
+ assert entity.get_parent_id() == inner_instance.container_entity.id
+ assert inner_instance.container_entity.get_parent_id() == outer_instance.container_entity.id
+
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(CreatePrefab_UnderAnotherPrefab)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreatePrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_WithSingleEntity.py
similarity index 84%
rename from AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreatePrefab.py
rename to AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_WithSingleEntity.py
index cae105a9a9..eb8a262a69 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreatePrefab.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/create_prefab/CreatePrefab_WithSingleEntity.py
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-def PrefabBasicWorkflow_CreatePrefab():
+def CreatePrefab_WithSingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab'
@@ -13,7 +13,7 @@ def PrefabBasicWorkflow_CreatePrefab():
from editor_python_test_tools.utils import Report
from editor_python_test_tools.prefab_utils import Prefab
- import PrefabTestUtils as prefab_test_utils
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -24,6 +24,7 @@ def PrefabBasicWorkflow_CreatePrefab():
# Creates a prefab from the new entity
Prefab.create_prefab(car_prefab_entities, CAR_PREFAB_FILE_NAME)
+
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(PrefabBasicWorkflow_CreatePrefab)
+ Report.start_test(CreatePrefab_WithSingleEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py
new file mode 100644
index 0000000000..deaaaedf30
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderAnotherPrefab.py
@@ -0,0 +1,52 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+def DeleteEntity_UnderAnotherPrefab():
+ """
+ Test description:
+ - Creates an entity.
+ - Creates a prefab out of the above entity.
+ - Focuses on the created prefab and destroys the entity within.
+ Checks that the entity is correctly destroyed.
+ """
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ from editor_python_test_tools.prefab_utils import Prefab
+
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
+
+ prefab_test_utils.open_base_tests_level()
+
+ PREFAB_FILE_NAME = 'some_prefab'
+
+ # Creates a new entity at the root level
+ entity = EditorEntity.create_editor_entity()
+ assert entity.id.IsValid(), "Couldn't create entity."
+
+ # Asserts if prefab creation doesn't succeed
+ child_prefab, child_instance = Prefab.create_prefab([entity], PREFAB_FILE_NAME)
+ child_entity_ids_inside_prefab = child_instance.get_direct_child_entities()
+ assert len(
+ child_entity_ids_inside_prefab) == 1, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \
+ f" when there should have been just 1 entity"
+
+ child_entity_inside_prefab = child_entity_ids_inside_prefab[0]
+ child_entity_inside_prefab.focus_on_owning_prefab()
+
+ child_entity_inside_prefab.delete()
+
+ # Wait till prefab propagation finishes before validating entity deletion.
+ azlmbr.legacy.general.idle_wait_frames(1)
+
+ child_entity_ids_inside_prefab = child_instance.get_direct_child_entities()
+ assert len(
+ child_entity_ids_inside_prefab) == 0, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \
+ f" when there should have been 0 entities"
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(DeleteEntity_UnderAnotherPrefab)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py
new file mode 100644
index 0000000000..807427718c
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_entity/DeleteEntity_UnderLevelPrefab.py
@@ -0,0 +1,37 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+def DeleteEntity_UnderLevelPrefab():
+ """
+ Test description:
+ - Creates an entity.
+ - Destroys the created entity.
+ Checks that the entity is correctly destroyed.
+ """
+
+ from editor_python_test_tools.editor_entity_utils import EditorEntity
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
+
+ prefab_test_utils.open_base_tests_level()
+
+ # Creates a new Entity at the root level
+ # Asserts if creation didn't succeed
+ entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0), name = "TestEntity")
+ assert entity.id.IsValid(), "Couldn't create entity"
+
+ level_container_entity = EditorEntity(entity.get_parent_id())
+ entity.delete()
+
+ # Wait till prefab propagation finishes before validating entity deletion.
+ azlmbr.legacy.general.idle_wait_frames(1)
+ level_container_child_entities_count = len(level_container_entity.get_children_ids())
+ assert level_container_child_entities_count == 0, f"The level still has {level_container_child_entities_count}" \
+ f" children when it should have 0."
+
+if __name__ == "__main__":
+ from editor_python_test_tools.utils import Report
+ Report.start_test(DeleteEntity_UnderLevelPrefab)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndDeletePrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_prefab/DeletePrefab_ContainingASingleEntity.py
similarity index 83%
rename from AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndDeletePrefab.py
rename to AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_prefab/DeletePrefab_ContainingASingleEntity.py
index bbebd70e04..919168019e 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndDeletePrefab.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/delete_prefab/DeletePrefab_ContainingASingleEntity.py
@@ -5,14 +5,14 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-def PrefabBasicWorkflow_CreateAndDeletePrefab():
+def DeletePrefab_ContainingASingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
- import PrefabTestUtils as prefab_test_utils
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -29,4 +29,4 @@ def PrefabBasicWorkflow_CreateAndDeletePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(PrefabBasicWorkflow_CreateAndDeletePrefab)
+ Report.start_test(DeletePrefab_ContainingASingleEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateReparentAndDetachPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py
similarity index 84%
rename from AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateReparentAndDetachPrefab.py
rename to AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py
index bdf77c4bf3..69dbcfc89c 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateReparentAndDetachPrefab.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/detach_prefab/DetachPrefab_UnderAnotherPrefab.py
@@ -5,10 +5,10 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-def PrefabBasicWorkflow_CreateReparentAndDetachPrefab():
+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
@@ -18,7 +18,7 @@ def PrefabBasicWorkflow_CreateReparentAndDetachPrefab():
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
- import PrefabTestUtils as prefab_test_utils
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -48,4 +48,4 @@ def PrefabBasicWorkflow_CreateReparentAndDetachPrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(PrefabBasicWorkflow_CreateReparentAndDetachPrefab)
+ Report.start_test(DetachPrefab_UnderAnotherPrefab)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndDuplicatePrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/duplicate_prefab/DuplicatePrefab_ContainingASingleEntity.py
similarity index 83%
rename from AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndDuplicatePrefab.py
rename to AutomatedTesting/Gem/PythonTests/Prefab/tests/duplicate_prefab/DuplicatePrefab_ContainingASingleEntity.py
index 2479ae549e..e611303fbb 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndDuplicatePrefab.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/duplicate_prefab/DuplicatePrefab_ContainingASingleEntity.py
@@ -5,14 +5,14 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-def PrefabBasicWorkflow_CreateAndDuplicatePrefab():
+def DuplicatePrefab_ContainingASingleEntity():
CAR_PREFAB_FILE_NAME = 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
- import PrefabTestUtils as prefab_test_utils
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -29,4 +29,4 @@ def PrefabBasicWorkflow_CreateAndDuplicatePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(PrefabBasicWorkflow_CreateAndDuplicatePrefab)
+ Report.start_test(DuplicatePrefab_ContainingASingleEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_InstantiatePrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/instantiate_prefab/InstantiatePrefab_ContainingASingleEntity.py
similarity index 85%
rename from AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_InstantiatePrefab.py
rename to AutomatedTesting/Gem/PythonTests/Prefab/tests/instantiate_prefab/InstantiatePrefab_ContainingASingleEntity.py
index a701802cd4..a81608ee8a 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_InstantiatePrefab.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/instantiate_prefab/InstantiatePrefab_ContainingASingleEntity.py
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-def PrefabBasicWorkflow_InstantiatePrefab():
+def InstantiatePrefab_ContainingASingleEntity():
from azlmbr.math import Vector3
@@ -15,7 +15,7 @@ def PrefabBasicWorkflow_InstantiatePrefab():
from editor_python_test_tools.prefab_utils import Prefab
- import PrefabTestUtils as prefab_test_utils
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -30,4 +30,4 @@ def PrefabBasicWorkflow_InstantiatePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(PrefabBasicWorkflow_InstantiatePrefab)
+ Report.start_test(InstantiatePrefab_ContainingASingleEntity)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabLevel_OpensLevelWithEntities.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/open_level/OpenLevel_ContainingTwoEntities.py
similarity index 96%
rename from AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabLevel_OpensLevelWithEntities.py
rename to AutomatedTesting/Gem/PythonTests/Prefab/tests/open_level/OpenLevel_ContainingTwoEntities.py
index 0eb7e86a9e..787d7000d2 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabLevel_OpensLevelWithEntities.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/open_level/OpenLevel_ContainingTwoEntities.py
@@ -14,7 +14,7 @@ class Tests():
# fmt:on
-def PrefabLevel_OpensLevelWithEntities():
+def OpenLevel_ContainingTwoEntities():
"""
Opens the level that contains 2 entities, "EmptyEntity" and "EntityWithPxCollider".
This test makes sure that both entities exist after opening the level and that:
@@ -70,4 +70,4 @@ def PrefabLevel_OpensLevelWithEntities():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(PrefabLevel_OpensLevelWithEntities)
+ Report.start_test(OpenLevel_ContainingTwoEntities)
diff --git a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndReparentPrefab.py b/AutomatedTesting/Gem/PythonTests/Prefab/tests/reparent_prefab/ReparentPrefab_UnderAnotherPrefab.py
similarity index 89%
rename from AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndReparentPrefab.py
rename to AutomatedTesting/Gem/PythonTests/Prefab/tests/reparent_prefab/ReparentPrefab_UnderAnotherPrefab.py
index 1cbc591c29..2c460a3298 100644
--- a/AutomatedTesting/Gem/PythonTests/Prefab/tests/PrefabBasicWorkflow_CreateAndReparentPrefab.py
+++ b/AutomatedTesting/Gem/PythonTests/Prefab/tests/reparent_prefab/ReparentPrefab_UnderAnotherPrefab.py
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
-def PrefabBasicWorkflow_CreateAndReparentPrefab():
+def ReparentPrefab_UnderAnotherPrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab'
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab'
@@ -18,7 +18,7 @@ def PrefabBasicWorkflow_CreateAndReparentPrefab():
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.prefab_utils import Prefab
- import PrefabTestUtils as prefab_test_utils
+ import Prefab.tests.PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -45,4 +45,4 @@ def PrefabBasicWorkflow_CreateAndReparentPrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
- Report.start_test(PrefabBasicWorkflow_CreateAndReparentPrefab)
+ Report.start_test(ReparentPrefab_UnderAnotherPrefab)
diff --git a/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainHeightGradientList_AddRemoveGradientWorks.py b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainHeightGradientList_AddRemoveGradientWorks.py
new file mode 100644
index 0000000000..0be1f1ca10
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/TerrainHeightGradientList_AddRemoveGradientWorks.py
@@ -0,0 +1,144 @@
+"""
+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 HeightTests:
+ single_gradient_height_correct = (
+ "Successfully retrieved height for gradient1.",
+ "Failed to retrieve height for gradient1."
+ )
+ double_gradient_height_correct = (
+ "Successfully retrieved height when two gradients exist.",
+ "Failed to retrieve height when two gradients exist."
+ )
+ triple_gradient_height_correct = (
+ "Successfully retrieved height when three gradients exist.",
+ "Failed to retrieve height when three gradients exist."
+ )
+ terrain_data_changed_call_count_correct = (
+ "OnTerrainDataChanged called expected number of times.",
+ "OnTerrainDataChanged call count incorrect."
+ )
+
+def TerrainHeightGradientList_AddRemoveGradientWorks():
+ """
+ Summary:
+ Test aspects of the TerrainHeightGradientList through the BehaviorContext and the Property Tree.
+ :return: None
+ """
+
+ import os
+ import math as sys_math
+
+ import azlmbr.legacy.general as general
+ 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
+
+ terrain_changed_call_count = 0
+ expected_terrain_changed_calls = 0
+
+ aabb_component_name = "Axis Aligned Box Shape"
+ gradientlist_component_name = "Terrain Height Gradient List"
+ layerspawner_component_name = "Terrain Layer Spawner"
+
+ gradient_value_path = "Configuration|Value"
+
+ 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 on_terrain_changed(args):
+ nonlocal terrain_changed_call_count
+
+ terrain_changed_call_count += 1
+
+ def set_component_path_val(entity, component, path, value):
+ entity.get_set_test(component, path, value)
+
+ def set_gradients_check_height(main_entity, gradient_list, expected_height, test_results):
+ nonlocal expected_terrain_changed_calls
+
+ test_tolerance = 0.01
+ gradient_list_path = "Configuration|Gradient Entities"
+
+ set_component_path_val(main_entity, 1, gradient_list_path, gradient_list)
+
+ expected_terrain_changed_calls += 1
+
+ # Wait until the terrain data has been updated.
+ helper.wait_for_condition(lambda: terrain_changed_call_count == expected_terrain_changed_calls, 2.0)
+
+ # Get the height at the origin.
+ height = terrain.TerrainDataRequestBus(bus.Broadcast, "GetHeightFromFloats", 0.0, 0.0, 0)
+
+ Report.result(test_results, sys_math.isclose(height, expected_height, abs_tol=test_tolerance))
+
+ 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)
+
+ # Add a terrain world component
+ world_component = hydra.add_level_component("Terrain World")
+
+ aabb_height = 1024.0
+ box_dimensions = math.Vector3(1.0, 1.0, aabb_height);
+
+ # Create a main entity with a LayerSpawner, AAbb and HeightGradientList.
+ main_entity = create_entity_at("entity2", [layerspawner_component_name, gradientlist_component_name, aabb_component_name], 0.0, 0.0, aabb_height/2.0)
+
+ # Create three gradient entities.
+ gradient_entity1 = create_entity_at("Constant Gradient1", ["Constant Gradient"], 0.0, 0.0, 0.0);
+ gradient_entity2 = create_entity_at("Constant Gradient2", ["Constant Gradient"], 0.0, 0.0, 0.0);
+ gradient_entity3 = create_entity_at("Constant Gradient3", ["Constant Gradient"], 0.0, 0.0, 0.0);
+
+ # Give everything a chance to finish initializing.
+ general.idle_wait_frames(1)
+
+ # Set the gradients to different values.
+ gradient_values = [0.5, 0.8, 0.3]
+ set_component_path_val(gradient_entity1, 0, gradient_value_path, gradient_values[0])
+ set_component_path_val(gradient_entity2, 0, gradient_value_path, gradient_values[1])
+ set_component_path_val(gradient_entity3, 0, gradient_value_path, gradient_values[2])
+
+ # Give the TerrainSystem time to tick.
+ general.idle_wait_frames(1)
+
+ # Set the dimensions of the Aabb.
+ set_component_path_val(main_entity, 2, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
+
+ # Set up a handler to wait for notifications from the TerrainSystem.
+ handler = azlmbr.terrain.TerrainDataNotificationBusHandler()
+ handler.connect()
+ handler.add_callback("OnTerrainDataChanged", on_terrain_changed)
+
+ # Add a gradient to GradientList, then check the height returned from the TerrainSystem is correct.
+ set_gradients_check_height(main_entity, [gradient_entity1.id], aabb_height * gradient_values[0], HeightTests.single_gradient_height_correct)
+
+ # Add gradient2 and check height at the origin, this should have changed to match the second gradient value.
+ set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id], aabb_height * gradient_values[1], HeightTests.double_gradient_height_correct)
+
+ # Add gradient3, the height should still be the second value, as that was the highest.
+ set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id, gradient_entity3.id], aabb_height * gradient_values[1], HeightTests.triple_gradient_height_correct)
+
+if __name__ == "__main__":
+
+ from editor_python_test_tools.utils import Report
+ Report.start_test(TerrainHeightGradientList_AddRemoveGradientWorks)
\ No newline at end of file
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_SupportsPhysics.py b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/Terrain_SupportsPhysics.py
index e68b0932c2..390ec6a6b0 100644
--- a/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/Terrain_SupportsPhysics.py
+++ b/AutomatedTesting/Gem/PythonTests/Terrain/EditorScripts/Terrain_SupportsPhysics.py
@@ -72,7 +72,7 @@ def Terrain_SupportsPhysics():
# 2) 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", "PhysX Heightfield Collider"]
- entity2_components_to_add = ["Vegetation Reference Shape", "Gradient Transform Modifier", "FastNoise Gradient"]
+ entity2_components_to_add = ["Shape Reference", "Gradient Transform Modifier", "FastNoise Gradient"]
ball_components_to_add = ["Sphere Shape", "PhysX Collider", "PhysX Rigid Body"]
terrain_spawner_entity = hydra.Entity("TestEntity1")
terrain_spawner_entity.create_entity(azmath.Vector3(512.0, 512.0, 50.0), entity1_components_to_add)
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 c5eec74c08..98c4f8a660 100644
--- a/AutomatedTesting/Gem/PythonTests/Terrain/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/Terrain/TestSuite_Main.py
@@ -20,8 +20,22 @@ from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSharedTest
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
+ enable_prefab_system = False
+
class test_AxisAlignedBoxShape_ConfigurationWorks(EditorSharedTest):
from .EditorScripts import TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges as test_module
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/PythonTests/WhiteBox/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/WhiteBox/TestSuite_Main.py
index fa6c81c98a..2fc717e256 100644
--- a/AutomatedTesting/Gem/PythonTests/WhiteBox/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/TestSuite_Main.py
@@ -24,12 +24,12 @@ from base import TestAutomationBase
class TestAutomation(TestAutomationBase):
def test_WhiteBox_AddComponentToEntity(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_AddComponentToEntity as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_WhiteBox_SetDefaultShape(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_SetDefaultShape as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_WhiteBox_SetInvisible(self, request, workspace, editor, launcher_platform):
from .tests import WhiteBox_SetInvisible as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_fast_scan_setting_backup_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_fast_scan_setting_backup_fixture.py
index 4a096ca3fe..c224289cf4 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_fast_scan_setting_backup_fixture.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_fast_scan_setting_backup_fixture.py
@@ -29,6 +29,9 @@ def ap_fast_scan_setting_backup_fixture(request, workspace) -> PlatformSetting:
if workspace.asset_processor_platform == 'mac':
pytest.skip("Mac plist file editing not implemented yet")
+ if workspace.asset_processor_platform == 'linux':
+ pytest.skip("Linux system settings not implemented yet")
+
key = fast_scan_key
subkey = fast_scan_subkey
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_missing_dependency_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_missing_dependency_fixture.py
index 857d91bb12..7f7f420fd0 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_missing_dependency_fixture.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_missing_dependency_fixture.py
@@ -183,23 +183,26 @@ def ap_missing_dependency_fixture(request, workspace, ap_setup_fixture) -> Any:
:return: None
"""
logger.info(f"Searching output for expected dependencies for product {product}")
+ sorted_expected = sorted(expected_dependencies)
# Check dependencies found either in the log or console output
for product_name, missing_deps in self.extract_missing_dependencies_from_output(log_output).items():
if product in product_name:
+ sorted_missing = sorted(missing_deps)
# fmt:off
- assert sorted(missing_deps) == sorted(expected_dependencies), \
+ assert sorted_expected == sorted_missing, \
f"Missing dependencies for '{product_name}' did not match expected. Expected: " \
- f"{expected_dependencies}, Actual: {missing_deps}"
+ f"{sorted_expected}, Actual: {sorted_missing}"
# fmt:on
# Check dependencies found in Database
for product_name, missing_deps in self.extract_missing_dependencies_from_database(product,
platforms).items():
if product.replace("\\", "/") in product_name:
+ sorted_missing = sorted(missing_deps)
# fmt:off
- assert sorted(expected_dependencies) == sorted(missing_deps), \
- f"Product '{product_name}' expected missing dependencies: {expected_dependencies}; " \
- f"actual missing dependencies {missing_deps}"
+ assert sorted_expected == sorted_missing, \
+ f"Product '{product_name}' expected missing dependencies: {sorted_expected}; " \
+ f"actual missing dependencies {sorted_missing}"
# fmt:on
def __getitem__(self, item: str) -> object:
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py
index 244ecfb516..c5b02e4f28 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_setup_fixture.py
@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
-A fixture for Setting Up Asset Processor Batch workspace for tests in lmbr_test
+A fixture for Setting Up Asset Processor Batch workspace for tests
"""
# Import builtin libraries
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py
index eea6cb9224..885b4c2959 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/asset_processor_fixture.py
@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
-A fixture for using the Asset Processor in lmbr_test, this will stop the asset processor after every test via
+A fixture for using the Asset Processor, this will stop the asset processor after every test via
the teardown. Using the fixture at class level will stop the asset processor after the suite completes.
Using the fixture at test level will stop asset processor after the test completes. Calling this fixture as a test argument will still run the teardown to stop the Asset Processor.
"""
@@ -15,6 +15,7 @@ import logging
# Import LyTestTools
import ly_test_tools.o3de.asset_processor as asset_processor_commands
+import ly_test_tools.o3de.asset_processor_utils
logger = logging.getLogger(__name__)
@@ -36,5 +37,8 @@ def asset_processor(request: pytest.fixture, workspace: pytest.fixture) -> asset
ap.stop()
request.addfinalizer(teardown)
+ for n in ly_test_tools.o3de.asset_processor_utils.processList:
+ assert not ly_test_tools.o3de.asset_processor_utils.check_ap_running(n), f"{n} process did not shutdown correctly."
+
return ap
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
index 5a5809595e..e37a5ed99b 100644
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
@@ -103,6 +103,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
AZ::AssetBundlerBatch
)
+ ly_add_pytest(
+ NAME AssetPipelineTests.BundleMode
+ PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py
+ EXCLUDE_TEST_RUN_TARGET_FROM_IDE
+ TEST_SERIAL
+ TEST_SUITE periodic
+ RUNTIME_DEPENDENCIES
+ AZ::AssetProcessor
+ AZ::AssetBundlerBatch
+ Legacy::Editor
+ AutomatedTesting.Assets
+ )
+
ly_add_pytest(
NAME AssetPipelineTests.AssetBuilder
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py
index f3483d9c1f..cc79ed7c27 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py
@@ -8,6 +8,8 @@ General Asset Processor Batch Tests
"""
# Import builtin libraries
+from os import listdir
+
import pytest
import logging
import os
@@ -329,7 +331,7 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
# or an expected behavior has changed. Processing bootstrap.cfg sometimes but not other times should not
# cause a failure in this test.
num_processed_assets = asset_processor_utils.get_num_processed_assets(output)
- assert num_processed_assets >= 8, f'Wrong number of successfully processed assets found in output: '\
+ assert num_processed_assets >= 6, f'Wrong number of successfully processed assets found in output: '\
'{num_processed_assets}'
missing_assets, _ = asset_processor.compare_assets_with_cache()
@@ -585,20 +587,18 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
3. Verify that logs exist for both AP Batch & AP GUI
"""
asset_processor.create_temp_asset_root()
+ asset_processor.create_temp_log_root()
LOG_PATH = {
"batch_log": workspace.paths.ap_batch_log(),
- "gui_log": workspace.paths.ap_gui_log(),
- "job_logs": workspace.paths.ap_job_logs(),
+ "gui_log": workspace.paths.ap_gui_log()
}
class LogTimes:
batch_log_start_time = 0
gui_log_start_time = 0
- job_logs_start_time = 0
batch_log_final_time = 0
gui_log_final_time = 0
- job_logs_final_time = 0
@staticmethod
def Report():
@@ -607,12 +607,10 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
Original Times:
Batch: {LogTimes.batch_log_start_time}
GUI: {LogTimes.gui_log_start_time}
- JobLogs:{LogTimes.job_logs_start_time}
Post-Run Times:
Batch: {LogTimes.batch_log_final_time}
GUI: {LogTimes.gui_log_final_time}
- JobLogs:{LogTimes.job_logs_final_time}
"""
)
@@ -629,23 +627,19 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
LogTimes.Report()
def check_existence(name, path):
- assert os.path.exists(path), f"{name} could not be located after running the AP."
+ assert os.path.exists(path), f"{name} could not be located {path} after running the AP."
# Check if log files previously exist and grab their modification times
update_times("_start_time")
# Run the Batch process
- assert asset_processor.batch_process(), "Batch process failed to successfully terminate"
+ assert asset_processor.batch_process(create_temp_log=False), "Batch process failed to successfully terminate"
- asset_processor.gui_process(quitonidle=True)
+ asset_processor.gui_process(quitonidle=True, create_temp_log=False)
# Check that the Logs directory exists (C1564055)
check_existence("Logs Directory", workspace.paths.ap_log_dir())
- # Check that the logs and JobLogs directory have updated modified times (C1564056)
- for key in LOG_PATH.keys():
- check_existence(key, LOG_PATH[key])
-
update_times("_final_time")
for key in LOG_PATH.keys():
@@ -708,6 +702,7 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
@pytest.mark.BAT
@pytest.mark.assetpipeline
+ @pytest.mark.skip(reason="need to change assets from .slice files to an asset type that can have nested dependencies")
def test_validateNestedPreloadDependency_Found(self, asset_processor, ap_setup_fixture, workspace):
"""
Tests processing of a nested circular dependency and verifies that Asset Processor will return an error
@@ -731,3 +726,11 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
assert error_line_found, "The error could not be found in the newest run of the AP Batch log."
+ @pytest.mark.assetpipeline
+ def test_AssetProcessor_Log_On_Failure(self, asset_processor, ap_setup_fixture, workspace):
+ asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "test_AP_Logs")
+ result, output = asset_processor.batch_process(expect_failure=True, capture_output=True)
+ assert result == False, f'AssetProcessorBatch should have failed because there is a bad asset, output was {output}'
+
+ jobLogs = listdir(workspace.paths.ap_job_logs() + "/test_AP_Logs")
+ assert not len(jobLogs) == 0, 'No job logs where output during failure.'
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/cgf_to_delete.cgf b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/cgf_to_delete.cgf
deleted file mode 100644
index 47571e39a9..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/cgf_to_delete.cgf
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7932fada1523fad4eb6ad5c13111bb4c00d6b0584ec8641060bf25f306b17e69
-size 84632
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/fbx_to_delete.fbx b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/fbx_to_delete.fbx
deleted file mode 100644
index 165bc01a54..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/fbx_to_delete.fbx
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bf94b548eccb78432db65077124cadf20de975919b181d712fde081f59edd353
-size 38848
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/file_to_delete.prefab b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/file_to_delete.prefab
new file mode 100644
index 0000000000..9e26dfeeb6
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/file_to_delete.prefab
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/file_to_delete.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/file_to_delete.txt
new file mode 100644
index 0000000000..3d789f8b83
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1568831/file_to_delete.txt
@@ -0,0 +1 @@
+to be deleted
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1571774/test_mesh_robot.cgf b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1571774/test_mesh_robot.cgf
deleted file mode 100644
index fcb3513ed0..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1571774/test_mesh_robot.cgf
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:1675471085483e0bd252a5bdd4db1b365c66f16ac32a6e6dd70bb1c23df83fa5
-size 24160
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1591338/test_mesh_robot.cgf b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1591338/test_mesh_robot.cgf
deleted file mode 100644
index fcb3513ed0..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1591338/test_mesh_robot.cgf
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:1675471085483e0bd252a5bdd4db1b365c66f16ac32a6e6dd70bb1c23df83fa5
-size 24160
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1591338/test_mesh_robot.prefab b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1591338/test_mesh_robot.prefab
new file mode 100644
index 0000000000..9e26dfeeb6
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C1591338/test_mesh_robot.prefab
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AP_Logs/BadAsset.fbx b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AP_Logs/BadAsset.fbx
new file mode 100644
index 0000000000..cf1bbaac8a
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AP_Logs/BadAsset.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7c6b33c6137d6bd8c696f180c30a23089c95c1af398a630b4b13e080bec3254d
+size 18220
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AddSameAssetsDifferentNames_ShouldProcess/Energy_Background_One.png b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AddSameAssetsDifferentNames_ShouldProcess/Energy_Background_One.png
deleted file mode 100644
index e012e887e7..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AddSameAssetsDifferentNames_ShouldProcess/Energy_Background_One.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:21df6ab62f2572daa6d0710ad6819a728ee751a62170903a6773563d614aa51f
-size 15191
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AddSameAssetsDifferentNames_ShouldProcess/Energy_Background_Two.png b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AddSameAssetsDifferentNames_ShouldProcess/Energy_Background_Two.png
deleted file mode 100644
index e012e887e7..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_AddSameAssetsDifferentNames_ShouldProcess/Energy_Background_Two.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:21df6ab62f2572daa6d0710ad6819a728ee751a62170903a6773563d614aa51f
-size 15191
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessAndDeleteCache_APBatchShouldReprocess/Init.bnk b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessAndDeleteCache_APBatchShouldReprocess/Init.bnk
deleted file mode 100644
index f525a402af..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessAndDeleteCache_APBatchShouldReprocess/Init.bnk
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:f0b4750147acbcc6229a1043ed47ee48e7703a5241f27fc72976e95741144369
-size 2372
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessAndDeleteCache_APBatchShouldReprocess/entity_icon_example_2.png b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessAndDeleteCache_APBatchShouldReprocess/entity_icon_example_2.png
deleted file mode 100644
index 47e2d35331..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessAndDeleteCache_APBatchShouldReprocess/entity_icon_example_2.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:a036c3763b96079dde8505ad6995f8b717a777c78d7a434ac8de6f1ccb5d8dd1
-size 4327
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/SoundWave_1.png b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/SoundWave_1.png
deleted file mode 100644
index b3b8fba4a1..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/SoundWave_1.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:cf55a4372d82d70d8cdcc95468367cd4fad7649d3fb99c4d85049977b506885c
-size 13429
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/extra_file.prefab b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/extra_file.prefab
new file mode 100644
index 0000000000..9e26dfeeb6
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/extra_file.prefab
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/test_cube.fbx b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/test_cube.fbx
deleted file mode 100644
index 57fa7b327c..0000000000
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/test_ProcessByBothApAndBatch_Md5ShouldMatch/test_cube.fbx
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:1821d000b583821fd36ec73f91073d51ae90762225a34a81a74771c36236b5e1
-size 12963
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py
new file mode 100644
index 0000000000..33a55d6601
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py
@@ -0,0 +1,20 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+import azlmbr.bus
+import azlmbr.editor
+import azlmbr.legacy.general
+import sys
+
+# Print out the passed in bundle_path, so the outer test can verify this was sent in correctly
+bundle_path = sys.argv[1]
+print('Bundle mode test running with path {}'.format(sys.argv[1]))
+
+# Turn on bundle mode. This will trigger some printouts that the outer test logic will validate.
+azlmbr.legacy.general.set_cvar_integer("sys_report_files_not_found_in_paks", 1)
+azlmbr.legacy.general.run_console(f"loadbundles {bundle_path}")
+
+azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py
new file mode 100644
index 0000000000..af92bb1773
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py
@@ -0,0 +1,93 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+import os
+import pytest
+import logging
+import sys
+import time
+pytest.importorskip('ly_test_tools')
+
+import ly_test_tools.environment.file_system as fs
+import ly_test_tools.environment.waiter as waiter
+import ly_test_tools.log.log_monitor
+
+from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
+from ..ap_fixtures.bundler_batch_setup_fixture import bundler_batch_setup_fixture as bundler_batch_helper
+from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
+
+@pytest.mark.SUITE_periodic
+@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
+@pytest.mark.parametrize('project', ['AutomatedTesting'])
+@pytest.mark.parametrize('level', ['auto_test'])
+class TestBundleMode(object):
+ def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform,
+ asset_processor, workspace, bundler_batch_helper):
+ level_pak = os.path.join("levels", level, "level.pak")
+
+ bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
+ bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
+ bundle_result_path = os.path.join(bundles_folder,
+ bundler_batch_helper.platform_file_name(
+ "bundle.pak", workspace.asset_processor_platform))
+
+ # Create target 'Bundles' folder if it doesn't exist
+ if not os.path.exists(bundles_folder):
+ os.mkdir(bundles_folder)
+ # Delete target bundle file if it already exists
+ if os.path.exists(bundle_result_path):
+ fs.delete([bundle_result_path], True, False)
+
+ # Make asset list file to use in the bundle
+ bundler_batch_helper.call_assetLists(
+ addSeed=level_pak,
+ assetListFile=bundler_batch_helper["asset_info_file_request"],
+ )
+
+ # Make bundle in /Bundles
+ bundler_batch_helper.call_bundles(
+ assetListFile=bundler_batch_helper["asset_info_file_result"],
+ outputBundlePath=bundle_request_path,
+ maxSize="2048",
+ )
+
+ # Ensure the bundle was created
+ assert os.path.exists(bundle_result_path), f"Bundle was not created at location: {bundle_result_path}"
+
+ # The editor flips the slash direction in some of the printouts
+ bundle_result_path_editor_separator = bundle_result_path.replace('\\', '/')
+
+ expected_lines = [
+ # A beginning of test printout can help debug where failures occur, if this line is missing
+ # then the Editor didn't launch, didn't run the Python test, or didn't pass in the right parameter
+ f'Bundle mode test running with path {bundles_folder}',
+ # These printouts happen in response to the loadbundles call, and verify this bundle is actually loaded
+ f"[CONSOLE] Executing console command 'loadbundles {bundles_folder}'",
+ f'(BundlingSystem) - Loading bundles from {bundles_folder} of type .pak',
+ f'(Archive) - Opening archive file {bundle_result_path_editor_separator}',
+ ]
+ unexpected_lines = []
+
+ timeout = 180
+ halt_on_unexpected = False
+ test_directory = os.path.join(os.path.dirname(__file__))
+ test_file = os.path.join(test_directory, 'bundle_mode_in_editor_tests.py')
+ editor.args.extend(['-NullRenderer', '-rhi=Null', "--skipWelcomeScreenDialog",
+ "--autotest_mode", "--runpythontest", test_file, "--runpythonargs", bundles_folder])
+
+ with editor.start(launch_ap=True):
+ editor_log_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
+ log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editor_log_file)
+ waiter.wait_for(
+ lambda: editor.is_alive(),
+ timeout,
+ exc=("Log file '{}' was never opened by another process.".format(editor_log_file)),
+ interval=1)
+ log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout)
+
+ # Delete the bundle created and used in this test
+ fs.delete([bundle_result_path], True, False)
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py
index 7159b2e83f..52321fceea 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py
@@ -120,31 +120,29 @@ class TestsMissingDependencies_WindowsAndMac(object):
# Relative path to the txt file with missing dependencies
expected_product = f"testassets\\validuuidsnotdependency.txt"
- self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Objects\\LumberTank")
- self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Objects\\Characters\\Jack")
# Expected missing dependencies
expected_dependencies = [
# String Asset #
- ('1CB10C43F3245B93A294C602ADEF95F9:[0', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'),
+ # InvalidAssetIdNoReport.txt
+ ('E68A85B0-131D-5A82-B2D5-BC58EE4062AE', '{E68A85B0-131D-5A82-B2D5-BC58EE4062AE}:0'),
+ # InvalidRelativePathsNoReport.txt
+ ('B3EF12DD306C520EB0A8A6B0D031A195', '{B3EF12DD-306C-520E-B0A8-A6B0D031A195}:0'),
+ # SelfReferenceUUID.txt
('33bcee02F3225688ABEE534F6058593F', '{33BCEE02-F322-5688-ABEE-534F6058593F}:0'),
- ('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3e8'),
- ('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3ea'),
- ('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3eb'),
- ('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3e8'),
- ('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3ea'),
- ('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3eb'),
- ('6BDE282B49C957F7B0714B26579BCA9A', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'),
- ('747D31D71E62553592226173C49CF97E', '{747D31D7-1E62-5535-9222-6173C49CF97E}:1'),
- ('747D31D71E62553592226173C49CF97E', '{747D31D7-1E62-5535-9222-6173C49CF97E}:2'),
- ('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3e8'),
- ('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3ea'),
- ('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3eb'),
- ('B076CDDC-14DF-50F4-A5E9-7518ABB3E851', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'),
- ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3e8'),
- ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3ea'),
- ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3eb'),
- ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3ec'),
- ('D92C4661C8985E19BD3597CB2318CFA6:[0', '{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0'),
+ # SelfReferencePath.txt
+ ('DD587FBE-16C8-5B98-AE3C-A9F8750B2692', '{DD587FBE-16C8-5B98-AE3C-A9F8750B2692}:0'),
+ # InvalidUUIDNoReport.txt
+ ('837412DF-D05F-576D-81AA-ACF360463749', '{837412DF-D05F-576D-81AA-ACF360463749}:0'),
+ # MaxIteration31Deep.txt
+ ('3F642A0FDC825696A70A1DA5709744DF', '{3F642A0F-DC82-5696-A70A-1DA5709744DF}:0'),
+ # OnlyMatchesCorrectLengthUUIDs.txt
+ ('2545AD8B-1B9B-5F93-859D-D8DC1DC2B480', '{2545AD8B-1B9B-5F93-859D-D8DC1DC2B480}:0'),
+ # WildcardScanTest1.txt
+ ('1CB10C43F3245B93A294C602ADEF95F9:[0', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'),
+ # RelativeProductPathsNotDependencies.txt
+ ('B772953CA08A5D209491530E87D11504:[0', '{B772953C-A08A-5D20-9491-530E87D11504}:0'),
+ # WildcardScanTest2.txt
+ ('D92C4661C8985E19BD3597CB2318CFA6', '{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0'),
]
self.do_missing_dependency_test(expected_product, expected_dependencies,
"%ValidUUIDsNotDependency.txt")
@@ -187,8 +185,11 @@ class TestsMissingDependencies_WindowsAndMac(object):
# Expected missing dependencies
expected_dependencies = [
# String Asset #
- ('2ef92b8D044E5C278E2BB1AC0374A4E7:1003', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3eb'),
+ # _dev_Red.tif
+ ('2ef92b8D044E5C278E2BB1AC0374A4E7:1000', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3e8'),
+ # _dev_Purple.tif
('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
+ # _dev_White.tif
('D83B36F1-61A6-5001-B191-4D0CE282E236}-1002', '{D83B36F1-61A6-5001-B191-4D0CE282E236}:3ea'),
]
@@ -237,11 +238,10 @@ class TestsMissingDependencies_WindowsAndMac(object):
expected_dependencies = [
# String Asset #
('TestAssets\\WildcardScanTest1.txt', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'),
- ('libs/particles/milestone2PARTICLES.XML', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'),
+ ('TESTASSETS/ReportONEmISSINGdEPENDENCY.tXT', '{BE5E2373-245E-59E4-B4C6-7370EEAA2EFD}:0'),
('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3e8'),
('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
- ('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3eb'),
- ('project.json', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'),
+ ('TestAssets/InvalidAssetIdNoReport.txt', '{E68A85B0-131D-5A82-B2D5-BC58EE4062AE}:0'),
('TestAssets/RelativeProductPathsNotDependencies.txt', '{B772953C-A08A-5D20-9491-530E87D11504}:0'),
]
@@ -282,29 +282,31 @@ class TestsMissingDependencies_WindowsAndMac(object):
2. Set the expected missing dependencies
3. Execute test
"""
-
- self._asset_processor.add_source_folder_assets(f"Gems\\LyShineExamples\\Assets\\UI\\Fonts\\LyShineExamples")
- self._asset_processor.add_scan_folder(f"Gems\\LyShineExamples\\Assets")
# Relative path to the txt file with missing dependencies as product paths
expected_product = f"testassets\\relativeproductpathsnotdependencies.txt"
expected_dependencies = [
# String Asset #
- ('materials/floor_tile.mtl', '{0EFF5E4A-F544-5D87-8696-6DDFA62D6063}:0'),
- ('materials/am_grass1.mtl', '{1151F14D-38A6-5579-888A-BE3139882E68}:0'),
- ('2ef92b8D044E5C278E2BB1AC0374A4E7:1002', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3ea'),
- ('textures/milestone2/ama_grey_02.tif.streamingimage', '{3EE80AAD-EB9C-56BD-9E9C-65410578998C}:3e8'),
- ('ui/milestone2menu.uicanvas', '{445D9AF3-6CA5-5281-82A9-5C570BCD1DB8}:0'),
- ('libs/particles/milestone2particles.xml', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'),
- ('textures/_dev_yellow_light.tif.1002.imagemipchain', '{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:3ea'),
- ('textures\\\\_dev_tan.tif.streamingimage', '{8F2BCEF5-C8CE-5B80-8103-8C1D694D012C}:3e8'),
- ('materials/am_rockground.mtl', '{A1DA3D05-A020-5BB5-A608-C4812B7BD733}:0'),
('textures/_dev_purple.tif.streamingimage', '{A2482826-053D-5634-A27B-084B1326AAE5}:3e8'),
- ('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
- ('project.json', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'),
- ('CEAA362B4E505BCEB827CB92EF40A50E', '{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:1'),
- ('CEAA362B4E505BCEB827CB92EF40A50E', '{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:2'),
+ ('textures\\_dev_stucco.tif.streamingimage', '{70114D85-D712-5AEB-A816-8FE3A37087AF}:3e8'),
+ ('textures\\\\_dev_tan.tif.streamingimage', '{8F2BCEF5-C8CE-5B80-8103-8C1D694D012C}:3e8'),
('TEXTURES/_DEV_WHITE.tif.streamingimage', '{D83B36F1-61A6-5001-B191-4D0CE282E236}:3e8'),
+ ('textures/_dev_yellow_light.tif.1002.imagemipchain', '{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:3ea'),
+ ('textures/_dev_woodland.tif.1002.imagemipchain', '{F3DD193C-5845-569C-A974-AA338B30CF86}:3ea'),
('textures/_dev_woodland.tif.streamingimage', '{F3DD193C-5845-569C-A974-AA338B30CF86}:3e8'),
+ ('textures/_dev_yellow_light.tif.streamingimage', '{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:3e8'),
+ ('textures/_dev_yellow_med.tif.1002.imagemipchain', '{BB4DFF57-52BD-525B-9628-68232E31802C}:3ea'),
+ ('textures/lights/flare01.tif.streamingimage', '{D8E49CC4-C743-5F31-A1EC-4AA89163B8F5}:3e8'),
+ # SelfReferenceUUID.txt
+ ('33BCEE02-F322-5688-ABEE-534F6058593F', '{33BCEE02-F322-5688-ABEE-534F6058593F}:0'),
+ ('textures/test_texture_sequence/test_texture_sequence000.png.streamingimage', '{6CC90BEE-0A9F-57A8-9013-7C1D643C0E8E}:3e8'),
+ # _dev_red.tif.streamingimage
+ ('2ef92b8D044E5C278E2BB1AC0374A4E7:1002', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3ea'),
+ # SelfReferenceAssetID.txt
+ ('785A05D2-483E-5B43-A2B9-92ACDAE6E938', '{785A05D2-483E-5B43-A2B9-92ACDAE6E938}:0'),
+ ('textures/test_texture_sequence/test_texture_sequence001.png.streamingimage', '{8A8A37DD-01B9-5D70-92E4-925E2C0FE826}:3e8'),
+ # _dev_purple.tif.1002.imagemipchain
+ ('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
+ ('textures/_dev_purple_glass.tif.1002.imagemipchain', '{2FCDD831-77D1-5BE1-A4C8-CA47E4F89F19}:3ea'),
]
self.do_missing_dependency_test(expected_product, expected_dependencies,
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/Jack_Idle_Aim_ZUp.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/SceneDebug/Jack_Idle_Aim_ZUp.dbgsg
similarity index 99%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/Jack_Idle_Aim_ZUp.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/SceneDebug/Jack_Idle_Aim_ZUp.dbgsg
index 8b0132a448..c8c5c8697b 100644
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/Jack_Idle_Aim_ZUp.dbgsg
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/SceneDebug/Jack_Idle_Aim_ZUp.dbgsg
@@ -242,7 +242,7 @@ Node Type: BoneData
BasisX: < 1.000000, -0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: <-0.000000, -0.000000, 1.000000>
- Transl: < 0.152547, 0.043345, 0.090955>
+ Transl: < 0.152547, 0.043345, 0.090954>
Node Name: animation
Node Path: RootNode.jack_root.Bip01__pelvis.spine1.spine2.animation
@@ -544,7 +544,7 @@ Node Type: BoneData
Node Name: animation
Node Path: RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_upArmRoll.animation
Node Type: AnimationData
- KeyFrames: Count 195. Hash: 15529789169672670472
+ KeyFrames: Count 195. Hash: 8781707605519483934
TimeStepBetweenFrames: 0.033333
Node Name: transform
@@ -710,7 +710,7 @@ Node Type: BoneData
BasisX: < 0.514369, 0.855813, 0.054857>
BasisY: < 0.088153, 0.010863, -0.996047>
BasisZ: <-0.853026, 0.517172, -0.069855>
- Transl: <-0.247306, -0.062325, 0.878373>
+ Transl: <-0.247306, -0.062325, 0.878372>
Node Name: animation
Node Path: RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_loArmRoll.animation
@@ -857,7 +857,7 @@ Node Type: BoneData
BasisX: < 0.329257, 0.944038, -0.019538>
BasisY: < 0.465563, -0.180309, -0.866452>
BasisZ: <-0.821487, 0.276189, -0.498877>
- Transl: <-0.255124, -0.049696, 0.794467>
+ Transl: <-0.255124, -0.049696, 0.794466>
Node Name: animation
Node Path: RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.l_shldr.l_upArm.l_loArm.l_hand.l_metacarpal.animation
@@ -939,7 +939,6 @@ Node Type: AnimationData
Node Name: transform
Node Path: RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_index1.transform
-
Node Type: TransformData
Matrix:
BasisX: < 0.939162, 0.133704, -0.316383>
@@ -954,7 +953,7 @@ Node Type: BoneData
BasisX: <-0.102387, -0.418082, -0.902621>
BasisY: < 0.928150, 0.286271, -0.237880>
BasisZ: < 0.357847, -0.862123, 0.358732>
- Transl: < 0.187367, 0.698324, 1.467209>
+ Transl: < 0.187367, 0.698323, 1.467209>
Node Name: animation
Node Path: RootNode.jack_root.Bip01__pelvis.spine1.spine2.spine3.r_shldr.r_upArm.r_loArm.r_hand.r_mid1.animation
@@ -1513,3 +1512,4 @@ Node Type: TransformData
BasisY: < 0.000000, 0.229519, -0.973304>
BasisZ: < 0.000000, 0.973304, 0.229519>
Transl: < 0.000000, -0.023770, 0.000000>
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/SceneDebug/jack_idle_aim_zup.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/SceneDebug/jack_idle_aim_zup.dbgsg.xml
new file mode 100644
index 0000000000..caaf3810fe
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/Motion/SceneDebug/jack_idle_aim_zup.dbgsg.xml
@@ -0,0 +1,3223 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshMultipleMaterials/single_mesh_multiple_materials.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshMultipleMaterials/SceneDebug/single_mesh_multiple_materials.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshMultipleMaterials/single_mesh_multiple_materials.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshMultipleMaterials/SceneDebug/single_mesh_multiple_materials.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshMultipleMaterials/SceneDebug/single_mesh_multiple_materials.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshMultipleMaterials/SceneDebug/single_mesh_multiple_materials.dbgsg.xml
new file mode 100644
index 0000000000..80b80fd67c
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshMultipleMaterials/SceneDebug/single_mesh_multiple_materials.dbgsg.xml
@@ -0,0 +1,849 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshOneMaterial/onemeshonematerial.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshOneMaterial/SceneDebug/onemeshonematerial.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshOneMaterial/onemeshonematerial.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshOneMaterial/SceneDebug/onemeshonematerial.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshOneMaterial/SceneDebug/onemeshonematerial.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshOneMaterial/SceneDebug/onemeshonematerial.dbgsg.xml
new file mode 100644
index 0000000000..87cc4fe260
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/OneMeshOneMaterial/SceneDebug/onemeshonematerial.dbgsg.xml
@@ -0,0 +1,519 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/SceneDebug/shaderball.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/SceneDebug/shaderball.dbgsg
new file mode 100644
index 0000000000..7d070fcea0
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/SceneDebug/shaderball.dbgsg
@@ -0,0 +1,3111 @@
+ProductName: shaderball.dbgsg
+debugSceneGraphVersion: 1
+shaderball
+Node Name: RootNode
+Node Path: RootNode
+Node Type: RootBoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, 1.000000, 0.000000>
+ BasisZ: < 0.000000, 0.000000, 1.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: ShaderBall_1m
+Node Path: RootNode.ShaderBall_1m
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: transform
+Node Path: RootNode.ShaderBall_1m.transform
+Node Type: TransformData
+ Matrix:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: InnerPortion
+Node Path: RootNode.ShaderBall_1m.InnerPortion
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: MaterialBase
+Node Path: RootNode.ShaderBall_1m.MaterialBase
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: InlayRings
+Node Path: RootNode.ShaderBall_1m.InlayRings
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: MainSphere
+Node Path: RootNode.ShaderBall_1m.MainSphere
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: HubCap_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1
+Node Type: MeshData
+ Positions: Count 20476. Hash: 5411361036988924549
+ Normals: Count 20476. Hash: 5915154682063029054
+ FaceList: Count 8676. Hash: 9142863582186575896
+ FaceMaterialIds: Count 8676. Hash: 723360536895379791
+
+Node Name: HubCap_2
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: HubCap_1_optimized
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized
+Node Type: MeshData
+ Positions: Count 4724. Hash: 448283466401665158
+ Normals: Count 4724. Hash: 345267294337234954
+ FaceList: Count 8676. Hash: 11155608373229651496
+ FaceMaterialIds: Count 8676. Hash: 723360536895379791
+
+Node Name: InnerSphere_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1
+Node Type: MeshData
+ Positions: Count 19800. Hash: 17342106809405761922
+ Normals: Count 19800. Hash: 602384960091561079
+ FaceList: Count 9800. Hash: 15975352410309879244
+ FaceMaterialIds: Count 9800. Hash: 2219364576630417284
+
+Node Name: InnerSphere_2
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: InnerSphere_1_optimized
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized
+Node Type: MeshData
+ Positions: Count 5846. Hash: 18229431498904963984
+ Normals: Count 5846. Hash: 12980164457801827192
+ FaceList: Count 9800. Hash: 2914108932212582430
+ FaceMaterialIds: Count 9800. Hash: 2219364576630417284
+
+Node Name: InnerCone_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1
+Node Type: MeshData
+ Positions: Count 192. Hash: 3022774266117638288
+ Normals: Count 192. Hash: 12863565187316537150
+ FaceList: Count 64. Hash: 1255131899577053537
+ FaceMaterialIds: Count 64. Hash: 6312841653578246165
+
+Node Name: InnerCone_2
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: InnerCone_1_optimized
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized
+Node Type: MeshData
+ Positions: Count 65. Hash: 832325255726840940
+ Normals: Count 65. Hash: 14121159448916141450
+ FaceList: Count 64. Hash: 9660474080562375138
+ FaceMaterialIds: Count 64. Hash: 6312841653578246165
+
+Node Name: InnerPost_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1
+Node Type: MeshData
+ Positions: Count 4864. Hash: 7530018531436061848
+ Normals: Count 4864. Hash: 534420091635424803
+ FaceList: Count 2432. Hash: 4330575616942580147
+ FaceMaterialIds: Count 2432. Hash: 12393250111858627709
+
+Node Name: InnerPost_2
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: InnerPost_1_optimized
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized
+Node Type: MeshData
+ Positions: Count 1300. Hash: 15277132209442728123
+ Normals: Count 1300. Hash: 1247055552073340932
+ FaceList: Count 2432. Hash: 16808521883586752319
+ FaceMaterialIds: Count 2432. Hash: 12393250111858627709
+
+Node Name: InnerBaseCuff_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1
+Node Type: MeshData
+ Positions: Count 4096. Hash: 1814004361979755447
+ Normals: Count 4096. Hash: 1760582409511017750
+ FaceList: Count 2048. Hash: 6642755656211284824
+ FaceMaterialIds: Count 2048. Hash: 2795877824940392899
+
+Node Name: InnerBaseCuff_2
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: InnerBaseCuff_1_optimized
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized
+Node Type: MeshData
+ Positions: Count 1122. Hash: 15009434720129565864
+ Normals: Count 1122. Hash: 7245598986723209052
+ FaceList: Count 2048. Hash: 2887888015166354330
+ FaceMaterialIds: Count 2048. Hash: 2795877824940392899
+
+Node Name: Inset_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1
+Node Type: MeshData
+ Positions: Count 1536. Hash: 6247721054948161820
+ Normals: Count 1536. Hash: 16362051041722971623
+ FaceList: Count 768. Hash: 3142075668387852387
+ FaceMaterialIds: Count 768. Hash: 2979441869813298271
+
+Node Name: Inset_2
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: Inset_1_optimized
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized
+Node Type: MeshData
+ Positions: Count 448. Hash: 9520190263881589378
+ Normals: Count 448. Hash: 8658432920439039136
+ FaceList: Count 768. Hash: 8621713142583851338
+ FaceMaterialIds: Count 768. Hash: 2979441869813298271
+
+Node Name: BottomCap_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1
+Node Type: MeshData
+ Positions: Count 960. Hash: 13502046855286963834
+ Normals: Count 960. Hash: 7165134632415312413
+ FaceList: Count 448. Hash: 11458684524699877690
+ FaceMaterialIds: Count 448. Hash: 15444662993354423801
+
+Node Name: BottomCap_2
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: BottomCap_1_optimized
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized
+Node Type: MeshData
+ Positions: Count 257. Hash: 6437758550313952689
+ Normals: Count 257. Hash: 9382966961287919705
+ FaceList: Count 448. Hash: 16093592375171717669
+ FaceMaterialIds: Count 448. Hash: 15444662993354423801
+
+Node Name: InnerCushion_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1
+Node Type: MeshData
+ Positions: Count 54208. Hash: 17548679297809443982
+ Normals: Count 54208. Hash: 18279651495381460361
+ FaceList: Count 27104. Hash: 12714006452420198903
+ FaceMaterialIds: Count 27104. Hash: 12674758055018775830
+
+Node Name: InnerCushion_2
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: InnerCushion_1_optimized
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized
+Node Type: MeshData
+ Positions: Count 13860. Hash: 15965614532178328362
+ Normals: Count 13860. Hash: 7297376140184766040
+ FaceList: Count 27104. Hash: 2523751700832022798
+ FaceMaterialIds: Count 27104. Hash: 12674758055018775830
+
+Node Name: OuterBaseCuff_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1
+Node Type: MeshData
+ Positions: Count 20048. Hash: 3861768905934340307
+ Normals: Count 20048. Hash: 12292053423401502106
+ FaceList: Count 10024. Hash: 4821138438569111218
+ FaceMaterialIds: Count 10024. Hash: 9849297365743356453
+
+Node Name: OuterBaseCuff_2
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: OuterBaseCuff_1_optimized
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized
+Node Type: MeshData
+ Positions: Count 5206. Hash: 5201932106801476439
+ Normals: Count 5206. Hash: 15696187265416627056
+ FaceList: Count 10024. Hash: 10907381836011223214
+ FaceMaterialIds: Count 10024. Hash: 9849297365743356453
+
+Node Name: RingLeft_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1
+Node Type: MeshData
+ Positions: Count 2560. Hash: 10944366330558725569
+ Normals: Count 2560. Hash: 11471590896496428199
+ FaceList: Count 1280. Hash: 2548580276766813978
+ FaceMaterialIds: Count 1280. Hash: 6371267399123018661
+
+Node Name: RingLeft_2
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: RingLeft_1_optimized
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized
+Node Type: MeshData
+ Positions: Count 720. Hash: 14374869925777029719
+ Normals: Count 720. Hash: 2252820527750115179
+ FaceList: Count 1280. Hash: 17583744445000895264
+ FaceMaterialIds: Count 1280. Hash: 6371267399123018661
+
+Node Name: RingRight_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1
+Node Type: MeshData
+ Positions: Count 2560. Hash: 17639843025153488175
+ Normals: Count 2560. Hash: 8564843488923790338
+ FaceList: Count 1280. Hash: 2548580276766813978
+ FaceMaterialIds: Count 1280. Hash: 6371267399123018661
+
+Node Name: RingRight_2
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: RingRight_1_optimized
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized
+Node Type: MeshData
+ Positions: Count 720. Hash: 17033597990859129189
+ Normals: Count 720. Hash: 14263134585377771060
+ FaceList: Count 1280. Hash: 13824345071081010014
+ FaceMaterialIds: Count 1280. Hash: 6371267399123018661
+
+Node Name: RightHub_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1
+Node Type: MeshData
+ Positions: Count 6304. Hash: 11021385291123971383
+ Normals: Count 6304. Hash: 10267084099841111837
+ FaceList: Count 3152. Hash: 17728162485525521181
+ FaceMaterialIds: Count 3152. Hash: 17405713692885844041
+
+Node Name: RightHub_2
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: RightHub_1_optimized
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized
+Node Type: MeshData
+ Positions: Count 1617. Hash: 9820946434895369083
+ Normals: Count 1617. Hash: 16951123277321747448
+ FaceList: Count 3152. Hash: 15437295155178226041
+ FaceMaterialIds: Count 3152. Hash: 17405713692885844041
+
+Node Name: LeftHub_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1
+Node Type: MeshData
+ Positions: Count 6304. Hash: 7564731352768958355
+ Normals: Count 6304. Hash: 8133714814490222392
+ FaceList: Count 3152. Hash: 17728162485525521181
+ FaceMaterialIds: Count 3152. Hash: 17405713692885844041
+
+Node Name: LeftHub_2
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: LeftHub_1_optimized
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized
+Node Type: MeshData
+ Positions: Count 1617. Hash: 8811470420139443913
+ Normals: Count 1617. Hash: 11224729257132823435
+ FaceList: Count 3152. Hash: 16696390019846851737
+ FaceMaterialIds: Count 3152. Hash: 17405713692885844041
+
+Node Name: Inside_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1
+Node Type: MeshData
+ Positions: Count 3520. Hash: 13476777876937219698
+ Normals: Count 3520. Hash: 10561277746451021236
+ FaceList: Count 1760. Hash: 1345243954764462275
+ FaceMaterialIds: Count 1760. Hash: 3100204266221257056
+
+Node Name: Inside_2
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: Inside_1_optimized
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized
+Node Type: MeshData
+ Positions: Count 960. Hash: 1074011803485396393
+ Normals: Count 960. Hash: 16318911598614464642
+ FaceList: Count 1760. Hash: 3382287220404120115
+ FaceMaterialIds: Count 1760. Hash: 3100204266221257056
+
+Node Name: MainOuterSphere_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1
+Node Type: MeshData
+ Positions: Count 18912. Hash: 15956257973657753552
+ Normals: Count 18912. Hash: 9328348641512406334
+ FaceList: Count 9456. Hash: 9836933646038198686
+ FaceMaterialIds: Count 9456. Hash: 13982281543095132650
+
+Node Name: MainOuterSphere_2
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_2
+Node Type: BoneData
+ WorldTransform:
+ BasisX: < 1.000000, 0.000000, 0.000000>
+ BasisY: < 0.000000, -0.000000, 1.000000>
+ BasisZ: < 0.000000, -1.000000, -0.000000>
+ Transl: < 0.000000, 0.000000, 0.000000>
+
+Node Name: MainOuterSphere_1_optimized
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized
+Node Type: MeshData
+ Positions: Count 4891. Hash: 9579089515723090907
+ Normals: Count 4891. Hash: 10089610259011330329
+ FaceList: Count 9456. Hash: 13541126452398082145
+ FaceMaterialIds: Count 9456. Hash: 13982281543095132650
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 20476. Hash: 10688945422788452939
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 20476. Hash: 1387390223232454000
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 20476. Hash: 4424021631256816544
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 20476. Hash: 9768152532901400557
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 20476. Hash: 4890305528292926235
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 20476. Hash: 309820643999247955
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 20476. Hash: 10688945422788452939
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 20476. Hash: 1387390223232454000
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 4724. Hash: 10265340188340999982
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 4724. Hash: 6393506322209434620
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 4724. Hash: 7072046838448900487
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 4724. Hash: 14469479861311642848
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4724. Hash: 14586570136206675867
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4724. Hash: 1080930468361041453
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.HubCap.HubCap_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 19800. Hash: 9998270082112342253
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 19800. Hash: 715698668253946311
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 19800. Hash: 9689144294054390217
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 19800. Hash: 13129471596255615133
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 19800. Hash: 12915864712175384367
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 19800. Hash: 704744783983559605
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 19800. Hash: 9998270082112342253
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 19800. Hash: 715698668253946311
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 5846. Hash: 2128276120164603588
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 5846. Hash: 954788723450394678
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 5846. Hash: 14309642535096835998
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 5846. Hash: 2996000735336843208
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 5846. Hash: 6423899825309547347
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 5846. Hash: 6861847030641362531
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InnerPortion.InnerSphere.InnerSphere_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 192. Hash: 10645867109602892598
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 192. Hash: 7257961874201179082
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 192. Hash: 12720324392877726426
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 192. Hash: 7937958557505694755
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 192. Hash: 15065829696130008213
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 192. Hash: 14378088137727336097
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 192. Hash: 10645867109602892598
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 192. Hash: 7257961874201179082
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 65. Hash: 3145658351065228323
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 65. Hash: 13102825703658386866
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 65. Hash: 14651886668877289638
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 65. Hash: 7706988068999921308
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 65. Hash: 1183045102730537867
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 65. Hash: 15200278891890596008
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCone.InnerCone_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 4864. Hash: 5283498994389857134
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 4864. Hash: 4759806696539235318
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 4864. Hash: 1916980755154570809
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4864. Hash: 3641075817419129841
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 4864. Hash: 1597884606887295389
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4864. Hash: 12470368568863176335
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 4864. Hash: 5283498994389857134
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 4864. Hash: 4759806696539235318
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 1300. Hash: 519927422840758162
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 1300. Hash: 16690819534142395524
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 1300. Hash: 13697492049473980098
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 1300. Hash: 16069718749273082363
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1300. Hash: 9503213552298852479
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1300. Hash: 14920629477034919393
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerPost.InnerPost_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 4096. Hash: 12344372623177285558
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 4096. Hash: 3415525735687273566
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 4096. Hash: 1937219152553164558
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4096. Hash: 16718347243549159919
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 4096. Hash: 7775661729866538946
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4096. Hash: 16465645522600859391
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 4096. Hash: 12344372623177285558
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 4096. Hash: 3415525735687273566
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 1122. Hash: 10794215007683911939
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 1122. Hash: 4030215540982392192
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 1122. Hash: 14289595630739500233
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 1122. Hash: 13010448485976282215
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1122. Hash: 8318401526835048407
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1122. Hash: 100095329364523248
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerBaseCuff.InnerBaseCuff_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 1536. Hash: 7123339701675171032
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 1536. Hash: 15827204344457762670
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 1536. Hash: 15732245908985477324
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1536. Hash: 865397990859725823
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 1536. Hash: 2552281640891423471
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1536. Hash: 17779645716491562667
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 1536. Hash: 7123339701675171032
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 1536. Hash: 15827204344457762670
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 448. Hash: 11533511688039530581
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 448. Hash: 6463578982826635244
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 448. Hash: 10590255987412720146
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 448. Hash: 17744412650281038495
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 448. Hash: 8278337182397882868
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 448. Hash: 8818080862566813062
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.Inset.Inset_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 960. Hash: 12059380739436291361
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 960. Hash: 17894062399627363441
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 960. Hash: 3025207993250150716
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 960. Hash: 909667023812047269
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 960. Hash: 9807712812840041710
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 960. Hash: 15826838159231044203
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 960. Hash: 12059380739436291361
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 960. Hash: 17894062399627363441
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 257. Hash: 8823641736072761245
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 257. Hash: 17988941723121644388
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 257. Hash: 8180735114915510878
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 257. Hash: 6608315278879931556
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 257. Hash: 15606348252975307518
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 257. Hash: 9909736394462106525
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.BottomCap.BottomCap_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 54208. Hash: 3444203649101035485
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 54208. Hash: 937532470362399061
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 54208. Hash: 196567085853229565
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 54208. Hash: 1716600532837684655
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 54208. Hash: 2905235470236164097
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 54208. Hash: 2074363216216487237
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 54208. Hash: 3444203649101035485
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 54208. Hash: 937532470362399061
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 13860. Hash: 263381874971540959
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 13860. Hash: 15191673020616208011
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 13860. Hash: 7105458185902008309
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 13860. Hash: 16259705089531364237
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 13860. Hash: 16022317673583270139
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 13860. Hash: 7251784463761381809
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.InnerCushion.InnerCushion_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 20048. Hash: 10464397683020008867
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 20048. Hash: 11067273583889078226
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 20048. Hash: 15901168792190323178
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 20048. Hash: 552570814640404138
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 20048. Hash: 17726428588184726937
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 20048. Hash: 7508591493894188819
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 20048. Hash: 10464397683020008867
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 20048. Hash: 11067273583889078226
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 5206. Hash: 1074257132915638034
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 5206. Hash: 2243653809093009497
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 5206. Hash: 11559777087289074275
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 5206. Hash: 15450183130901763011
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 5206. Hash: 15359221084106995089
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 5206. Hash: 8652443944286435468
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MaterialBase.OuterBaseCuff.OuterBaseCuff_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 14931201357194905697
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 5600314145323623005
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 2560. Hash: 11738661055172304644
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 2560. Hash: 320620113692599118
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 2560. Hash: 8466587534284734762
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 2560. Hash: 3318206549561696188
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 14931201357194905697
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 5600314145323623005
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 720. Hash: 75483450873662317
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 720. Hash: 3793407172213641704
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 720. Hash: 2508676912793167321
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 720. Hash: 2013136453053212946
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 720. Hash: 9302779689053257196
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 720. Hash: 16922723248982534245
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingLeft.RingLeft_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 9568588494434360329
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 5573555818259644549
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 2560. Hash: 12082144485035076372
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 2560. Hash: 5616878210949329467
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 2560. Hash: 4057154333260499171
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 2560. Hash: 1620460765416970456
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 9568588494434360329
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 2560. Hash: 5573555818259644549
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 720. Hash: 3542867785718437760
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 720. Hash: 5575788853295372734
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 720. Hash: 8244955966647049157
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 720. Hash: 17763430282605007327
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 720. Hash: 5442657821959315522
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 720. Hash: 12477592739739533067
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.InlayRings.RingRight.RingRight_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 4609122246850169975
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 2696528076485355457
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 6304. Hash: 6640465288865380105
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 6304. Hash: 133343330720363387
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 6304. Hash: 790774688340154169
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 6304. Hash: 3046294637431015510
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 4609122246850169975
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 2696528076485355457
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 1617. Hash: 16761061667647714654
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 1617. Hash: 14954885971875692232
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 1617. Hash: 37061345418264916
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 1617. Hash: 7368059604555723833
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1617. Hash: 6244533771017459078
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1617. Hash: 6416015160247779547
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.RightHub.RightHub_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 2524875548439506384
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 89810986084680009
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 6304. Hash: 1044733215619569246
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 6304. Hash: 15252409165383740719
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 6304. Hash: 3184716392697283856
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 6304. Hash: 4969210758291089995
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 2524875548439506384
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 6304. Hash: 89810986084680009
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 1617. Hash: 8467946356718878053
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 1617. Hash: 2373603727160338558
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 1617. Hash: 1521191693628786862
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 1617. Hash: 7175852234718691900
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1617. Hash: 12283058591680528758
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 1617. Hash: 14516337485055158228
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.LeftHub.LeftHub_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 3520. Hash: 7734180808251274182
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 3520. Hash: 13560118186140352568
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 3520. Hash: 5538036360908204376
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 3520. Hash: 470358662493460341
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 3520. Hash: 13801426056203770982
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 3520. Hash: 8463107387658894201
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 3520. Hash: 7734180808251274182
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 3520. Hash: 13560118186140352568
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 960. Hash: 2691029117997309291
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 960. Hash: 10093724573967674240
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 960. Hash: 1221219959437752888
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 960. Hash: 1294720383009806722
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 960. Hash: 10294793677923893113
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 960. Hash: 6108415656799664788
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.Inside.Inside_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 18912. Hash: 4120783891454032649
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 18912. Hash: 9011003754405408275
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 18912. Hash: 12406712159692783345
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 18912. Hash: 7868083933985729169
+ GenerationMethod: 1
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 18912. Hash: 1990603474898794477
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 18912. Hash: 4812378464029296668
+ GenerationMethod: 1
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_2.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 18912. Hash: 4120783891454032649
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_2.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 18912. Hash: 9011003754405408275
+ UVCustomName: Unwrapped
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_2.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
+Node Name: Tiled
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized.Tiled
+Node Type: MeshVertexUVData
+ UVs: Count 4891. Hash: 15498889522919365505
+ UVCustomName: Tiled
+
+Node Name: Unwrapped
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized.Unwrapped
+Node Type: MeshVertexUVData
+ UVs: Count 4891. Hash: 15832520573612498718
+ UVCustomName: Unwrapped
+
+Node Name: TangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized.TangentSet_0
+Node Type: MeshVertexTangentData
+ Tangents: Count 4891. Hash: 6697133368486369688
+ GenerationMethod: 1
+ SetIndex: 0
+
+Node Name: TangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized.TangentSet_1
+Node Type: MeshVertexTangentData
+ Tangents: Count 4891. Hash: 18420832496569008358
+ GenerationMethod: 1
+ SetIndex: 1
+
+Node Name: BitangentSet_0
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized.BitangentSet_0
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4891. Hash: 2267250201584370787
+ GenerationMethod: 1
+
+Node Name: BitangentSet_1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized.BitangentSet_1
+Node Type: MeshVertexBitangentData
+ Bitangents: Count 4891. Hash: 7889928104085840247
+ GenerationMethod: 1
+
+Node Name: blinn1
+Node Path: RootNode.ShaderBall_1m.MainSphere.MainOuterSphere.MainOuterSphere_1_optimized.blinn1
+Node Type: MaterialData
+ MaterialName: blinn1
+ UniqueId: 2076548245838624187
+ IsNoDraw: false
+ DiffuseColor: < 0.800000, 0.800000, 0.800000>
+ SpecularColor: < 0.500000, 0.500000, 0.500000>
+ EmissiveColor: < 0.000000, 0.000000, 0.000000>
+ Opacity: 1.000000
+ Shininess: 6.311791
+ UseColorMap: Not set
+ BaseColor: Not set
+ UseMetallicMap: Not set
+ MetallicFactor: Not set
+ UseRoughnessMap: Not set
+ RoughnessFactor: Not set
+ UseEmissiveMap: Not set
+ EmissiveIntensity: Not set
+ UseAOMap: Not set
+ DiffuseTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+ SpecularTexture:
+ BumpTexture:
+ NormalTexture:
+ MetallicTexture:
+ RoughnessTexture:
+ AmbientOcclusionTexture:
+ EmissiveTexture:
+ BaseColorTexture: ShaderBall/_dev_shaderball_00_basecolor.png
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/SceneDebug/shaderball.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/SceneDebug/shaderball.dbgsg.xml
new file mode 100644
index 0000000000..acff9e5f02
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/SceneDebug/shaderball.dbgsg.xml
@@ -0,0 +1,9491 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/_dev_shaderball_00_basecolor.png b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/_dev_shaderball_00_basecolor.png
new file mode 100644
index 0000000000..415ca3e521
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/_dev_shaderball_00_basecolor.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:93a7e033d9fb0fcac221647322bde03716643d789390f79078c4fcc37ecfd005
+size 68327
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/shaderball.fbx b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/shaderball.fbx
new file mode 100644
index 0000000000..caf6dcbe8f
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/ShaderBall/shaderball.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6e63a55a35c749a16a03e10a1f53a48bd426c61db80151de080235b14cf6b70d
+size 2479344
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingLOD/lodtest.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingLOD/SceneDebug/lodtest.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingLOD/lodtest.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingLOD/SceneDebug/lodtest.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingLOD/SceneDebug/lodtest.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingLOD/SceneDebug/lodtest.dbgsg.xml
new file mode 100644
index 0000000000..d1af4198b5
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingLOD/SceneDebug/lodtest.dbgsg.xml
@@ -0,0 +1,2007 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingPhysics/physicstest.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingPhysics/SceneDebug/physicstest.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingPhysics/physicstest.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingPhysics/SceneDebug/physicstest.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingPhysics/SceneDebug/physicstest.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingPhysics/SceneDebug/physicstest.dbgsg.xml
new file mode 100644
index 0000000000..b22eb14fc6
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/SoftNamingPhysics/SceneDebug/physicstest.dbgsg.xml
@@ -0,0 +1,817 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshLinkedMaterials/multiple_mesh_linked_materials.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshLinkedMaterials/SceneDebug/multiple_mesh_linked_materials.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshLinkedMaterials/multiple_mesh_linked_materials.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshLinkedMaterials/SceneDebug/multiple_mesh_linked_materials.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshLinkedMaterials/SceneDebug/multiple_mesh_linked_materials.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshLinkedMaterials/SceneDebug/multiple_mesh_linked_materials.dbgsg.xml
new file mode 100644
index 0000000000..3eaf018fb6
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshLinkedMaterials/SceneDebug/multiple_mesh_linked_materials.dbgsg.xml
@@ -0,0 +1,1345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshOneMaterial/multiple_mesh_one_material.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshOneMaterial/SceneDebug/multiple_mesh_one_material.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshOneMaterial/multiple_mesh_one_material.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshOneMaterial/SceneDebug/multiple_mesh_one_material.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshOneMaterial/SceneDebug/multiple_mesh_one_material.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshOneMaterial/SceneDebug/multiple_mesh_one_material.dbgsg.xml
new file mode 100644
index 0000000000..39ac33f654
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshOneMaterial/SceneDebug/multiple_mesh_one_material.dbgsg.xml
@@ -0,0 +1,1015 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/multiple_mesh_multiple_material.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/multiple_mesh_multiple_material.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material.dbgsg.xml
new file mode 100644
index 0000000000..c41c1414a4
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material.dbgsg.xml
@@ -0,0 +1,1015 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/multiple_mesh_multiple_material_override.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material_override.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/multiple_mesh_multiple_material_override.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material_override.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material_override.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material_override.dbgsg.xml
new file mode 100644
index 0000000000..01167ec0ee
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/TwoMeshTwoMaterial/SceneDebug/multiple_mesh_multiple_material_override.dbgsg.xml
@@ -0,0 +1,817 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/VertexColor/vertexcolor.dbgsg b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/VertexColor/SceneDebug/vertexcolor.dbgsg
similarity index 100%
rename from AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/VertexColor/vertexcolor.dbgsg
rename to AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/VertexColor/SceneDebug/vertexcolor.dbgsg
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/VertexColor/SceneDebug/vertexcolor.dbgsg.xml b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/VertexColor/SceneDebug/vertexcolor.dbgsg.xml
new file mode 100644
index 0000000000..f5caa70d63
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/assets/VertexColor/SceneDebug/vertexcolor.dbgsg.xml
@@ -0,0 +1,576 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py
index 71f200074c..c28dfa64f2 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py
@@ -21,8 +21,8 @@ from ly_test_tools.o3de.asset_processor import ASSET_PROCESSOR_PLATFORM_MAP
from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
from ..ap_fixtures.ap_setup_fixture import ap_setup_fixture as ap_setup_fixture
from ..ap_fixtures.ap_config_backup_fixture import ap_config_backup_fixture as ap_config_backup_fixture
-from ..ap_fixtures.ap_config_default_platform_fixture import ap_config_default_platform_fixture as ap_config_default_platform_fixture
-
+from ..ap_fixtures.ap_config_default_platform_fixture \
+ import ap_config_default_platform_fixture as ap_config_default_platform_fixture
# Import LyShared
import ly_test_tools.o3de.pipeline_utils as utils
@@ -33,6 +33,7 @@ logger = logging.getLogger(__name__)
# Helper: variables we will use for parameter values in the test:
targetProjects = ["AutomatedTesting"]
+
@pytest.fixture
@pytest.mark.SUITE_sandbox
def local_resources(request, workspace, ap_setup_fixture):
@@ -54,25 +55,30 @@ class BlackboxAssetTest:
blackbox_fbx_tests = [
pytest.param(
BlackboxAssetTest(
- test_name= "OneMeshOneMaterial_RunAP_SuccessWithMatchingProducts",
- asset_folder= "OneMeshOneMaterial",
+ test_name="OneMeshOneMaterial_RunAP_SuccessWithMatchingProducts",
+ asset_folder="OneMeshOneMaterial",
scene_debug_file="onemeshonematerial.dbgsg",
- assets = [
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "OneMeshOneMaterial.fbx",
- uuid = b"8a9164adb84859be893e18aa819438e1",
- jobs = [
+ source_file_name="OneMeshOneMaterial.fbx",
+ uuid=b"8a9164adb84859be893e18aa819438e1",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
+ job_key="Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=1,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='onemeshonematerial/onemeshonematerial.dbgsg',
sub_id=1918494907,
- asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b')
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='onemeshonematerial/onemeshonematerial.dbgsg.xml',
+ sub_id=556355570,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ )
]
),
]
@@ -86,25 +92,30 @@ blackbox_fbx_tests = [
BlackboxAssetTest(
# Verifies that the soft naming convention feature with level of detail meshes works.
# https://docs.aws.amazon.com/lumberyard/latest/userguide/char-fbx-importer-soft-naming.html
- test_name= "SoftNamingLOD_RunAP_SuccessWithMatchingProducts",
- asset_folder= "SoftNamingLOD",
+ test_name="SoftNamingLOD_RunAP_SuccessWithMatchingProducts",
+ asset_folder="SoftNamingLOD",
scene_debug_file="lodtest.dbgsg",
- assets = [
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "lodtest.fbx",
- uuid = b"44c8627fe2c25aae91fe3ff9547be3b9",
- jobs = [
+ source_file_name="lodtest.fbx",
+ uuid=b"44c8627fe2c25aae91fe3ff9547be3b9",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
+ job_key="Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=22,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='softnaminglod/lodtest.dbgsg',
sub_id=-632012261,
- asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b')
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='softnaminglod/lodtest.dbgsg.xml',
+ sub_id=-2036095434,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ )
]
),
]
@@ -118,31 +129,36 @@ blackbox_fbx_tests = [
BlackboxAssetTest(
# Verifies that the soft naming convention feature with physics proxies works.
# https://docs.aws.amazon.com/lumberyard/latest/userguide/char-fbx-importer-soft-naming.html
- test_name= "SoftNamingPhysics_RunAP_SuccessWithMatchingProducts",
- asset_folder= "SoftNamingPhysics",
+ test_name="SoftNamingPhysics_RunAP_SuccessWithMatchingProducts",
+ asset_folder="SoftNamingPhysics",
scene_debug_file="physicstest.dbgsg",
- assets = [
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "physicstest.fbx",
- uuid = b"df957b7918cf5b029806c73f630fa1c8",
- jobs = [
+ source_file_name="physicstest.fbx",
+ uuid=b"df957b7918cf5b029806c73f630fa1c8",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
+ job_key="Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=14,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='softnamingphysics/physicstest.dbgsg',
sub_id=-740411732,
asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'
),
+ asset_db_utils.DBProduct(
+ product_name='softnamingphysics/physicstest.dbgsg.xml',
+ sub_id=330338417,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ ),
asset_db_utils.DBProduct(
product_name="softnamingphysics/physicstest.pxmesh",
sub_id=640975857,
asset_type=b"7a2871b95eab4de0a901b0d2c6920ddb"
- ),
+ )
]
),
]
@@ -152,25 +168,29 @@ blackbox_fbx_tests = [
),
pytest.param(
BlackboxAssetTest(
- test_name= "MultipleMeshOneMaterial_RunAP_SuccessWithMatchingProducts",
- asset_folder= "TwoMeshOneMaterial",
+ test_name="MultipleMeshOneMaterial_RunAP_SuccessWithMatchingProducts",
+ asset_folder="TwoMeshOneMaterial",
scene_debug_file="multiple_mesh_one_material.dbgsg",
- assets = [
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "multiple_mesh_one_material.fbx",
- uuid = b"597618fd497659a1b197a015fe47aa95",
- jobs = [
+ source_file_name="multiple_mesh_one_material.fbx",
+ uuid=b"597618fd497659a1b197a015fe47aa95",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
+ job_key="Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=2,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='twomeshonematerial/multiple_mesh_one_material.dbgsg',
sub_id=2077268018,
- asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b')
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='twomeshonematerial/multiple_mesh_one_material.dbgsg.xml',
+ sub_id=1321067730,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868')
]
),
]
@@ -183,26 +203,31 @@ blackbox_fbx_tests = [
pytest.param(
BlackboxAssetTest(
# Verifies whether multiple meshes can share linked materials
- test_name= "MultipleMeshLinkedMaterials_RunAP_SuccessWithMatchingProducts",
- asset_folder= "TwoMeshLinkedMaterials",
- scene_debug_file= "multiple_mesh_linked_materials.dbgsg",
- assets = [
+ test_name="MultipleMeshLinkedMaterials_RunAP_SuccessWithMatchingProducts",
+ asset_folder="TwoMeshLinkedMaterials",
+ scene_debug_file="multiple_mesh_linked_materials.dbgsg",
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "multiple_mesh_linked_materials.fbx",
- uuid = b"25d8301c2eef5dc7bded310db8ea608d",
- jobs = [
+ source_file_name="multiple_mesh_linked_materials.fbx",
+ uuid=b"25d8301c2eef5dc7bded310db8ea608d",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
- platform= "pc",
+ job_key="Scene compilation",
+ platform="pc",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=2,
- products= [
+ products=[
asset_db_utils.DBProduct(
product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.dbgsg',
sub_id=-1898461950,
asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'
+ ),
+ asset_db_utils.DBProduct(
+ product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.dbgsg.xml',
+ sub_id=-772341513,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
)
]
),
@@ -216,26 +241,31 @@ blackbox_fbx_tests = [
pytest.param(
BlackboxAssetTest(
# Verifies a mesh with multiple materials
- test_name= "SingleMeshMultipleMaterials_RunAP_SuccessWithMatchingProducts",
- asset_folder= "OneMeshMultipleMaterials",
+ test_name="SingleMeshMultipleMaterials_RunAP_SuccessWithMatchingProducts",
+ asset_folder="OneMeshMultipleMaterials",
scene_debug_file="single_mesh_multiple_materials.dbgsg",
- assets = [
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "single_mesh_multiple_materials.fbx",
- uuid = b"f08fd585dfa35881b4bf86637da5e858",
- jobs = [
+ source_file_name="single_mesh_multiple_materials.fbx",
+ uuid=b"f08fd585dfa35881b4bf86637da5e858",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
- platform= "pc",
+ job_key="Scene compilation",
+ platform="pc",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=1,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='onemeshmultiplematerials/single_mesh_multiple_materials.dbgsg',
sub_id=-262822238,
- asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b')
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='onemeshmultiplematerials/single_mesh_multiple_materials.dbgsg.xml',
+ sub_id=1462358160,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ )
]
),
]
@@ -265,7 +295,12 @@ blackbox_fbx_tests = [
asset_db_utils.DBProduct(
product_name='vertexcolor/vertexcolor.dbgsg',
sub_id=-1543877170,
- asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b')
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='vertexcolor/vertexcolor.dbgsg.xml',
+ sub_id=1743516586,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ )
]
),
]
@@ -277,25 +312,30 @@ blackbox_fbx_tests = [
),
pytest.param(
BlackboxAssetTest(
- test_name= "MotionTest_RunAP_SuccessWithMatchingProducts",
- asset_folder= "Motion",
+ test_name="MotionTest_RunAP_SuccessWithMatchingProducts",
+ asset_folder="Motion",
scene_debug_file="Jack_Idle_Aim_ZUp.dbgsg",
- assets = [
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "Jack_Idle_Aim_ZUp.fbx",
- uuid = b"eda904ae0e145f8b973d57fc5809918b",
- jobs = [
+ source_file_name="Jack_Idle_Aim_ZUp.fbx",
+ uuid=b"eda904ae0e145f8b973d57fc5809918b",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
+ job_key="Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='motion/jack_idle_aim_zup.dbgsg',
sub_id=-517610290,
asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='motion/jack_idle_aim_zup.dbgsg.xml',
+ sub_id=-817863914,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ ),
asset_db_utils.DBProduct(
product_name='motion/jack_idle_aim_zup.motion',
sub_id=186392073,
@@ -307,33 +347,69 @@ blackbox_fbx_tests = [
]
),
),
+ pytest.param(
+ BlackboxAssetTest(
+ test_name="ShaderBall_RunAP_SuccessWithMatchingProducts",
+ asset_folder="ShaderBall",
+ scene_debug_file="shaderball.dbgsg",
+ assets=[
+ asset_db_utils.DBSourceAsset(
+ source_file_name="shaderball.fbx",
+ uuid=b"48181ba8038e5193997540fc8dffb06d",
+ jobs=[
+ asset_db_utils.DBJob(
+ job_key="Scene compilation",
+ builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
+ status=4,
+ error_count=0,
+ warning_count=30,
+ products=[
+ asset_db_utils.DBProduct(
+ product_name='shaderball/shaderball.dbgsg',
+ sub_id=-1607815784,
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='shaderball/shaderball.dbgsg.xml',
+ sub_id=-1153118555,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'),
+ ]
+ ),
+ ]
+ )
+ ]
+ ),
+ ),
]
-
blackbox_fbx_special_tests = [
pytest.param(
BlackboxAssetTest(
- test_name= "MultipleMeshMultipleMaterial_MultipleAssetInfo_RunAP_SuccessWithMatchingProducts",
- asset_folder= "TwoMeshTwoMaterial",
- override_asset_folder = "OverrideAssetInfoForTwoMeshTwoMaterial",
+ test_name="MultipleMeshMultipleMaterial_MultipleAssetInfo_RunAP_SuccessWithMatchingProducts",
+ asset_folder="TwoMeshTwoMaterial",
+ override_asset_folder="OverrideAssetInfoForTwoMeshTwoMaterial",
scene_debug_file="multiple_mesh_multiple_material.dbgsg",
override_scene_debug_file="multiple_mesh_multiple_material_override.dbgsg",
- assets = [
+ assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "multiple_mesh_multiple_material.fbx",
- uuid = b"b5915fb874af5c8a866ccabbddb57595",
- jobs = [
+ source_file_name="multiple_mesh_multiple_material.fbx",
+ uuid=b"b5915fb874af5c8a866ccabbddb57595",
+ jobs=[
asset_db_utils.DBJob(
job_key="Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=2,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='twomeshtwomaterial/multiple_mesh_multiple_material.dbgsg',
sub_id=896980093,
- asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b')
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='twomeshtwomaterial/multiple_mesh_multiple_material.dbgsg.xml',
+ sub_id=-1556988544,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ )
]
),
]
@@ -341,20 +417,25 @@ blackbox_fbx_special_tests = [
],
override_assets=[
asset_db_utils.DBSourceAsset(
- source_file_name = "multiple_mesh_multiple_material.fbx",
- uuid = b"b5915fb874af5c8a866ccabbddb57595",
- jobs = [
+ source_file_name="multiple_mesh_multiple_material.fbx",
+ uuid=b"b5915fb874af5c8a866ccabbddb57595",
+ jobs=[
asset_db_utils.DBJob(
- job_key= "Scene compilation",
+ job_key="Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=2,
- products = [
+ products=[
asset_db_utils.DBProduct(
product_name='twomeshtwomaterial/multiple_mesh_multiple_material.dbgsg',
sub_id=896980093,
- asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b')
+ asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
+ asset_db_utils.DBProduct(
+ product_name='twomeshtwomaterial/multiple_mesh_multiple_material.dbgsg.xml',
+ sub_id=-1556988544,
+ asset_type=b'51f376140d774f369ac67ed70a0ac868'
+ )
]
),
]
@@ -378,29 +459,26 @@ class TestsFBX_AllPlatforms(object):
@pytest.mark.BAT
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize("blackbox_param", blackbox_fbx_tests)
- def test_FBXBlackboxTest_SourceFiles_Processed_ResultInExpectedProducts(self, workspace,
- ap_setup_fixture, asset_processor, project,
- blackbox_param):
+ def test_FBXBlackboxTest_SourceFiles_Processed_ResultInExpectedProducts(self, workspace, ap_setup_fixture,
+ asset_processor, project, blackbox_param):
"""
- Please see run_fbx_test(...) for details
+ Please see run_fbx_test(...) for details
Test Steps:
1. Determine if blackbox is set to none
2. Run FBX Test
+
"""
if blackbox_param == None:
return
- self.run_fbx_test(workspace, ap_setup_fixture,
- asset_processor, project, blackbox_param)
+ self.run_fbx_test(workspace, ap_setup_fixture, asset_processor, project, blackbox_param)
@pytest.mark.BAT
@pytest.mark.SUITE_sandbox
@pytest.mark.parametrize("blackbox_param", blackbox_fbx_special_tests)
- def test_FBXBlackboxTest_AssetInfoModified_AssetReprocessed_ResultInExpectedProducts(self,
- workspace, ap_setup_fixture,
- asset_processor, project,
- blackbox_param):
+ def test_FBXBlackboxTest_AssetInfoModified_AssetReprocessed_ResultInExpectedProducts(
+ self, workspace, ap_setup_fixture, asset_processor, project, blackbox_param):
"""
Please see run_fbx_test(...) for details
@@ -429,8 +507,21 @@ class TestsFBX_AllPlatforms(object):
product.product_name = job.platform + "/" \
+ product.product_name
+ def compare_scene_debug_file(self, asset_processor, expected_file_path, actual_file_path):
+ debug_graph_path = os.path.join(asset_processor.project_test_cache_folder(), actual_file_path)
+ expected_debug_graph_path = os.path.join(asset_processor.project_test_source_folder(), "SceneDebug", expected_file_path)
+
+ logger.info(f"Parsing scene graph: {debug_graph_path}")
+ with open(debug_graph_path, "r") as scene_file:
+ actual_lines = scene_file.readlines()
+
+ logger.info(f"Parsing scene graph: {expected_debug_graph_path}")
+ with open(expected_debug_graph_path, "r") as scene_file:
+ expected_lines = scene_file.readlines()
+
+ assert utils.compare_lists(actual_lines, expected_lines), "Scene mismatch"
def run_fbx_test(self, workspace, ap_setup_fixture, asset_processor,
- project, blackbox_params: BlackboxAssetTest, overrideAsset = False):
+ project, blackbox_params: BlackboxAssetTest, overrideAsset=False):
"""
These tests work by having the test case ingest the test data and determine the run pattern.
Tests will process scene settings files and will additionally do a verification against a provided debug file
@@ -469,32 +560,27 @@ class TestsFBX_AllPlatforms(object):
expected_product_list.append(expected_product.product_name)
missing_assets, _ = utils.compare_assets_with_cache(expected_product_list,
- asset_processor.project_test_cache_folder())
+ asset_processor.project_test_cache_folder())
- assert not missing_assets, f'The following assets were expected to be in, but not found in cache: {str(missing_assets)}'
+ assert not missing_assets, \
+ f'The following assets were expected to be in, but not found in cache: {str(missing_assets)}'
# Load the asset database.
db_path = os.path.join(asset_processor.temp_asset_root(), "Cache",
"assetdb.sqlite")
cache_root = os.path.dirname(os.path.join(asset_processor.temp_asset_root(), "Cache",
- ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
+ ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
if blackbox_params.scene_debug_file:
- scene_debug_file = blackbox_params.override_scene_debug_file if overrideAsset\
+ scene_debug_file = blackbox_params.override_scene_debug_file if overrideAsset \
else blackbox_params.scene_debug_file
- debug_graph_path = os.path.join(asset_processor.project_test_cache_folder(), blackbox_params.scene_debug_file)
- expected_debug_graph_path = os.path.join(asset_processor.project_test_source_folder(), scene_debug_file)
+ self.compare_scene_debug_file(asset_processor, scene_debug_file, blackbox_params.scene_debug_file)
- logger.info(f"Parsing scene graph: {debug_graph_path}")
- with open(debug_graph_path, "r") as scene_file:
- actual_lines = scene_file.readlines()
-
- logger.info(f"Parsing scene graph: {expected_debug_graph_path}")
- with open(expected_debug_graph_path, "r") as scene_file:
- expected_lines = scene_file.readlines()
-
- assert utils.compare_lists(actual_lines, expected_lines), "Scene mismatch"
+ # Run again for the .dbgsg.xml file
+ self.compare_scene_debug_file(asset_processor,
+ scene_debug_file + ".xml",
+ blackbox_params.scene_debug_file + ".xml")
# Check that each given source asset resulted in the expected jobs and products.
self.populateAssetInfo(workspace, project, assetsToValidate)
diff --git a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py
index cbb6102a44..88188aa6c0 100755
--- a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py
+++ b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/base.py
@@ -8,7 +8,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import os
import logging
-import subprocess
+import sys
import pytest
import time
@@ -52,7 +52,7 @@ class TestAutomationBase:
cls._kill_ly_processes()
def _run_test(self, request, workspace, editor, testcase_module, extra_cmdline_args=[], batch_mode=True,
- autotest_mode=True, use_null_renderer=True):
+ autotest_mode=True, use_null_renderer=True, enable_prefab_system=True):
test_starttime = time.time()
self.logger = logging.getLogger(__name__)
errors = []
@@ -97,6 +97,11 @@ class TestAutomationBase:
pycmd += ["-BatchMode"]
if autotest_mode:
pycmd += ["-autotest_mode"]
+ if enable_prefab_system:
+ pycmd += ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]
+ else:
+ pycmd += ["--regset=/Amazon/Preferences/EnablePrefabSystem=false"]
+
pycmd += extra_cmdline_args
editor.args.extend(pycmd) # args are added to the WinLauncher start command
editor.start(backupFiles = False, launch_ap = False)
@@ -123,7 +128,8 @@ class TestAutomationBase:
errors.append(TestRunError("FAILED TEST", error_str))
if return_code and return_code != TestAutomationBase.TEST_FAIL_RETCODE: # Crashed
crash_info = "-- No crash log available --"
- crash_log = os.path.join(workspace.paths.project_log(), 'error.log')
+ crash_log = workspace.paths.crash_log()
+
try:
waiter.wait_for(lambda: os.path.exists(crash_log), timeout=TestAutomationBase.WAIT_FOR_CRASH_LOG)
except AssertionError:
@@ -165,7 +171,7 @@ class TestAutomationBase:
for line in f.readlines():
error_str += f"|{log_basename}| {line}"
except Exception as ex:
- error_str += "-- No log available --"
+ error_str += f"-- No log available ({ex})--"
pytest.fail(error_str)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt
index bf42579970..1fc71da972 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt
@@ -7,60 +7,6 @@
#
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED)
- ly_add_pytest(
- NAME AutomatedTesting::EditorTests_Main
- TEST_SUITE main
- TEST_SERIAL
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
- PYTEST_MARKS "not REQUIRES_gpu"
- RUNTIME_DEPENDENCIES
- Legacy::Editor
- AZ::AssetProcessor
- AutomatedTesting.Assets
- COMPONENT
- Editor
- )
-
- ly_add_pytest(
- NAME AutomatedTesting::EditorTests_Main_GPU
- TEST_SUITE main
- TEST_SERIAL
- TEST_REQUIRES gpu
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
- PYTEST_MARKS "REQUIRES_gpu"
- RUNTIME_DEPENDENCIES
- Legacy::Editor
- AZ::AssetProcessor
- AutomatedTesting.Assets
- COMPONENT
- Editor
- )
-
- ly_add_pytest(
- NAME AutomatedTesting::EditorTests_Periodic
- TEST_SUITE periodic
- TEST_SERIAL
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py
- RUNTIME_DEPENDENCIES
- Legacy::Editor
- AZ::AssetProcessor
- AutomatedTesting.Assets
- COMPONENT
- Editor
- )
-
- ly_add_pytest(
- NAME AutomatedTesting::EditorTests_Sandbox
- TEST_SUITE sandbox
- TEST_SERIAL
- PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
- RUNTIME_DEPENDENCIES
- Legacy::Editor
- AZ::AssetProcessor
- AutomatedTesting.Assets
- COMPONENT
- Editor
- )
ly_add_pytest(
NAME AutomatedTesting::EditorTests_Main_Optimized
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py
index 2a91e7a374..6683fc952a 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Docking_BasicDockedTools.py
@@ -140,13 +140,13 @@ def Docking_BasicDockedTools():
# 2.5,6) Send a console command.
console_line_edit = console.findChild(QtWidgets.QLineEdit, "lineEdit")
- console_line_edit.setText("t_Scale 2")
+ console_line_edit.setText("t_simulationTickScale 2")
QtTest.QTest.keyClick(console_line_edit, QtCore.Qt.Key_Enter)
- general.get_cvar("t_Scale")
- Report.result(Tests.docked_console_works, general.get_cvar("t_Scale") == "2")
+ general.get_cvar("t_simulationTickScale")
+ Report.result(Tests.docked_console_works, general.get_cvar("t_simulationTickScale") == "2")
# Reset the altered cvar
- console_line_edit.setText("t_Scale 1")
+ console_line_edit.setText("t_simulationTickScale 1")
QtTest.QTest.keyClick(console_line_edit, QtCore.Qt.Key_Enter)
run_test()
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py
index 49069569eb..c9e91687e0 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py
@@ -33,14 +33,14 @@ class TestAutomation(TestAutomationBase):
def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform,
remove_test_level):
from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False)
@pytest.mark.REQUIRES_gpu
def test_BasicEditorWorkflows_GPU_LevelEntityComponentCRUD(self, request, workspace, editor, launcher_platform,
remove_test_level):
from .EditorScripts import BasicEditorWorkflows_LevelEntityComponentCRUD as test_module
self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False,
- use_null_renderer=False)
+ use_null_renderer=False, enable_prefab_system=False)
def test_EntityOutlienr_EntityOrdering(self, request, workspace, editor, launcher_platform):
from .EditorScripts import EntityOutliner_EntityOrdering as test_module
@@ -51,5 +51,4 @@ class TestAutomation(TestAutomationBase):
test_module,
batch_mode=False,
autotest_mode=True,
- extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]
)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
index 820e4bd2aa..d87fd8625b 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main_Optimized.py
@@ -21,6 +21,8 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
# Disable -autotest_mode and -BatchMode. Tests cannot run in -BatchMode due to UI interactions, and these tests
# interact with modal dialogs
global_extra_cmdline_args = []
+
+ enable_prefab_system = False
class test_BasicEditorWorkflows_LevelEntityComponentCRUD(EditorSingleTest):
# Custom teardown to remove slice asset created during test
@@ -47,7 +49,6 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
from .EditorScripts import AssetPicker_UI_UX as test_module
-@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@@ -56,6 +57,8 @@ class TestAutomationAutoTestMode(EditorTestSuite):
# Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions
global_extra_cmdline_args = ["-autotest_mode"]
+ enable_prefab_system = False
+
class test_AssetBrowser_TreeNavigation(EditorSharedTest):
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py
index f131a1c8bc..1bd1d7f987 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Periodic.py
@@ -32,29 +32,29 @@ class TestAutomation(TestAutomationBase):
def test_AssetBrowser_TreeNavigation(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetBrowser_TreeNavigation as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
def test_AssetBrowser_SearchFiltering(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetBrowser_SearchFiltering as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
def test_AssetPicker_UI_UX(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetPicker_UI_UX as test_module
- self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, autotest_mode=False, batch_mode=False, enable_prefab_system=False)
def test_ComponentCRUD_Add_Delete_Components(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ComponentCRUD_Add_Delete_Components as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
def test_InputBindings_Add_Remove_Input_Events(self, request, workspace, editor, launcher_platform):
from .EditorScripts import InputBindings_Add_Remove_Input_Events as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, autotest_mode=False, enable_prefab_system=False)
def test_Menus_ViewMenuOptions_Work(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Menus_ViewMenuOptions as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
@pytest.mark.skip(reason="Times out due to dialogs failing to dismiss: LYN-4208")
def test_Menus_FileMenuOptions_Work(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Menus_FileMenuOptions as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py
index 98a6620d9c..8a56a2dbfd 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox.py
@@ -20,8 +20,8 @@ class TestAutomation(TestAutomationBase):
def test_Menus_EditMenuOptions_Work(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Menus_EditMenuOptions as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
def test_Docking_BasicDockedTools(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Docking_BasicDockedTools as test_module
- self._run_test(request, workspace, editor, test_module, batch_mode=False)
+ self._run_test(request, workspace, editor, test_module, batch_mode=False, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py
index 4a472095ae..ce0d5e43e9 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/TestSuite_Sandbox_Optimized.py
@@ -19,6 +19,8 @@ class TestAutomationAutoTestMode(EditorTestSuite):
# Enable only -autotest_mode for these tests. Tests cannot run in -BatchMode due to UI interactions
global_extra_cmdline_args = ["-autotest_mode"]
+ enable_prefab_system = False
+
class test_Docking_BasicDockedTools(EditorSharedTest):
from .EditorScripts import Docking_BasicDockedTools as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/editor_test_testing/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/editor_test_testing/TestSuite_Main.py
index 15ba6690a1..50b89ab138 100644
--- a/AutomatedTesting/Gem/PythonTests/editor_test_testing/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/editor_test_testing/TestSuite_Main.py
@@ -15,6 +15,7 @@ import sys
import importlib
import re
+import ly_test_tools
from ly_test_tools import LAUNCHERS
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
@@ -25,8 +26,15 @@ import ly_test_tools.environment.process_utils as process_utils
import argparse, sys
-@pytest.mark.SUITE_main
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+def get_editor_launcher_platform():
+ if ly_test_tools.WINDOWS:
+ return "windows_editor"
+ elif ly_test_tools.LINUX:
+ return "linux_editor"
+ else:
+ return None
+
+@pytest.mark.parametrize("launcher_platform", [get_editor_launcher_platform()])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestEditorTest:
@@ -69,7 +77,7 @@ class TestEditorTest:
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorTestSuite
@pytest.mark.SUITE_main
- @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+ @pytest.mark.parametrize("launcher_platform", [{get_editor_launcher_platform()}])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
class test_single(EditorSingleTest):
@@ -123,7 +131,7 @@ class TestEditorTest:
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorTestSuite
@pytest.mark.SUITE_main
- @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+ @pytest.mark.parametrize("launcher_platform", [{get_editor_launcher_platform()}])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
{module_class_code}
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt
index c2123d683c..ba607ede32 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt
@@ -10,45 +10,29 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
## DynVeg ##
- ly_add_pytest(
- NAME AutomatedTesting::DynamicVegetationTests_Main
- TEST_SERIAL
- TEST_SUITE main
- PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main.py
- RUNTIME_DEPENDENCIES
- AZ::AssetProcessor
- Legacy::Editor
- AutomatedTesting.GameLauncher
- AutomatedTesting.Assets
- COMPONENT
- LargeWorlds
- )
-
-
- ly_add_pytest(
- NAME AutomatedTesting::DynamicVegetationTests_Periodic
- TEST_SERIAL
- TEST_SUITE periodic
- PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic.py
- RUNTIME_DEPENDENCIES
- AZ::AssetProcessor
- Legacy::Editor
- AutomatedTesting.Assets
- AutomatedTesting.GameLauncher
- COMPONENT
- LargeWorlds
- )
-
ly_add_pytest(
NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized
TEST_SERIAL
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py
RUNTIME_DEPENDENCIES
- AZ::AssetProcessor
- Legacy::Editor
- AutomatedTesting.Assets
- AutomatedTesting.GameLauncher
+ AZ::AssetProcessor
+ Legacy::Editor
+ AutomatedTesting.Assets
+ AutomatedTesting.GameLauncher
+ COMPONENT
+ LargeWorlds
+ )
+ ly_add_pytest(
+ NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized
+ TEST_SERIAL
+ TEST_SUITE periodic
+ PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic_Optimized.py
+ RUNTIME_DEPENDENCIES
+ AZ::AssetProcessor
+ Legacy::Editor
+ AutomatedTesting.Assets
+ AutomatedTesting.GameLauncher
COMPONENT
LargeWorlds
)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py
new file mode 100644
index 0000000000..d016473d5e
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py
@@ -0,0 +1,85 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+
+def DynVegUtils_TempPrefabCreationWorks():
+ """
+ Summary:
+ An existing level is opened. Each Prefab setup to be spawned by Dynamic Vegetation tests is created in memory and
+ validated against existing test slice components/mesh assignments.
+
+ Expected Behavior:
+ Temporary prefabs contain the expected components/assets.
+
+ Test Steps:
+ 1) Open an existing level
+ 2) Create each of the necessary temporary Mesh prefabs, and validate the component/mesh setups
+ 3) Create the necessary temporary PhysX Collider, and validate the component setup
+ 4) Report errors/asserts
+
+ :return: None
+ """
+
+ import os
+
+ import azlmbr.asset as asset
+ import azlmbr.bus as bus
+ import azlmbr.math as math
+
+ from Prefab.tests import PrefabTestUtils as prefab_test_utils
+ from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg
+ from editor_python_test_tools.utils import Report, Tracer
+ from editor_python_test_tools.utils import TestHelper as helper
+ from editor_python_test_tools.prefab_utils import PrefabInstance
+
+ with Tracer() as error_tracer:
+ # Create dictionary for prefab filenames and paths to create using helper function
+ mesh_prefabs = {
+ "PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"),
+ "PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"),
+ "1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"),
+ "CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"),
+ "Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"),
+ }
+
+ # 1) Open an existing simple level
+ prefab_test_utils.open_base_tests_level()
+
+ # 2) Create each of the Mesh asset prefabs and validate that the prefab created successfully
+ for prefab_filename, asset_path in mesh_prefabs.items():
+ mesh_prefab_created = (
+ f"Temporary mesh prefab: {prefab_filename} created successfully",
+ f"Failed to create temporary mesh prefab: {prefab_filename}"
+ )
+ prefab = dynveg.create_temp_mesh_prefab(asset_path, prefab_filename)
+ Report.result(mesh_prefab_created, helper.wait_for_condition(lambda:
+ PrefabInstance.is_valid(prefab[1]), 3.0))
+
+ # 3) Create temp PhysX Collider prefab and validate that the prefab created successfully
+ physx_prefab_filename = "CedarTree_Collision"
+ physx_collider_prefab_created = (
+ f"Temporary mesh prefab: {physx_prefab_filename} created successfully",
+ f"Failed to create temporary mesh prefab: {physx_prefab_filename}"
+ )
+ test_physx_mesh_asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", os.path.join(
+ "assets", "objects", "foliage", "cedar.pxmesh"), math.Uuid(), False)
+ dynveg.create_temp_physx_mesh_collider(test_physx_mesh_asset_id, physx_prefab_filename)
+ Report.result(physx_collider_prefab_created, helper.wait_for_condition(lambda:
+ PrefabInstance.is_valid(prefab[1]), 3.0))
+
+ # 4) Report errors/asserts
+ helper.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(DynVegUtils_TempPrefabCreationWorks)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py
index 84c661873c..fa45e057e2 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py
@@ -72,9 +72,9 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
# 1) Create a new, temporary level
lvl_name = "tmp_level"
helper.init_idle()
- level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False)
+ level_created = helper.create_level(lvl_name)
general.idle_wait(1.0)
- Report.critical_result(Tests.level_created, level_created == 0)
+ Report.critical_result(Tests.level_created, level_created)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components and Script Canvas component for launcher test
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py
index de2554034f..2353095849 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py
@@ -73,9 +73,9 @@ def DynamicSliceInstanceSpawner_External_E2E():
# 1) Create a new, temporary level
lvl_name = "tmp_level"
helper.init_idle()
- level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False)
+ level_created = helper.create_level(lvl_name)
general.idle_wait(1.0)
- Report.critical_result(Tests.level_created, level_created == 0)
+ Report.critical_result(Tests.level_created, level_created)
general.set_current_view_position(512.0, 480.0, 38.0)
# 2) Create a new entity with required vegetation area components and switch the Vegetation Asset List Source
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py
index bf6501f469..130d56937b 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py
@@ -76,9 +76,9 @@ def LayerBlender_E2E_Editor():
# 1) Create a new, temporary level
lvl_name = "tmp_level"
helper.init_idle()
- level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False)
+ level_created = helper.create_level(lvl_name)
general.idle_wait(1.0)
- Report.critical_result(Tests.level_created, level_created == 0)
+ Report.critical_result(Tests.level_created, level_created)
general.set_current_view_position(500.49, 498.69, 46.66)
general.set_current_view_rotation(-42.05, 0.00, -36.33)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py
index 649c7d0776..1153ae2657 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InheritBehaviorFlag.py
@@ -78,7 +78,7 @@ def LayerSpawner_InheritBehaviorFlag():
# Create Vegetation area and assign a valid asset
veg_1 = hydra.Entity("veg_1")
veg_1.create_entity(
- position, ["Vegetation Layer Spawner", "Vegetation Reference Shape", "Vegetation Asset List"]
+ position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
)
set_dynamic_slice_asset(veg_1, 2, os.path.join("Slices", "PinkFlower.dynamicslice"))
veg_1.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
@@ -86,7 +86,7 @@ def LayerSpawner_InheritBehaviorFlag():
# Create second vegetation area and assign a valid asset
veg_2 = hydra.Entity("veg_2")
veg_2.create_entity(
- position, ["Vegetation Layer Spawner", "Vegetation Reference Shape", "Vegetation Asset List"]
+ position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
)
set_dynamic_slice_asset(veg_2, 2, os.path.join("Slices", "PurpleFlower.dynamicslice"))
veg_2.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py
index 0da200d87a..42604cd2da 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesPlantInAllSupportedShapes.py
@@ -9,7 +9,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
def LayerSpawner_InstancesPlantInAllSupportedShapes():
"""
Summary:
- The level is loaded and vegetation area is created. Then the Vegetation Reference Shape
+ The level is loaded and vegetation area is created. Then the Shape Reference
component of vegetation area is pinned with entities of different shape components to check
if the vegetation plants in different shaped areas.
@@ -67,7 +67,7 @@ def LayerSpawner_InstancesPlantInAllSupportedShapes():
10.0, 10.0, 10.0,
asset_path)
vegetation.remove_component("Box Shape")
- vegetation.add_component("Vegetation Reference Shape")
+ vegetation.add_component("Shape Reference")
# Create surface for planting on
dynveg.create_surface_entity("Surface Entity", entity_position, 60.0, 60.0, 1.0)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py
index 4c02c887ef..06c9c5f615 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main.py
@@ -20,8 +20,8 @@ class TestAutomation(TestAutomationBase):
def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, workspace, editor, launcher_platform):
from .EditorScripts import EmptyInstanceSpawner_EmptySpawnerWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py
index ded2dda4e9..673e40e397 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py
@@ -12,12 +12,24 @@ import ly_test_tools.environment.file_system as file_system
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
-@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
+ enable_prefab_system = False
+
+ # Helpers for test asset cleanup
+ def cleanup_test_level(self, workspace):
+ file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
+ True, True)
+
+ def cleanup_test_slices(self, workspace):
+ file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
+ "TestSlice_1.slice")], True, True)
+ file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
+ "TestSlice_2.slice")], True, True)
+
class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorParallelTest):
from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
@@ -36,10 +48,7 @@ class TestAutomation(EditorTestSuite):
class test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(EditorSingleTest):
# Custom teardown to remove slice asset created during test
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
- file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
- "TestSlice_1.slice")], True, True)
- file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
- "TestSlice_2.slice")], True, True)
+ TestAutomation.cleanup_test_slices(self, workspace)
from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorParallelTest):
@@ -150,23 +159,29 @@ class TestAutomation(EditorTestSuite):
class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest):
from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
- # Custom teardown to remove test level created during test
+ # Custom setup/teardown to remove test level created during test
+ def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
+ TestAutomation.cleanup_test_level(self, workspace)
+
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
- file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
- True, True)
+ TestAutomation.cleanup_test_level(self, workspace)
class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest):
from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
- # Custom teardown to remove test level created during test
+ # Custom setup/teardown to remove test level created during test
+ def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
+ TestAutomation.cleanup_test_level(self, workspace)
+
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
- file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
- True, True)
-
+ TestAutomation.cleanup_test_level(self, workspace)
+
class test_LayerBlender_E2E_Editor(EditorSingleTest):
from .EditorScripts import LayerBlender_E2E_Editor as test_module
- # Custom teardown to remove test level created during test
+ # Custom setup/teardown to remove test level created during test
+ def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
+ TestAutomation.cleanup_test_level(self, workspace)
+
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
- file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
- True, True)
+ TestAutomation.cleanup_test_level(self, workspace)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py
index 2780c0f471..d0d570950b 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic.py
@@ -52,158 +52,158 @@ class TestAutomation(TestAutomationBase):
def test_AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_ComponentAndOverrides_InstancesPlantAtSpecifiedAltitude as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_ShapeSample_InstancesPlantAtSpecifiedAltitude as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AltitudeFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AltitudeFilter_FilterStageToggle as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(self, request, workspace, editor, remove_test_slice, launcher_platform):
from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_AssetWeightSelector_InstancesExpressBasedOnWeight(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AssetWeightSelector_InstancesExpressBasedOnWeight as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
def test_DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4155")
def test_DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius(self, request, workspace, editor, launcher_platform):
from .EditorScripts import DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceDataRefreshes_RemainsStable(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceDataRefreshes_RemainsStable as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_VegetationInstances_DespawnWhenOutOfRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import VegetationInstances_DespawnWhenOutOfRange as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_InstanceSpawnerPriority_LayerAndSubPriority_HigherValuesPlantOverLower(self, request, workspace, editor, launcher_platform):
from .EditorScripts import InstanceSpawnerPriority_LayerAndSubPriority as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerBlocker_InstancesBlockedInConfiguredArea(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerBlocker_InstancesBlockedInConfiguredArea as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_InheritBehaviorFlag(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InheritBehaviorFlag as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_InstancesPlantInAllSupportedShapes(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InstancesPlantInAllSupportedShapes as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LayerSpawner_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_FilterStageToggle as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2038")
def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerSpawner_InstancesRefreshUsingCorrectViewportCamera as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshBlocker_InstancesBlockedByMesh(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshBlocker_InstancesBlockedByMesh as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshBlocker_InstancesBlockedByMeshHeightTuning(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshBlocker_InstancesBlockedByMeshHeightTuning as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshSurfaceTagEmitter_DependentOnMeshComponent(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshSurfaceTagEmitter_DependentOnMeshComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import MeshSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PhysXColliderSurfaceTagEmitter_E2E_Editor(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PhysXColliderSurfaceTagEmitter_E2E_Editor as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PositionModifier_ComponentAndOverrides_InstancesPlantAtSpecifiedOffsets as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_PositionModifier_AutoSnapToSurfaceWorks(self, request, workspace, editor, launcher_platform):
from .EditorScripts import PositionModifier_AutoSnapToSurfaceWorks as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RotationModifier_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import RotationModifier_InstancesRotateWithinRange as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_RotationModifierOverrides_InstancesRotateWithinRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import RotationModifierOverrides_InstancesRotateWithinRange as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScaleModifier_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ScaleModifier_InstancesProperlyScale as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScaleModifierOverrides_InstancesProperlyScale(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ScaleModifierOverrides_InstancesProperlyScale as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ShapeIntersectionFilter_FilterStageToggle(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeAlignmentModifier_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeAlignmentModifier_InstanceSurfaceAlignment as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeAlignmentModifierOverrides_InstanceSurfaceAlignment as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_BasicSurfaceTagCreation(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_BasicSurfaceTagCreation as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_ExclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_ExclusionList as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilter_InclusiveSurfaceTags_Function(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilter_InclusionList as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SurfaceMaskFilterOverrides_MultipleDescriptorOverridesPlantAsExpected as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SystemSettings_SectorPointDensity(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SystemSettings_SectorPointDensity as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SystemSettings_SectorSize(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SystemSettings_SectorSize as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlopes(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlopeFilter_ComponentAndOverrides_InstancesPlantOnValidSlope as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.SUITE_periodic
@@ -219,7 +219,7 @@ class TestAutomationE2E(TestAutomationBase):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level,
@@ -240,7 +240,7 @@ class TestAutomationE2E(TestAutomationBase):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level,
@@ -261,7 +261,7 @@ class TestAutomationE2E(TestAutomationBase):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
from .EditorScripts import LayerBlender_E2E_Editor as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("launcher_platform", ['windows'])
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/4170")
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py
new file mode 100644
index 0000000000..f87d6567ef
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py
@@ -0,0 +1,23 @@
+"""
+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 EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
+
+
+@pytest.mark.SUITE_main
+@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+class TestAutomation(EditorTestSuite):
+
+ global_extra_cmdline_args = ["-BatchMode", "-autotest_mode"]
+
+ class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest):
+ from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py
index 21eecf642c..3ad27eb973 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic.py
@@ -20,52 +20,52 @@ class TestAutomation(TestAutomationBase):
def test_GradientGenerators_Incompatibilities(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientGenerators_Incompatibilities as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientModifiers_Incompatibilities(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifiers_Incompatibilities as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientSampling_GradientReferencesAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientSurfaceTagEmitter_ComponentDependencies(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_RequiresShape(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_RequiresShape as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_ComponentIncompatibleWithSpawners(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_GradientTransform_ComponentIncompatibleWithExpectedGradients(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ImageGradient_RequiresShape(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ImageGradient_RequiresShape as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ImageGradient_ProcessedImageAssignedSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py
index 514504d324..6ac0658b4d 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/TestSuite_Periodic_Optimized.py
@@ -15,6 +15,8 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, E
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
+ enable_prefab_system = False
+
class test_GradientGenerators_Incompatibilities(EditorSharedTest):
from .EditorScripts import GradientGenerators_Incompatibilities as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py
index 9703423901..c69ce77041 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py
@@ -96,7 +96,7 @@ def AreaNodes_DependentComponentsAdded():
'SpawnerAreaNode': [
'Vegetation Layer Spawner',
'Vegetation Asset List',
- 'Vegetation Reference Shape'
+ 'Shape Reference'
],
'MeshBlockerAreaNode': [
'Vegetation Layer Blocker (Mesh)',
@@ -104,7 +104,7 @@ def AreaNodes_DependentComponentsAdded():
],
'BlockerAreaNode': [
'Vegetation Layer Blocker',
- 'Vegetation Reference Shape'
+ 'Shape Reference'
]
}
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py
index 417e093567..4dfc227c53 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py
@@ -82,7 +82,7 @@ def Edit_DisabledNodeDuplication():
nodes = {
'SpawnerAreaNode': 'Vegetation Asset List',
'MeshBlockerAreaNode': 'Mesh',
- 'BlockerAreaNode': 'Vegetation Reference Shape',
+ 'BlockerAreaNode': 'Shape Reference',
'FastNoiseGradientNode': 'Gradient Transform Modifier',
'ImageGradientNode': 'Gradient Transform Modifier',
'PerlinNoiseGradientNode': 'Gradient Transform Modifier',
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py
index c04f9f05f6..63df9a6fcb 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py
@@ -104,7 +104,7 @@ def GradientNodes_DependentComponentsAdded():
# we will be checking for
commonComponents = [
'Gradient Transform Modifier',
- 'Vegetation Reference Shape'
+ 'Shape Reference'
]
componentNames = []
for name in gradients:
@@ -114,7 +114,7 @@ def GradientNodes_DependentComponentsAdded():
# Create nodes for the gradients that have additional required dependencies and check if
# the Entity created by adding the node has the appropriate Component and required
- # Gradient Transform Modifier and Vegetation Reference Shape components added automatically to it
+ # Gradient Transform Modifier and Shape Reference components added automatically to it
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
x = 10.0
y = 10.0
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py
index af4855a546..dedc9c70c0 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main.py
@@ -22,8 +22,8 @@ class TestAutomation(TestAutomationBase):
def test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(self, request, workspace, editor, launcher_platform):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientMixer_NodeConstruction(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientMixer_NodeConstruction as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py
index 1c3652cae9..402df133cb 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Main_Optimized.py
@@ -18,6 +18,8 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, E
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(EditorTestSuite):
+ enable_prefab_system = False
+
class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Periodic.py
index ef8b3e492b..a719b1a7c0 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/TestSuite_Periodic.py
@@ -33,89 +33,89 @@ class TestAutomation(TestAutomationBase):
def test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Edit_DisabledNodeDuplication(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, workspace, editor, launcher_platform):
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Component_AddedRemoved(self, request, workspace, editor, launcher_platform):
from .EditorScripts import Component_AddedRemoved as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnLevelChange as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphClosed_TabbedGraph as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_Slice_CreateInstantiate(self, request, workspace, editor, remove_test_slice, launcher_platform):
from .EditorScripts import Slice_CreateInstantiate as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_GraphUpdates_UpdateComponents(self, request, workspace, editor, launcher_platform):
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ComponentUpdates_UpdateGraph(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, workspace, editor, launcher_platform):
from .EditorScripts import LayerBlender_NodeConstruction as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py
index 957536fffb..d7d5842518 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py
@@ -19,6 +19,45 @@ import azlmbr.paths
sys.path.append(os.path.join(azlmbr.paths.projectroot, 'Gem', 'PythonTests'))
import editor_python_test_tools.hydra_editor_utils as hydra
+from editor_python_test_tools.editor_entity_utils import EditorEntity
+from editor_python_test_tools.prefab_utils import Prefab
+
+
+def create_temp_mesh_prefab(mesh_asset_path, prefab_filename):
+ # Create initial entity
+ root = EditorEntity.create_editor_entity(name=prefab_filename)
+ assert root.exists(), "Failed to create entity"
+ # Add mesh component
+ mesh_component = root.add_component("Mesh")
+ assert root.has_component("Mesh") and mesh_component.is_enabled(), "Failed to add/activate Mesh component"
+ # Assign the specified mesh asset
+ mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(), False)
+ mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset)
+ assert mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset") == mesh_asset, \
+ "Failed to set Mesh asset"
+ # Create and return the temporary/in-memory prefab
+ temp_prefab = Prefab.create_prefab([root], prefab_filename)
+ return temp_prefab
+
+
+def create_temp_physx_mesh_collider(physx_mesh_id, prefab_filename):
+ # Create initial entity
+ root = EditorEntity.create_editor_entity(name=prefab_filename)
+ assert root.exists(), "Failed to create entity"
+ # Add PhysX Collider component
+ collider_component = root.add_component("PhysX Collider")
+ assert root.has_component("PhysX Collider") and collider_component.is_enabled(), \
+ "Failed to add/activate PhysX Collider component"
+ # Set the Collider's Shape Configuration field to PhysicsAsset, and assign the specified PhysX Mesh asset
+ collider_component.set_component_property_value("Shape Configuration|Shape", 7)
+ assert collider_component.get_component_property_value("Shape Configuration|Shape") == 7, \
+ "Failed to set Collider Shape to PhysicsAsset"
+ collider_component.set_component_property_value("Shape Configuration|Asset|PhysX Mesh", physx_mesh_id)
+ assert collider_component.get_component_property_value("Shape Configuration|Asset|PhysX Mesh") == physx_mesh_id, \
+ "Failed to assign PhysX Mesh asset"
+ # Create and return the temporary/in-memory prefab
+ temp_prefab = Prefab.create_prefab([root], prefab_filename)
+ return temp_prefab
def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z):
diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py
index b2001e6825..27af63ddbc 100755
--- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py
@@ -27,15 +27,15 @@ TEST_DIRECTORY = os.path.dirname(__file__)
class TestAutomation(TestAutomationBase):
def test_Pane_HappyPath_OpenCloseSuccessfully(self, request, workspace, editor, launcher_platform):
from . import Pane_HappyPath_OpenCloseSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Pane_HappyPath_DocksProperly(self, request, workspace, editor, launcher_platform):
from . import Pane_HappyPath_DocksProperly as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Pane_HappyPath_ResizesProperly(self, request, workspace, editor, launcher_platform):
from . import Pane_HappyPath_ResizesProperly as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -45,7 +45,7 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptCanvas_TwoComponents_InteractSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -55,15 +55,15 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptCanvas_ChangingAssets_ComponentStable as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Graph_HappyPath_ZoomInZoomOut(self, request, workspace, editor, launcher_platform):
from . import Graph_HappyPath_ZoomInZoomOut as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_NodePalette_HappyPath_CanSelectNode(self, request, workspace, editor, launcher_platform):
from . import NodePalette_HappyPath_CanSelectNode as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -73,11 +73,11 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_NodePalette_HappyPath_ClearSelection(self, request, workspace, editor, launcher_platform, project):
from . import NodePalette_HappyPath_ClearSelection as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -87,7 +87,7 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptCanvas_TwoEntities_UseSimultaneously as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScriptEvent_HappyPath_CreatedWithoutError(self, request, workspace, editor, launcher_platform, project):
def teardown():
@@ -99,19 +99,19 @@ class TestAutomation(TestAutomationBase):
[os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True
)
from . import ScriptEvent_HappyPath_CreatedWithoutError as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScriptCanvasTools_Toggle_OpenCloseSuccess(self, request, workspace, editor, launcher_platform):
from . import ScriptCanvasTools_Toggle_OpenCloseSuccess as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_NodeInspector_HappyPath_VariableRenames(self, request, workspace, editor, launcher_platform, project):
from . import NodeInspector_HappyPath_VariableRenames as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Debugger_HappyPath_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project):
from . import Debugger_HappyPath_TargetMultipleGraphs as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("level", ["tmp_level"])
def test_Debugger_HappyPath_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level):
@@ -120,16 +120,16 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import Debugger_HappyPath_TargetMultipleEntities as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
def test_EditMenu_Default_UndoRedo(self, request, workspace, editor, launcher_platform, project):
from . import EditMenu_Default_UndoRedo as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Pane_Undocked_ClosesSuccessfully(self, request, workspace, editor, launcher_platform):
from . import Pane_Undocked_ClosesSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.parametrize("level", ["tmp_level"])
def test_Entity_HappyPath_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level):
@@ -138,11 +138,11 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import Entity_HappyPath_AddScriptCanvasComponent as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Pane_Default_RetainOnSCRestart(self, request, workspace, editor, launcher_platform):
from . import Pane_Default_RetainOnSCRestart as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -152,7 +152,7 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptEvents_HappyPath_SendReceiveAcrossMultiple as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -162,7 +162,7 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptEvents_Default_SendReceiveSuccessfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -172,24 +172,24 @@ class TestAutomation(TestAutomationBase):
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptEvents_ReturnSetType_Successfully as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform):
from . import NodeCategory_ExpandOnClick as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform):
from . import NodePalette_SearchText_Deletion as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
def test_VariableManager_UnpinVariableType_Works(self, request, workspace, editor, launcher_platform):
from . import VariableManager_UnpinVariableType_Works as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_Node_HappyPath_DuplicateNode(self, request, workspace, editor, launcher_platform):
from . import Node_HappyPath_DuplicateNode as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
def test_ScriptEvent_AddRemoveParameter_ActionsSuccessful(self, request, workspace, editor, launcher_platform):
def teardown():
@@ -201,7 +201,7 @@ class TestAutomation(TestAutomationBase):
[os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True
)
from . import ScriptEvent_AddRemoveParameter_ActionsSuccessful as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method
# fails because of pyside_utils import
@@ -220,7 +220,14 @@ class TestScriptCanvasTests(object):
"File->Open action working as expected: True",
]
hydra.launch_and_validate_results(
- request, TEST_DIRECTORY, editor, "FileMenu_Default_NewAndOpen.py", expected_lines, auto_test_mode=False, timeout=60,
+ request,
+ TEST_DIRECTORY,
+ editor,
+ "FileMenu_Default_NewAndOpen.py",
+ expected_lines,
+ auto_test_mode=False,
+ timeout=60,
+ enable_prefab_system=False,
)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@@ -239,6 +246,7 @@ class TestScriptCanvasTests(object):
expected_lines,
auto_test_mode=False,
timeout=60,
+ enable_prefab_system=False,
)
def test_GraphClose_Default_SavePrompt(self, request, editor, launcher_platform):
@@ -255,6 +263,7 @@ class TestScriptCanvasTests(object):
expected_lines,
auto_test_mode=False,
timeout=60,
+ enable_prefab_system=False,
)
def test_VariableManager_Default_CreateDeleteVars(self, request, editor, launcher_platform):
@@ -269,6 +278,7 @@ class TestScriptCanvasTests(object):
expected_lines,
auto_test_mode=False,
timeout=60,
+ enable_prefab_system=False,
)
@pytest.mark.parametrize(
@@ -304,6 +314,7 @@ class TestScriptCanvasTests(object):
cfg_args=[config.get('cfg_args')],
auto_test_mode=False,
timeout=60,
+ enable_prefab_system=False,
)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@@ -332,6 +343,7 @@ class TestScriptCanvasTests(object):
expected_lines,
auto_test_mode=False,
timeout=60,
+ enable_prefab_system=False,
)
@pytest.mark.xfail(reason="Test fails to find expected lines, it needs to be fixed.")
@@ -359,5 +371,6 @@ class TestScriptCanvasTests(object):
expected_lines,
auto_test_mode=False,
timeout=60,
+ enable_prefab_system=False,
)
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Sandbox.py
index 91b01d8d08..071ae2286c 100644
--- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Sandbox.py
+++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Sandbox.py
@@ -23,4 +23,4 @@ class TestAutomation(TestAutomationBase):
def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform):
from . import Opening_Closing_Pane as test_module
- self._run_test(request, workspace, editor, test_module)
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py
index b269c9e131..df755d5d11 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py
@@ -13,18 +13,26 @@ import os
import pytest
import subprocess
+import ly_test_tools
+
@pytest.mark.SUITE_smoke
class TestCLIToolAzTestRunnerWorks(object):
- def test_CLITool_AzTestRunner_Works(self, build_directory):
+ def test_CLITool_AzTestRunner_ListSelfTests(self, build_directory):
file_path = os.path.join(build_directory, "AzTestRunner")
help_message = "OKAY Symbol found: AzRunUnitTests"
- # Launch AzTestRunner
+
+ if ly_test_tools.WINDOWS:
+ target_lib = "AzTestRunner.Tests"
+ else:
+ target_lib = "libAzTestRunner.Tests"
+
+ # Launch AzTestRunner, load self-tests, print test names
output = subprocess.run(
- [file_path, "AzTestRunner.Tests", "AzRunUnitTests", "--gtest_list_tests"], capture_output=True, timeout=10
+ [file_path, target_lib, "AzRunUnitTests", "--gtest_list_tests"], capture_output=True, timeout=10
)
assert (
len(output.stderr) == 0 and output.returncode == 0
), f"Error occurred while launching {file_path}: {output.stderr}"
# Verify help message
- assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
+ assert help_message in str(output.stdout), f"Help Message: '{help_message}' unexpectedly not present"
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py
index a3f6b8b09f..917ff17f82 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py
@@ -13,7 +13,10 @@ import os
import pytest
import subprocess
+import ly_test_tools
+
+@pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Only succeeds on windows https://github.com/o3de/o3de/issues/5539")
@pytest.mark.SUITE_smoke
class TestCLIToolSerializeContextToolsWorks(object):
def test_CLITool_SerializeContextTools_Works(self, build_directory):
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
index 72e548615c..5caf7744c4 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
@@ -11,10 +11,13 @@ Test should run in both gpu and non gpu
import pytest
import os
from automatedtesting_shared.base import TestAutomationBase
+
+import ly_test_tools
import ly_test_tools.environment.file_system as file_system
@pytest.mark.SUITE_smoke
+@pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Only succeeds on windows https://github.com/o3de/o3de/issues/5539")
@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("level", ["temp_level"])
@@ -28,4 +31,4 @@ class TestAutomation(TestAutomationBase):
from . import Editor_NewExistingLevels_Works as test_module
- self._run_test(request, workspace, editor, test_module, extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=false"])
+ self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
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/Code/Tools/Standalone/Platform/Linux/profiler_linux_files.cmake b/AutomatedTesting/Gem/Sponza/CMakeLists.txt
similarity index 50%
rename from Code/Tools/Standalone/Platform/Linux/profiler_linux_files.cmake
rename to AutomatedTesting/Gem/Sponza/CMakeLists.txt
index 35ab1449e2..2d625a71b6 100644
--- a/Code/Tools/Standalone/Platform/Linux/profiler_linux_files.cmake
+++ b/AutomatedTesting/Gem/Sponza/CMakeLists.txt
@@ -5,8 +5,7 @@
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
-
-set(FILES
- ../Common/Unimplemented/Source/StandaloneApplication_Unimplemented.cpp
- ../Common/Unimplemented/Source/Driller/EvenTrace/EventTraceDataAggregator_Unimplemented.cpp
-)
+# 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/Multiplayer/AutoComponent_NetworkInput/AutoComponent_NetworkInput.prefab b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/AutoComponent_NetworkInput.prefab
new file mode 100644
index 0000000000..78c88144fd
--- /dev/null
+++ b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/AutoComponent_NetworkInput.prefab
@@ -0,0 +1,525 @@
+{
+ "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
+ },
+ "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_[1159459292531]": {
+ "Id": "Entity_[1159459292531]",
+ "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_[1176639161715]"
+ },
+ "Component_[16919232076966545697]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 16919232076966545697
+ },
+ "Component_[5182430712893438093]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 5182430712893438093,
+ "materialSlots": [
+ {
+ "id": {
+ "materialSlotStableId": 803645540
+ }
+ },
+ {
+ "id": {
+ "materialSlotStableId": 803645540
+ }
+ }
+ ],
+ "materialSlotsByLod": [
+ [
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialSlotStableId": 803645540
+ }
+ }
+ ],
+ [
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialSlotStableId": 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
+ }
+ }
+ },
+ "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": 12554887233631987164
+ }
+ }
+ },
+ "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": [
+ -2.3000001907348633,
+ -3.9368600845336914,
+ 1.0
+ ],
+ "Rotate": [
+ -2.050307512283325,
+ 1.9552897214889526,
+ -43.623355865478516
+ ]
+ }
+ },
+ "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_[1168049227123]": {
+ "Id": "Entity_[1168049227123]",
+ "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_[1176639161715]"
+ },
+ "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
+ }
+ }
+ },
+ "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,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[1155164325235]"
+ },
+ {
+ "EntityId": "Entity_[1180934129011]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[1168049227123]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[1163754259827]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[1159459292531]",
+ "SortIndex": 5
+ }
+ ]
+ },
+ "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
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/AutoComponent_NetworkInput.scriptcanvas b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/AutoComponent_NetworkInput.scriptcanvas
new file mode 100644
index 0000000000..2f8a434108
--- /dev/null
+++ b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/AutoComponent_NetworkInput.scriptcanvas
@@ -0,0 +1,1827 @@
+{
+ "Type": "JsonSerialization",
+ "Version": 1,
+ "ClassName": "ScriptCanvasData",
+ "ClassData": {
+ "m_scriptCanvas": {
+ "Id": {
+ "id": 20239954977260
+ },
+ "Name": "AutoComponent_NetworkInput",
+ "Components": {
+ "Component_[14059414856740480991]": {
+ "$type": "EditorGraphVariableManagerComponent",
+ "Id": 14059414856740480991,
+ "m_variableData": {
+ "m_nameVariableMap": [
+ {
+ "Key": {
+ "m_id": "{720D213F-AA7A-48B0-ABBB-A3756C528CF9}"
+ },
+ "Value": {
+ "Datum": {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 0.25
+ },
+ "VariableId": {
+ "m_id": "{720D213F-AA7A-48B0-ABBB-A3756C528CF9}"
+ },
+ "VariableName": "leftright"
+ }
+ },
+ {
+ "Key": {
+ "m_id": "{B2E338E9-2ACB-42FC-B0BE-EDA14A8A86AD}"
+ },
+ "Value": {
+ "Datum": {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 1.0
+ },
+ "VariableId": {
+ "m_id": "{B2E338E9-2ACB-42FC-B0BE-EDA14A8A86AD}"
+ },
+ "VariableName": "fwdback"
+ }
+ },
+ {
+ "Key": {
+ "m_id": "{D843B13F-B3C7-4619-8092-7164EB1D7888}"
+ },
+ "Value": {
+ "Datum": {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 20.0
+ },
+ "VariableId": {
+ "m_id": "{D843B13F-B3C7-4619-8092-7164EB1D7888}"
+ },
+ "VariableName": "VELOCITY"
+ }
+ }
+ ]
+ }
+ },
+ "Component_[642525765775040231]": {
+ "$type": "{4D755CA9-AB92-462C-B24F-0B3376F19967} Graph",
+ "Id": 642525765775040231,
+ "m_graphData": {
+ "m_nodes": [
+ {
+ "Id": {
+ "id": 20265724781036
+ },
+ "Name": "SC-Node(NotEqualTo)",
+ "Components": {
+ "Component_[12036973200504716538]": {
+ "$type": "NotEqualTo",
+ "Id": 12036973200504716538,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{6D0EF497-7C52-432B-9301-7BAB26F4F5A5}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Result",
+ "DisplayDataType": {
+ "m_type": 0
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{AE7E453C-15DE-47D2-954A-05C3895B7AC6}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "toolTip": "Signal to perform the evaluation when desired.",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{AC364E17-A9A1-42DB-A29D-7B2D666E4287}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "True",
+ "toolTip": "Signaled if the result of the operation is true.",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{0754AC37-61A6-42A7-B4EC-D35D18D27960}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "False",
+ "toolTip": "Signaled if the result of the operation is false.",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{57EBC15B-452E-49B3-8BD3-4FBBB07F1F14}"
+ },
+ "DynamicTypeOverride": 3,
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Value A",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DynamicGroup": {
+ "Value": 3545012108
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{21864AEE-7954-4F68-82C6-573C175724EF}"
+ },
+ "DynamicTypeOverride": 3,
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Value B",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DynamicGroup": {
+ "Value": 3545012108
+ },
+ "DataType": 1,
+ "IsReference": true,
+ "VariableReference": {
+ "m_id": "{720D213F-AA7A-48B0-ABBB-A3756C528CF9}"
+ }
+ }
+ ],
+ "Datums": [
+ {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 0.0,
+ "label": "Value A"
+ },
+ {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 0.0,
+ "label": "Value B"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20257134846444
+ },
+ "Name": "SC-Node(NotEqualTo)",
+ "Components": {
+ "Component_[12036973200504716538]": {
+ "$type": "NotEqualTo",
+ "Id": 12036973200504716538,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{6D0EF497-7C52-432B-9301-7BAB26F4F5A5}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Result",
+ "DisplayDataType": {
+ "m_type": 0
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{AE7E453C-15DE-47D2-954A-05C3895B7AC6}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "toolTip": "Signal to perform the evaluation when desired.",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{AC364E17-A9A1-42DB-A29D-7B2D666E4287}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "True",
+ "toolTip": "Signaled if the result of the operation is true.",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{0754AC37-61A6-42A7-B4EC-D35D18D27960}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "False",
+ "toolTip": "Signaled if the result of the operation is false.",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{57EBC15B-452E-49B3-8BD3-4FBBB07F1F14}"
+ },
+ "DynamicTypeOverride": 3,
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Value A",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DynamicGroup": {
+ "Value": 3545012108
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{21864AEE-7954-4F68-82C6-573C175724EF}"
+ },
+ "DynamicTypeOverride": 3,
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Value B",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DynamicGroup": {
+ "Value": 3545012108
+ },
+ "DataType": 1,
+ "IsReference": true,
+ "VariableReference": {
+ "m_id": "{B2E338E9-2ACB-42FC-B0BE-EDA14A8A86AD}"
+ }
+ }
+ ],
+ "Datums": [
+ {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 0.0,
+ "label": "Value A"
+ },
+ {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 0.0,
+ "label": "Value B"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20278609682924
+ },
+ "Name": "SC-Node(Print)",
+ "Components": {
+ "Component_[12996217042650310160]": {
+ "$type": "Print",
+ "Id": 12996217042650310160,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{D994D58A-DBF1-4929-B779-F0D2CBAD2F0D}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "toolTip": "Input signal",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{233C15BC-0186-4A7F-B272-6B2C020DE57A}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Out",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ }
+ ],
+ "m_format": "AutoComponent_NetworkInput ProcessInput called!",
+ "m_unresolvedString": [
+ "AutoComponent_NetworkInput ProcessInput called!"
+ ]
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20244249944556
+ },
+ "Name": "SC-Node(CreateFromValues)",
+ "Components": {
+ "Component_[16858161274259468878]": {
+ "$type": "{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF} Method",
+ "Id": 16858161274259468878,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{7CF3B6C0-FE59-4E16-ABC6-E7CC8AFA8EF3}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "fwdBack",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DataType": 1,
+ "IsReference": true,
+ "VariableReference": {
+ "m_id": "{B2E338E9-2ACB-42FC-B0BE-EDA14A8A86AD}"
+ }
+ },
+ {
+ "id": {
+ "m_id": "{02473A8A-A0F0-4E73-8999-0B16D17E8E2A}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "leftRight",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DataType": 1,
+ "IsReference": true,
+ "VariableReference": {
+ "m_id": "{720D213F-AA7A-48B0-ABBB-A3756C528CF9}"
+ }
+ },
+ {
+ "id": {
+ "m_id": "{514CDDAA-290F-4758-B28F-4003E719E635}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{E3A94716-C880-4D6D-ADD6-34D019161ED1}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Out",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{90E52F81-54E0-4C63-9881-B661FB5D87D1}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Result: NetworkTestPlayerComponentNetworkInput",
+ "DisplayDataType": {
+ "m_type": 4,
+ "m_azType": "{12A1776B-61F6-4E5F-356A-AD718A62051F}"
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ }
+ ],
+ "Datums": [
+ {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 0.0,
+ "label": "fwdBack"
+ },
+ {
+ "scriptCanvasType": {
+ "m_type": 3
+ },
+ "isNullPointer": false,
+ "$type": "double",
+ "value": 0.0,
+ "label": "leftRight"
+ }
+ ],
+ "methodType": 2,
+ "methodName": "CreateFromValues",
+ "className": "NetworkTestPlayerComponentNetworkInput",
+ "resultSlotIDs": [
+ {}
+ ],
+ "inputSlots": [
+ {
+ "m_id": "{7CF3B6C0-FE59-4E16-ABC6-E7CC8AFA8EF3}"
+ },
+ {
+ "m_id": "{02473A8A-A0F0-4E73-8999-0B16D17E8E2A}"
+ }
+ ],
+ "prettyClassName": "NetworkTestPlayerComponentNetworkInput"
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20252839879148
+ },
+ "Name": "EBusEventHandler",
+ "Components": {
+ "Component_[1734984895901771768]": {
+ "$type": "EBusEventHandler",
+ "Id": 1734984895901771768,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{41899533-66B3-423F-8BE2-A624A1FB6FCB}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Connect",
+ "toolTip": "Connect this event handler to the specified entity.",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{65C09819-1B00-4BA8-B6E0-8DD6D8B44A36}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Disconnect",
+ "toolTip": "Disconnect this event handler.",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{B7437693-34D0-4BDE-8516-2CADB9F509BF}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "OnConnected",
+ "toolTip": "Signaled when a connection has taken place.",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{BCE36ED4-0899-4403-826A-FE89BE033A0A}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "OnDisconnected",
+ "toolTip": "Signaled when this event handler is disconnected.",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{796993F4-685D-4A85-A0CA-032E3466FB57}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "OnFailure",
+ "toolTip": "Signaled when it is not possible to connect this handler.",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{680E9668-87B4-4FF2-AA24-EB8F11352A49}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Source",
+ "toolTip": "ID used to connect on a specific Event address (Type: EntityId)",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{ADF9B366-8324-4C1E-B601-C059DA70FDDE}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Result: NetworkTestPlayerComponentNetworkInput",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{3301102C-AD42-48A0-8764-D2D4D31E0C75}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Number",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{B831AC60-7641-4B74-9829-26A3576B4766}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "ExecutionSlot:CreateInput",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ },
+ "IsLatent": true
+ },
+ {
+ "id": {
+ "m_id": "{8F69FA2E-28D8-4DF1-A4B5-AEF3985095C5}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "NetworkTestPlayerComponentNetworkInput",
+ "DisplayDataType": {
+ "m_type": 4,
+ "m_azType": "{12A1776B-61F6-4E5F-356A-AD718A62051F}"
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{BE3E3F84-E91C-4F6C-B148-E13BF01B5FBC}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Number",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{4C8F2908-12B0-4C35-8468-31D3D4DF36AA}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "ExecutionSlot:ProcessInput",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ },
+ "IsLatent": true
+ }
+ ],
+ "Datums": [
+ {
+ "scriptCanvasType": {
+ "m_type": 1
+ },
+ "isNullPointer": false,
+ "$type": "EntityId",
+ "value": {
+ "id": 2901262558
+ },
+ "label": "Source"
+ },
+ {
+ "scriptCanvasType": {
+ "m_type": 4,
+ "m_azType": "{12A1776B-61F6-4E5F-356A-AD718A62051F}"
+ },
+ "isNullPointer": false,
+ "$type": "NetworkTestPlayerComponentNetworkInput",
+ "label": "Result: NetworkTestPlayerComponentNetworkInput"
+ }
+ ],
+ "m_eventMap": [
+ {
+ "Key": {
+ "Value": 78438309
+ },
+ "Value": {
+ "m_eventName": "CreateInput",
+ "m_eventId": {
+ "Value": 78438309
+ },
+ "m_eventSlotId": {
+ "m_id": "{B831AC60-7641-4B74-9829-26A3576B4766}"
+ },
+ "m_resultSlotId": {
+ "m_id": "{ADF9B366-8324-4C1E-B601-C059DA70FDDE}"
+ },
+ "m_parameterSlotIds": [
+ {
+ "m_id": "{3301102C-AD42-48A0-8764-D2D4D31E0C75}"
+ }
+ ],
+ "m_numExpectedArguments": 1
+ }
+ },
+ {
+ "Key": {
+ "Value": 1793364217
+ },
+ "Value": {
+ "m_eventName": "ProcessInput",
+ "m_eventId": {
+ "Value": 1793364217
+ },
+ "m_eventSlotId": {
+ "m_id": "{4C8F2908-12B0-4C35-8468-31D3D4DF36AA}"
+ },
+ "m_parameterSlotIds": [
+ {
+ "m_id": "{8F69FA2E-28D8-4DF1-A4B5-AEF3985095C5}"
+ },
+ {
+ "m_id": "{BE3E3F84-E91C-4F6C-B148-E13BF01B5FBC}"
+ }
+ ],
+ "m_numExpectedArguments": 2
+ }
+ }
+ ],
+ "m_ebusName": "NetworkTestPlayerComponentBusHandler",
+ "m_busId": {
+ "Value": 3690077280
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20248544911852
+ },
+ "Name": "SC-Node(ExtractProperty)",
+ "Components": {
+ "Component_[2395597035843331661]": {
+ "$type": "ExtractProperty",
+ "Id": 2395597035843331661,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{C80C50EE-F216-4F44-B107-6B35354AFD52}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "toolTip": "When signaled assigns property values using the supplied source input",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{C69C098D-D667-4DC7-85E5-AFD119727D94}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Out",
+ "toolTip": "Signaled after all property haves have been pushed to the output slots",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{D387C800-352B-4B01-8765-4F4B40DF45CB}"
+ },
+ "DynamicTypeOverride": 1,
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Source",
+ "toolTip": "The value on which to extract properties from.",
+ "DisplayDataType": {
+ "m_type": 4,
+ "m_azType": "{12A1776B-61F6-4E5F-356A-AD718A62051F}"
+ },
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{0C03D491-DE25-46C2-BF09-14769FA49FDB}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "FwdBack: Number",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ },
+ {
+ "id": {
+ "m_id": "{4C13F9EF-60BF-4AD1-8FA9-66F46455411C}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "LeftRight: Number",
+ "DisplayDataType": {
+ "m_type": 3
+ },
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 2
+ },
+ "DataType": 1
+ }
+ ],
+ "Datums": [
+ {
+ "scriptCanvasType": {
+ "m_type": 4,
+ "m_azType": "{12A1776B-61F6-4E5F-356A-AD718A62051F}"
+ },
+ "isNullPointer": false,
+ "$type": "NetworkTestPlayerComponentNetworkInput",
+ "label": "Source"
+ }
+ ],
+ "m_dataType": {
+ "m_type": 4,
+ "m_azType": "{12A1776B-61F6-4E5F-356A-AD718A62051F}"
+ },
+ "m_propertyAccounts": [
+ {
+ "m_propertySlotId": {
+ "m_id": "{0C03D491-DE25-46C2-BF09-14769FA49FDB}"
+ },
+ "m_propertyType": {
+ "m_type": 3
+ },
+ "m_propertyName": "FwdBack"
+ },
+ {
+ "m_propertySlotId": {
+ "m_id": "{4C13F9EF-60BF-4AD1-8FA9-66F46455411C}"
+ },
+ "m_propertyType": {
+ "m_type": 3
+ },
+ "m_propertyName": "LeftRight"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20270019748332
+ },
+ "Name": "SC-Node(Print)",
+ "Components": {
+ "Component_[7568030783460446634]": {
+ "$type": "Print",
+ "Id": 7568030783460446634,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{733AA75D-022C-45E9-9D0F-3EF9A1633ADC}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "toolTip": "Input signal",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{2E77B0FC-DE56-4D78-9A59-152B7A0666F3}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Out",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ }
+ ],
+ "m_format": "AutoComponent_NetworkInput received bad fwdback!",
+ "m_unresolvedString": [
+ "AutoComponent_NetworkInput received bad fwdback!"
+ ]
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20274314715628
+ },
+ "Name": "SC-Node(Print)",
+ "Components": {
+ "Component_[7568030783460446634]": {
+ "$type": "Print",
+ "Id": 7568030783460446634,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{733AA75D-022C-45E9-9D0F-3EF9A1633ADC}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "toolTip": "Input signal",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{2E77B0FC-DE56-4D78-9A59-152B7A0666F3}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Out",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ }
+ ],
+ "m_format": "AutoComponent_NetworkInput received bad leftright!",
+ "m_unresolvedString": [
+ "AutoComponent_NetworkInput received bad leftright!"
+ ]
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20261429813740
+ },
+ "Name": "SC-Node(Print)",
+ "Components": {
+ "Component_[8131385522131771125]": {
+ "$type": "Print",
+ "Id": 8131385522131771125,
+ "Slots": [
+ {
+ "id": {
+ "m_id": "{2B6DB3BC-AA87-4280-B4C3-42C1EE17CBA3}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "In",
+ "toolTip": "Input signal",
+ "Descriptor": {
+ "ConnectionType": 1,
+ "SlotType": 1
+ }
+ },
+ {
+ "id": {
+ "m_id": "{68F1C47B-3127-4CBA-AC9B-5B9B736C70AD}"
+ },
+ "contracts": [
+ {
+ "$type": "SlotTypeContract"
+ }
+ ],
+ "slotName": "Out",
+ "Descriptor": {
+ "ConnectionType": 2,
+ "SlotType": 1
+ }
+ }
+ ],
+ "m_format": "AutoComponent_NetworkInput CreateInput called!",
+ "m_unresolvedString": [
+ "AutoComponent_NetworkInput CreateInput called!"
+ ]
+ }
+ }
+ }
+ ],
+ "m_connections": [
+ {
+ "Id": {
+ "id": 20282904650220
+ },
+ "Name": "srcEndpoint=(NetworkTestPlayerComponentBusHandler Handler: ExecutionSlot:CreateInput), destEndpoint=(Print: In)",
+ "Components": {
+ "Component_[3586317167340048684]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 3586317167340048684,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20252839879148
+ },
+ "slotId": {
+ "m_id": "{B831AC60-7641-4B74-9829-26A3576B4766}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20261429813740
+ },
+ "slotId": {
+ "m_id": "{2B6DB3BC-AA87-4280-B4C3-42C1EE17CBA3}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20287199617516
+ },
+ "Name": "srcEndpoint=(NetworkTestPlayerComponentBusHandler Handler: ExecutionSlot:CreateInput), destEndpoint=(CreateFromValues: In)",
+ "Components": {
+ "Component_[15956251897822268937]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 15956251897822268937,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20252839879148
+ },
+ "slotId": {
+ "m_id": "{B831AC60-7641-4B74-9829-26A3576B4766}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20244249944556
+ },
+ "slotId": {
+ "m_id": "{514CDDAA-290F-4758-B28F-4003E719E635}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20291494584812
+ },
+ "Name": "srcEndpoint=(CreateFromValues: Result: NetworkTestPlayerComponentNetworkInput), destEndpoint=(NetworkTestPlayerComponentBusHandler Handler: Result: NetworkTestPlayerComponentNetworkInput)",
+ "Components": {
+ "Component_[3864080489501353126]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 3864080489501353126,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20244249944556
+ },
+ "slotId": {
+ "m_id": "{90E52F81-54E0-4C63-9881-B661FB5D87D1}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20252839879148
+ },
+ "slotId": {
+ "m_id": "{ADF9B366-8324-4C1E-B601-C059DA70FDDE}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20295789552108
+ },
+ "Name": "srcEndpoint=(NetworkTestPlayerComponentBusHandler Handler: ExecutionSlot:ProcessInput), destEndpoint=(Print: In)",
+ "Components": {
+ "Component_[8628095809445337119]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 8628095809445337119,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20252839879148
+ },
+ "slotId": {
+ "m_id": "{4C8F2908-12B0-4C35-8468-31D3D4DF36AA}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20278609682924
+ },
+ "slotId": {
+ "m_id": "{D994D58A-DBF1-4929-B779-F0D2CBAD2F0D}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20300084519404
+ },
+ "Name": "srcEndpoint=(NetworkTestPlayerComponentBusHandler Handler: ExecutionSlot:ProcessInput), destEndpoint=(Extract Properties: In)",
+ "Components": {
+ "Component_[10621112306443381493]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 10621112306443381493,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20252839879148
+ },
+ "slotId": {
+ "m_id": "{4C8F2908-12B0-4C35-8468-31D3D4DF36AA}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20248544911852
+ },
+ "slotId": {
+ "m_id": "{C80C50EE-F216-4F44-B107-6B35354AFD52}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20304379486700
+ },
+ "Name": "srcEndpoint=(NetworkTestPlayerComponentBusHandler Handler: NetworkTestPlayerComponentNetworkInput), destEndpoint=(Extract Properties: Source)",
+ "Components": {
+ "Component_[14013500888143163469]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 14013500888143163469,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20252839879148
+ },
+ "slotId": {
+ "m_id": "{8F69FA2E-28D8-4DF1-A4B5-AEF3985095C5}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20248544911852
+ },
+ "slotId": {
+ "m_id": "{D387C800-352B-4B01-8765-4F4B40DF45CB}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20308674453996
+ },
+ "Name": "srcEndpoint=(Extract Properties: Out), destEndpoint=(Not Equal To (!=): In)",
+ "Components": {
+ "Component_[14597948098713219792]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 14597948098713219792,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20248544911852
+ },
+ "slotId": {
+ "m_id": "{C69C098D-D667-4DC7-85E5-AFD119727D94}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20257134846444
+ },
+ "slotId": {
+ "m_id": "{AE7E453C-15DE-47D2-954A-05C3895B7AC6}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20312969421292
+ },
+ "Name": "srcEndpoint=(Extract Properties: FwdBack: Number), destEndpoint=(Not Equal To (!=): Value A)",
+ "Components": {
+ "Component_[14915522756837814768]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 14915522756837814768,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20248544911852
+ },
+ "slotId": {
+ "m_id": "{0C03D491-DE25-46C2-BF09-14769FA49FDB}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20257134846444
+ },
+ "slotId": {
+ "m_id": "{57EBC15B-452E-49B3-8BD3-4FBBB07F1F14}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20317264388588
+ },
+ "Name": "srcEndpoint=(Extract Properties: Out), destEndpoint=(Not Equal To (!=): In)",
+ "Components": {
+ "Component_[6510282773353837676]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 6510282773353837676,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20248544911852
+ },
+ "slotId": {
+ "m_id": "{C69C098D-D667-4DC7-85E5-AFD119727D94}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20265724781036
+ },
+ "slotId": {
+ "m_id": "{AE7E453C-15DE-47D2-954A-05C3895B7AC6}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20321559355884
+ },
+ "Name": "srcEndpoint=(Extract Properties: LeftRight: Number), destEndpoint=(Not Equal To (!=): Value A)",
+ "Components": {
+ "Component_[16150645152204311425]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 16150645152204311425,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20248544911852
+ },
+ "slotId": {
+ "m_id": "{4C13F9EF-60BF-4AD1-8FA9-66F46455411C}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20265724781036
+ },
+ "slotId": {
+ "m_id": "{57EBC15B-452E-49B3-8BD3-4FBBB07F1F14}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20325854323180
+ },
+ "Name": "srcEndpoint=(Not Equal To (!=): True), destEndpoint=(Print: In)",
+ "Components": {
+ "Component_[3322355580364572639]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 3322355580364572639,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20257134846444
+ },
+ "slotId": {
+ "m_id": "{AC364E17-A9A1-42DB-A29D-7B2D666E4287}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20270019748332
+ },
+ "slotId": {
+ "m_id": "{733AA75D-022C-45E9-9D0F-3EF9A1633ADC}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "Id": {
+ "id": 20330149290476
+ },
+ "Name": "srcEndpoint=(Not Equal To (!=): True), destEndpoint=(Print: In)",
+ "Components": {
+ "Component_[1975626970668030308]": {
+ "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
+ "Id": 1975626970668030308,
+ "sourceEndpoint": {
+ "nodeId": {
+ "id": 20265724781036
+ },
+ "slotId": {
+ "m_id": "{AC364E17-A9A1-42DB-A29D-7B2D666E4287}"
+ }
+ },
+ "targetEndpoint": {
+ "nodeId": {
+ "id": 20274314715628
+ },
+ "slotId": {
+ "m_id": "{733AA75D-022C-45E9-9D0F-3EF9A1633ADC}"
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "m_assetType": "{3E2AC8CD-713F-453E-967F-29517F331784}",
+ "versionData": {
+ "_grammarVersion": 1,
+ "_runtimeVersion": 1,
+ "_fileVersion": 1
+ },
+ "m_variableCounter": 2,
+ "GraphCanvasData": [
+ {
+ "Key": {
+ "id": 20239954977260
+ },
+ "Value": {
+ "ComponentData": {
+ "{5F84B500-8C45-40D1-8EFC-A5306B241444}": {
+ "$type": "SceneComponentSaveData",
+ "ViewParams": {
+ "Scale": 1.0097068678919363,
+ "AnchorX": 1086.4539794921875,
+ "AnchorY": 198.07728576660156
+ }
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20244249944556
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "MethodNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 740.0,
+ 100.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData",
+ "SubStyle": ".method"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{7A7C96CB-4B5A-48DD-A0AD-0094A113549B}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20248544911852
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "DefaultNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 740.0,
+ 320.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{ED8F0B6C-0811-4FB7-AEE8-B71DB87FABF0}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20252839879148
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 160.0,
+ 100.0
+ ]
+ },
+ "{9E81C95F-89C0-4476-8E82-63CCC4E52E04}": {
+ "$type": "EBusHandlerNodeDescriptorSaveData",
+ "EventIds": [
+ {
+ "Value": 78438309
+ },
+ {
+ "Value": 1793364217
+ }
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{BB97BA3E-F2AB-4078-9BB3-2A0F31DC771C}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20257134846444
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "MathNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 1040.0,
+ 320.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{71AB4748-41F4-4FEA-874C-F54037236F31}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20261429813740
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "StringNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 740.0,
+ -100.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{26E363EE-F35A-4096-88EF-DF907A809894}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20265724781036
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "MathNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 1040.0,
+ 520.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{F64E211C-8DDD-4223-9235-8DB802A017CB}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20270019748332
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "StringNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 1480.0,
+ 320.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{9161B9FA-8493-479D-BE35-10D92644D5C0}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20274314715628
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "StringNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 1480.0,
+ 520.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{1AF129A6-751C-4FC0-805E-65AC2D4B6D3D}"
+ }
+ }
+ }
+ },
+ {
+ "Key": {
+ "id": 20278609682924
+ },
+ "Value": {
+ "ComponentData": {
+ "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
+ "$type": "NodeSaveData"
+ },
+ "{328FF15C-C302-458F-A43D-E1794DE0904E}": {
+ "$type": "GeneralNodeTitleComponentSaveData",
+ "PaletteOverride": "StringNodeTitlePalette"
+ },
+ "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
+ "$type": "GeometrySaveData",
+ "Position": [
+ 740.0,
+ 740.0
+ ]
+ },
+ "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
+ "$type": "StylingComponentSaveData"
+ },
+ "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
+ "$type": "PersistentIdComponentSaveData",
+ "PersistentId": "{F7407B9B-C302-4B50-BFB0-D1208DF1D5AC}"
+ }
+ }
+ }
+ }
+ ],
+ "StatisticsHelper": {
+ "InstanceCounter": [
+ {
+ "Key": 5842116704436214676,
+ "Value": 1
+ },
+ {
+ "Key": 5842116706017748280,
+ "Value": 1
+ },
+ {
+ "Key": 7441100700879769985,
+ "Value": 2
+ },
+ {
+ "Key": 10684225535275896474,
+ "Value": 4
+ },
+ {
+ "Key": 10715014621082578046,
+ "Value": 1
+ },
+ {
+ "Key": 14285852892804039565,
+ "Value": 1
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/Player.prefab b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/Player.prefab
new file mode 100644
index 0000000000..72fce2d291
--- /dev/null
+++ b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/Player.prefab
@@ -0,0 +1,196 @@
+{
+ "ContainerEntity": {
+ "Id": "ContainerEntity",
+ "Name": "Player",
+ "Components": {
+ "Component_[10591405285626521927]": {
+ "$type": "EditorLockComponent",
+ "Id": 10591405285626521927
+ },
+ "Component_[10962884071806037909]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 10962884071806037909,
+ "Parent Entity": ""
+ },
+ "Component_[14883697413991420474]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 14883697413991420474
+ },
+ "Component_[1497622121956209837]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 1497622121956209837
+ },
+ "Component_[16429314387772079347]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 16429314387772079347
+ },
+ "Component_[16665294301093657382]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 16665294301093657382
+ },
+ "Component_[1706666252612720326]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 1706666252612720326
+ },
+ "Component_[4216896820422195198]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 4216896820422195198
+ },
+ "Component_[4540089401187370610]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 4540089401187370610
+ },
+ "Component_[6378576046601184103]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 6378576046601184103
+ },
+ "Component_[7745420981568587180]": {
+ "$type": "SelectionComponent",
+ "Id": 7745420981568587180
+ }
+ }
+ },
+ "Entities": {
+ "Entity_[1028733630164]": {
+ "Id": "Entity_[1028733630164]",
+ "Name": "Player",
+ "Components": {
+ "Component_[12294726333564087591]": {
+ "$type": "SelectionComponent",
+ "Id": 12294726333564087591
+ },
+ "Component_[13587084088242540786]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 13587084088242540786,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 6819443882832501114
+ },
+ {
+ "ComponentId": 5577505593558922067,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 2069554278758260821,
+ "SortIndex": 2
+ },
+ {
+ "ComponentId": 16508969730014660362,
+ "SortIndex": 3
+ },
+ {
+ "ComponentId": 8125406152674415588,
+ "SortIndex": 4
+ },
+ {
+ "ComponentId": 4337571454344109612,
+ "SortIndex": 5
+ },
+ {
+ "ComponentId": 16457408099527309065,
+ "SortIndex": 6
+ }
+ ]
+ },
+ "Component_[14335168881008289852]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14335168881008289852
+ },
+ "Component_[16308902899170829847]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 16308902899170829847
+ },
+ "Component_[16457408099527309065]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 16457408099527309065,
+ "m_template": {
+ "$type": "Multiplayer::NetworkTransformComponent"
+ }
+ },
+ "Component_[16508969730014660362]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 16508969730014660362,
+ "m_template": {
+ "$type": "AutomatedTesting::NetworkTestPlayerComponent"
+ }
+ },
+ "Component_[16541569566865026527]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 16541569566865026527
+ },
+ "Component_[2002761223483048905]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 2002761223483048905
+ },
+ "Component_[2069554278758260821]": {
+ "$type": "EditorScriptCanvasComponent",
+ "Id": 2069554278758260821,
+ "m_name": "AutoComponent_NetworkInput",
+ "m_assetHolder": {
+ "m_asset": {
+ "assetId": {
+ "guid": "{D079F53D-CCAA-5C98-8E0C-B485B7821747}"
+ },
+ "assetHint": "levels/multiplayer/autocomponent_networkinput/autocomponent_networkinput.scriptcanvas"
+ }
+ },
+ "runtimeDataIsValid": true,
+ "runtimeDataOverrides": {
+ "source": {
+ "assetId": {
+ "guid": "{D079F53D-CCAA-5C98-8E0C-B485B7821747}"
+ },
+ "assetHint": "levels/multiplayer/autocomponent_networkinput/autocomponent_networkinput.scriptcanvas"
+ }
+ }
+ },
+ "Component_[4337571454344109612]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 4337571454344109612,
+ "m_template": {
+ "$type": "NetBindComponent"
+ }
+ },
+ "Component_[477591477979440744]": {
+ "$type": "EditorLockComponent",
+ "Id": 477591477979440744
+ },
+ "Component_[5577505593558922067]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 5577505593558922067,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}",
+ "subId": 284780167
+ },
+ "assetHint": "models/sphere.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[5828214869455694702]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5828214869455694702
+ },
+ "Component_[6819443882832501114]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6819443882832501114,
+ "Parent Entity": "ContainerEntity"
+ },
+ "Component_[8125406152674415588]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 8125406152674415588,
+ "m_template": {
+ "$type": "Multiplayer::LocalPredictionPlayerInputComponent"
+ }
+ },
+ "Component_[8838623765985560328]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 8838623765985560328
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/tags.txt b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/Multiplayer/AutoComponent_NetworkInput/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/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/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/Levels/macbeth_shaderballs/macbeth_shaderballs.prefab b/AutomatedTesting/Levels/macbeth_shaderballs/macbeth_shaderballs.prefab
new file mode 100644
index 0000000000..22504f168a
--- /dev/null
+++ b/AutomatedTesting/Levels/macbeth_shaderballs/macbeth_shaderballs.prefab
@@ -0,0 +1,3401 @@
+{
+ "ContainerEntity": {
+ "Id": "ContainerEntity",
+ "Name": "macbeth_shaderballs",
+ "Components": {
+ "Component_[10182366347512475253]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 10182366347512475253
+ },
+ "Component_[12917798267488243668]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 12917798267488243668
+ },
+ "Component_[3261249813163778338]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3261249813163778338
+ },
+ "Component_[3837204912784440039]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 3837204912784440039
+ },
+ "Component_[4272963378099646759]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 4272963378099646759,
+ "Parent Entity": ""
+ },
+ "Component_[4848458548047175816]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 4848458548047175816
+ },
+ "Component_[5787060997243919943]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 5787060997243919943
+ },
+ "Component_[7804170251266531779]": {
+ "$type": "EditorLockComponent",
+ "Id": 7804170251266531779
+ },
+ "Component_[7874177159288365422]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 7874177159288365422
+ },
+ "Component_[8018146290632383969]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 8018146290632383969
+ },
+ "Component_[8452360690590857075]": {
+ "$type": "SelectionComponent",
+ "Id": 8452360690590857075
+ }
+ }
+ },
+ "Entities": {
+ "Entity_[471076350497]": {
+ "Id": "Entity_[471076350497]",
+ "Name": "WorldOrigin",
+ "Components": {
+ "Component_[10118378636607282023]": {
+ "$type": "AZ::Render::EditorImageBasedLightComponent",
+ "Id": 10118378636607282023,
+ "Controller": {
+ "Configuration": {
+ "diffuseImageAsset": {
+ "assetId": {
+ "guid": "{10853039-DC8A-558A-B27E-4433A6386731}",
+ "subId": 3000
+ },
+ "assetHint": "lightingpresets/lowcontrast/blouberg_sunrise_1_4k_iblskyboxcm_ibldiffuse.exr.streamingimage"
+ },
+ "specularImageAsset": {
+ "assetId": {
+ "guid": "{10853039-DC8A-558A-B27E-4433A6386731}",
+ "subId": 2000
+ },
+ "assetHint": "lightingpresets/lowcontrast/blouberg_sunrise_1_4k_iblskyboxcm_iblspecular.exr.streamingimage"
+ },
+ "exposure": 1.0
+ }
+ }
+ },
+ "Component_[10390989140659450689]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10390989140659450689,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 6066687697346848609
+ },
+ {
+ "ComponentId": 1538992203183232042,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 10118378636607282023,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[1122756123782465575]": {
+ "$type": "EditorLockComponent",
+ "Id": 1122756123782465575
+ },
+ "Component_[1411541685315998773]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 1411541685315998773
+ },
+ "Component_[1538992203183232042]": {
+ "$type": "AZ::Render::EditorGridComponent",
+ "Id": 1538992203183232042
+ },
+ "Component_[16871442125196328877]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 16871442125196328877,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[604220336673]"
+ },
+ {
+ "EntityId": "Entity_[599925369377]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[475371317793]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[509731056161]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[505436088865]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[539795827233]",
+ "SortIndex": 5
+ },
+ {
+ "EntityId": "Entity_[569860598305]",
+ "SortIndex": 6
+ }
+ ]
+ },
+ "Component_[18389136819207633744]": {
+ "$type": "SelectionComponent",
+ "Id": 18389136819207633744
+ },
+ "Component_[2967708543517171475]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 2967708543517171475
+ },
+ "Component_[6066687697346848609]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6066687697346848609,
+ "Parent Entity": "ContainerEntity"
+ },
+ "Component_[7035058231756199033]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 7035058231756199033
+ },
+ "Component_[7861798362721154905]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 7861798362721154905
+ },
+ "Component_[8535986786667781968]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 8535986786667781968
+ }
+ }
+ },
+ "Entity_[475371317793]": {
+ "Id": "Entity_[475371317793]",
+ "Name": "00_Illuminant",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{29C7358C-9899-56DF-8F99-F654C7138DB8}"
+ },
+ "assetHint": "materials/presets/macbeth/00_illuminant.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[471076350497]",
+ "Transform Data": {
+ "Translate": [
+ -0.020035700872540474,
+ 10.880657196044922,
+ 1.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[479666285089]": {
+ "Id": "Entity_[479666285089]",
+ "Name": "09_moderate_red",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{FD3D09E1-9B20-5761-87A2-388ADD3C966A}"
+ },
+ "assetHint": "materials/presets/macbeth/09_moderate_red.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[505436088865]",
+ "Transform Data": {
+ "Translate": [
+ -2.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[483961252385]": {
+ "Id": "Entity_[483961252385]",
+ "Name": "08_purplish_blue",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{0478869F-5E19-5A5C-AA22-0D31972E83B7}"
+ },
+ "assetHint": "materials/presets/macbeth/08_purplish_blue.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[505436088865]",
+ "Transform Data": {
+ "Translate": [
+ -6.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[488256219681]": {
+ "Id": "Entity_[488256219681]",
+ "Name": "07_orange",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{3E414822-FF6A-5A79-BF1A-66F4C48C381D}"
+ },
+ "assetHint": "materials/presets/macbeth/07_orange.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[505436088865]",
+ "Transform Data": {
+ "Translate": [
+ -10.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[492551186977]": {
+ "Id": "Entity_[492551186977]",
+ "Name": "10_purple",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{6A0A0CBE-FE95-5732-B2A9-442ABAC6B3AA}"
+ },
+ "assetHint": "materials/presets/macbeth/10_purple.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[505436088865]",
+ "Transform Data": {
+ "Translate": [
+ 1.8866175413131714,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[496846154273]": {
+ "Id": "Entity_[496846154273]",
+ "Name": "11_yellowish_green",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{8D382D9F-D56E-523E-8372-C372B002B81D}"
+ },
+ "assetHint": "materials/presets/macbeth/11_yellow_green.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[505436088865]",
+ "Transform Data": {
+ "Translate": [
+ 5.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[501141121569]": {
+ "Id": "Entity_[501141121569]",
+ "Name": "12_orange_yellow",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{7C8D9C96-8D79-5AA5-9A1D-DE68760127D7}"
+ },
+ "assetHint": "materials/presets/macbeth/12_orange_yellow.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[505436088865]",
+ "Transform Data": {
+ "Translate": [
+ 9.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[505436088865]": {
+ "Id": "Entity_[505436088865]",
+ "Name": "Row",
+ "Components": {
+ "Component_[10247332857034196288]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 10247332857034196288
+ },
+ "Component_[1050259146293298025]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1050259146293298025
+ },
+ "Component_[10963468433108777551]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10963468433108777551,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 5648156935684358836
+ }
+ ]
+ },
+ "Component_[11044618010943237536]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11044618010943237536
+ },
+ "Component_[11056805018150955063]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 11056805018150955063,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[488256219681]"
+ },
+ {
+ "EntityId": "Entity_[483961252385]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[479666285089]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[492551186977]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[496846154273]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[501141121569]",
+ "SortIndex": 5
+ }
+ ]
+ },
+ "Component_[11466054095979053511]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 11466054095979053511
+ },
+ "Component_[1364058654406679998]": {
+ "$type": "SelectionComponent",
+ "Id": 1364058654406679998
+ },
+ "Component_[1550934027474222562]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 1550934027474222562
+ },
+ "Component_[15938036103959223730]": {
+ "$type": "EditorLockComponent",
+ "Id": 15938036103959223730
+ },
+ "Component_[5648156935684358836]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 5648156935684358836,
+ "Parent Entity": "Entity_[471076350497]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 2.0,
+ 1.0
+ ]
+ }
+ }
+ }
+ },
+ "Entity_[509731056161]": {
+ "Id": "Entity_[509731056161]",
+ "Name": "Row",
+ "Components": {
+ "Component_[10247332857034196288]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 10247332857034196288
+ },
+ "Component_[1050259146293298025]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1050259146293298025
+ },
+ "Component_[10963468433108777551]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10963468433108777551,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 5648156935684358836
+ }
+ ]
+ },
+ "Component_[11044618010943237536]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11044618010943237536
+ },
+ "Component_[11056805018150955063]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 11056805018150955063,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[522615958049]"
+ },
+ {
+ "EntityId": "Entity_[518320990753]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[514026023457]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[526910925345]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[531205892641]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[535500859937]",
+ "SortIndex": 5
+ }
+ ]
+ },
+ "Component_[11466054095979053511]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 11466054095979053511
+ },
+ "Component_[1364058654406679998]": {
+ "$type": "SelectionComponent",
+ "Id": 1364058654406679998
+ },
+ "Component_[1550934027474222562]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 1550934027474222562
+ },
+ "Component_[15938036103959223730]": {
+ "$type": "EditorLockComponent",
+ "Id": 15938036103959223730
+ },
+ "Component_[5648156935684358836]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 5648156935684358836,
+ "Parent Entity": "Entity_[471076350497]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 6.0,
+ 1.0
+ ]
+ }
+ }
+ }
+ },
+ "Entity_[514026023457]": {
+ "Id": "Entity_[514026023457]",
+ "Name": "03_blue_sky",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{65DF9715-8D50-5852-BDDF-345BF9A36AAF}"
+ },
+ "assetHint": "materials/presets/macbeth/03_blue_sky.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[509731056161]",
+ "Transform Data": {
+ "Translate": [
+ -2.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[518320990753]": {
+ "Id": "Entity_[518320990753]",
+ "Name": "02_light_skin",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{0B0603C9-E7C3-5166-98EC-F8B3A4D469FB}"
+ },
+ "assetHint": "materials/presets/macbeth/02_light_skin.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[509731056161]",
+ "Transform Data": {
+ "Translate": [
+ -6.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[522615958049]": {
+ "Id": "Entity_[522615958049]",
+ "Name": "01_dark_skin",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{73B6CE55-0766-51FD-8D9C-92C60862D270}"
+ },
+ "assetHint": "materials/presets/macbeth/01_dark_skin.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[509731056161]",
+ "Transform Data": {
+ "Translate": [
+ -10.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[526910925345]": {
+ "Id": "Entity_[526910925345]",
+ "Name": "04_foliage",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{C11C560D-F984-5836-928A-45CF96179862}"
+ },
+ "assetHint": "materials/presets/macbeth/04_foliage.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[509731056161]",
+ "Transform Data": {
+ "Translate": [
+ 1.8866175413131714,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[531205892641]": {
+ "Id": "Entity_[531205892641]",
+ "Name": "05_blue_flower",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{3326A6D9-FEA4-5CDE-AE4A-8BD28DF3A7CA}"
+ },
+ "assetHint": "materials/presets/macbeth/05_blue_flower.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[509731056161]",
+ "Transform Data": {
+ "Translate": [
+ 5.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[535500859937]": {
+ "Id": "Entity_[535500859937]",
+ "Name": "06_bluish_green",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{BD7A8B80-242E-50CC-900F-9001945C5A0C}"
+ },
+ "assetHint": "materials/presets/macbeth/06_bluish_green.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[509731056161]",
+ "Transform Data": {
+ "Translate": [
+ 9.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[539795827233]": {
+ "Id": "Entity_[539795827233]",
+ "Name": "Row",
+ "Components": {
+ "Component_[10247332857034196288]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 10247332857034196288
+ },
+ "Component_[1050259146293298025]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1050259146293298025
+ },
+ "Component_[10963468433108777551]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10963468433108777551,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 5648156935684358836
+ }
+ ]
+ },
+ "Component_[11044618010943237536]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11044618010943237536
+ },
+ "Component_[11056805018150955063]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 11056805018150955063,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[552680729121]"
+ },
+ {
+ "EntityId": "Entity_[548385761825]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[544090794529]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[556975696417]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[561270663713]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[565565631009]",
+ "SortIndex": 5
+ }
+ ]
+ },
+ "Component_[11466054095979053511]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 11466054095979053511
+ },
+ "Component_[1364058654406679998]": {
+ "$type": "SelectionComponent",
+ "Id": 1364058654406679998
+ },
+ "Component_[1550934027474222562]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 1550934027474222562
+ },
+ "Component_[15938036103959223730]": {
+ "$type": "EditorLockComponent",
+ "Id": 15938036103959223730
+ },
+ "Component_[5648156935684358836]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 5648156935684358836,
+ "Parent Entity": "Entity_[471076350497]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ -2.0,
+ 1.0
+ ]
+ }
+ }
+ }
+ },
+ "Entity_[544090794529]": {
+ "Id": "Entity_[544090794529]",
+ "Name": "15_red",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{9C47066E-BD8F-5C1B-B935-933296BBE312}"
+ },
+ "assetHint": "materials/presets/macbeth/15_red.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[539795827233]",
+ "Transform Data": {
+ "Translate": [
+ -2.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[548385761825]": {
+ "Id": "Entity_[548385761825]",
+ "Name": "14_green",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{82346ED7-D369-5EF0-A7E0-70C1082EE073}"
+ },
+ "assetHint": "materials/presets/macbeth/14_green.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[539795827233]",
+ "Transform Data": {
+ "Translate": [
+ -6.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[552680729121]": {
+ "Id": "Entity_[552680729121]",
+ "Name": "13_blue",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{B8972ADB-DBA9-5807-9742-2B14453FDD96}"
+ },
+ "assetHint": "materials/presets/macbeth/13_blue.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[539795827233]",
+ "Transform Data": {
+ "Translate": [
+ -10.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[556975696417]": {
+ "Id": "Entity_[556975696417]",
+ "Name": "16_yellow",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{099BB2A1-F76E-5B77-BCFD-B0A6249F0EA3}"
+ },
+ "assetHint": "materials/presets/macbeth/16_yellow.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[539795827233]",
+ "Transform Data": {
+ "Translate": [
+ 1.8866175413131714,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[561270663713]": {
+ "Id": "Entity_[561270663713]",
+ "Name": "17_magenta",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{2A83451E-0FE6-508E-BAA2-6142AAA53C42}"
+ },
+ "assetHint": "materials/presets/macbeth/17_magenta.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[539795827233]",
+ "Transform Data": {
+ "Translate": [
+ 5.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[565565631009]": {
+ "Id": "Entity_[565565631009]",
+ "Name": "18_cyan",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{6949B983-05D6-50A4-9D43-A6CDAB2BF3F5}"
+ },
+ "assetHint": "materials/presets/macbeth/18_cyan.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[539795827233]",
+ "Transform Data": {
+ "Translate": [
+ 9.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[569860598305]": {
+ "Id": "Entity_[569860598305]",
+ "Name": "Row",
+ "Components": {
+ "Component_[10247332857034196288]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 10247332857034196288
+ },
+ "Component_[1050259146293298025]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1050259146293298025
+ },
+ "Component_[10963468433108777551]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10963468433108777551,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 5648156935684358836
+ }
+ ]
+ },
+ "Component_[11044618010943237536]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11044618010943237536
+ },
+ "Component_[11056805018150955063]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 11056805018150955063,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[582745500193]"
+ },
+ {
+ "EntityId": "Entity_[578450532897]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[574155565601]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[587040467489]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[591335434785]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[595630402081]",
+ "SortIndex": 5
+ }
+ ]
+ },
+ "Component_[11466054095979053511]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 11466054095979053511
+ },
+ "Component_[1364058654406679998]": {
+ "$type": "SelectionComponent",
+ "Id": 1364058654406679998
+ },
+ "Component_[1550934027474222562]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 1550934027474222562
+ },
+ "Component_[15938036103959223730]": {
+ "$type": "EditorLockComponent",
+ "Id": 15938036103959223730
+ },
+ "Component_[5648156935684358836]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 5648156935684358836,
+ "Parent Entity": "Entity_[471076350497]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ -6.0,
+ 1.0
+ ]
+ }
+ }
+ }
+ },
+ "Entity_[574155565601]": {
+ "Id": "Entity_[574155565601]",
+ "Name": "21_neutral_6.5",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{ADAA8BF6-1580-5684-A7F5-4B0150117375}"
+ },
+ "assetHint": "materials/presets/macbeth/21_neutral_6-5_0-44d.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[569860598305]",
+ "Transform Data": {
+ "Translate": [
+ -2.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[578450532897]": {
+ "Id": "Entity_[578450532897]",
+ "Name": "20_neutral_8",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{A9BAEC06-A3F6-53E9-9E3E-61E12048FC75}"
+ },
+ "assetHint": "materials/presets/macbeth/20_neutral_8-0_0-23d.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[569860598305]",
+ "Transform Data": {
+ "Translate": [
+ -6.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[582745500193]": {
+ "Id": "Entity_[582745500193]",
+ "Name": "19_white_9.5",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{94E3052F-2B5A-5C28-912A-C0FDC00F5CD3}"
+ },
+ "assetHint": "materials/presets/macbeth/19_white_9-5_0-05d.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[569860598305]",
+ "Transform Data": {
+ "Translate": [
+ -10.113382339477539,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[587040467489]": {
+ "Id": "Entity_[587040467489]",
+ "Name": "22_neutral_5",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{1E45E15B-8035-5775-B796-A77654CDB094}"
+ },
+ "assetHint": "materials/presets/macbeth/22_neutral_5-0_0-70d.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[569860598305]",
+ "Transform Data": {
+ "Translate": [
+ 1.8866175413131714,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[591335434785]": {
+ "Id": "Entity_[591335434785]",
+ "Name": "23_neutral_3.5",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{23C26041-7155-5FE2-8E12-FACFD52DA006}"
+ },
+ "assetHint": "materials/presets/macbeth/23_neutral_3-5_1-05d.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[569860598305]",
+ "Transform Data": {
+ "Translate": [
+ 5.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[595630402081]": {
+ "Id": "Entity_[595630402081]",
+ "Name": "24_black_2",
+ "Components": {
+ "Component_[12222961627447331506]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 12222961627447331506,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{1D83625A-4016-58F0-A94A-13B92B19F5B5}"
+ },
+ "assetHint": "materials/presets/macbeth/24_black_2-0_1-50d.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[12780007764330464223]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 12780007764330464223
+ },
+ "Component_[12904863407657276829]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 12904863407657276829,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 7205597372613518510
+ },
+ {
+ "ComponentId": 8564054653851438099,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 12222961627447331506,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[13729618014821386240]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13729618014821386240
+ },
+ "Component_[14429836600052599894]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 14429836600052599894
+ },
+ "Component_[14808014799413383215]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14808014799413383215
+ },
+ "Component_[17252932649882883756]": {
+ "$type": "SelectionComponent",
+ "Id": 17252932649882883756
+ },
+ "Component_[2229055145450914672]": {
+ "$type": "EditorLockComponent",
+ "Id": 2229055145450914672
+ },
+ "Component_[2249882080644631374]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 2249882080644631374
+ },
+ "Component_[7205597372613518510]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7205597372613518510,
+ "Parent Entity": "Entity_[569860598305]",
+ "Transform Data": {
+ "Translate": [
+ 9.886617660522461,
+ -9.999999974752427e-7,
+ 0.0
+ ],
+ "Rotate": [
+ 0.0,
+ 0.0,
+ 180.00001525878906
+ ]
+ }
+ },
+ "Component_[7918371639409185899]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 7918371639409185899
+ },
+ "Component_[8564054653851438099]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 8564054653851438099,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{D0F73AAF-52B7-507C-B045-DBE2FE2D4403}",
+ "subId": 268677693
+ },
+ "assetHint": "objects/shaderball_simple/shaberball_simple_1m.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ }
+ }
+ },
+ "Entity_[599925369377]": {
+ "Id": "Entity_[599925369377]",
+ "Name": "MacBeth_Chart",
+ "Components": {
+ "Component_[10911367092756441312]": {
+ "$type": "EditorLockComponent",
+ "Id": 10911367092756441312
+ },
+ "Component_[11487615730470734577]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 11487615730470734577
+ },
+ "Component_[1380862607750834390]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 1380862607750834390
+ },
+ "Component_[17376808010180534107]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 17376808010180534107
+ },
+ "Component_[18051852481298910543]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 18051852481298910543
+ },
+ "Component_[2468310869499941539]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 2468310869499941539
+ },
+ "Component_[3104847651593575388]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 3104847651593575388,
+ "Parent Entity": "Entity_[471076350497]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ 1.0
+ ],
+ "Scale": [
+ 24.748918533325195,
+ 24.748918533325195,
+ 24.748918533325195
+ ],
+ "UniformScale": 24.748918533325195
+ }
+ },
+ "Component_[4039743767801786212]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 4039743767801786212,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{767B3209-EDF7-503A-BF3D-6A69DAABC966}",
+ "subId": 285003870
+ },
+ "assetHint": "materialeditor/viewportmodels/plane_1x1.azmodel"
+ },
+ "LodOverride": 255
+ }
+ }
+ },
+ "Component_[4350883917310195183]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 4350883917310195183,
+ "Controller": {
+ "Configuration": {
+ "materials": {
+ "{}": {
+ "MaterialAsset": {
+ "assetId": {
+ "guid": "{6BCA78B0-98F0-5843-A0D9-2FD6AB5B8B95}"
+ },
+ "assetHint": "materials/presets/macbeth/macbeth_lab_16bit_2014_srgb.azmaterial"
+ }
+ }
+ }
+ }
+ },
+ "materialSlotsByLodEnabled": true
+ },
+ "Component_[5382697958657080154]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 5382697958657080154,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 3104847651593575388
+ },
+ {
+ "ComponentId": 4039743767801786212,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 4350883917310195183,
+ "SortIndex": 2
+ }
+ ]
+ },
+ "Component_[5944774294236360498]": {
+ "$type": "SelectionComponent",
+ "Id": 5944774294236360498
+ },
+ "Component_[7918181081161287223]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 7918181081161287223
+ }
+ }
+ },
+ "Entity_[604220336673]": {
+ "Id": "Entity_[604220336673]",
+ "Name": "Camera1",
+ "Components": {
+ "Component_[10875630838724467144]": {
+ "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+ "Id": 10875630838724467144,
+ "Controller": {
+ "Configuration": {
+ "EditorEntityId": 604220336673
+ }
+ }
+ },
+ "Component_[11853636775353879324]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 11853636775353879324,
+ "Parent Entity": "Entity_[471076350497]",
+ "Transform Data": {
+ "Translate": [
+ -0.088332898914814,
+ -14.735246658325195,
+ 12.247514724731445
+ ],
+ "Rotate": [
+ -34.60991287231445,
+ 0.19504709541797638,
+ -0.282683789730072
+ ]
+ }
+ },
+ "Component_[14115131108729471373]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14115131108729471373
+ },
+ "Component_[14490537709933782275]": {
+ "$type": "SelectionComponent",
+ "Id": 14490537709933782275
+ },
+ "Component_[15389860813854215395]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 15389860813854215395
+ },
+ "Component_[16956210187152487952]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 16956210187152487952
+ },
+ "Component_[3120168445836073859]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 3120168445836073859,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 11853636775353879324
+ },
+ {
+ "ComponentId": 6418726603140010485,
+ "SortIndex": 1
+ },
+ {
+ "ComponentId": 6573470892650938647,
+ "SortIndex": 2
+ },
+ {
+ "ComponentId": 10875630838724467144,
+ "SortIndex": 3
+ },
+ {
+ "ComponentId": 9127356411199949930,
+ "SortIndex": 4
+ }
+ ]
+ },
+ "Component_[397791896240265054]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 397791896240265054
+ },
+ "Component_[6418726603140010485]": {
+ "$type": "AZ::Render::EditorExposureControlComponent",
+ "Id": 6418726603140010485,
+ "Controller": {
+ "Configuration": {
+ "ExposureControlType": 1,
+ "EyeAdaptationExposureMin": -10.0,
+ "EyeAdaptationExposureMax": 10.0
+ }
+ }
+ },
+ "Component_[6572845495569063152]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 6572845495569063152
+ },
+ "Component_[6573470892650938647]": {
+ "$type": "AZ::Render::EditorPostFxLayerComponent",
+ "Id": 6573470892650938647
+ },
+ "Component_[7175586201406734874]": {
+ "$type": "EditorLockComponent",
+ "Id": 7175586201406734874
+ },
+ "Component_[7393764569438584638]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7393764569438584638
+ },
+ "Component_[9127356411199949930]": {
+ "$type": "GenericComponentWrapper",
+ "Id": 9127356411199949930,
+ "m_template": {
+ "$type": "FlyCameraInputComponent"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Levels/macbeth_shaderballs/tags.txt b/AutomatedTesting/Levels/macbeth_shaderballs/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/macbeth_shaderballs/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/Objects/sphere_5lods.fbx b/AutomatedTesting/Objects/sphere_5lods.fbx
new file mode 100644
index 0000000000..965738c933
--- /dev/null
+++ b/AutomatedTesting/Objects/sphere_5lods.fbx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7e169277bca473325281d5fe043cffc9196bd3ef46f6bffbea6e0b5e3b7194a1
+size 62700
diff --git a/AutomatedTesting/Objects/sphere_5lods.fbx.assetinfo b/AutomatedTesting/Objects/sphere_5lods.fbx.assetinfo
new file mode 100644
index 0000000000..d46cbf322a
--- /dev/null
+++ b/AutomatedTesting/Objects/sphere_5lods.fbx.assetinfo
@@ -0,0 +1,8 @@
+{
+ "values": [
+ {
+ "$type": "ScriptProcessorRule",
+ "scriptFilename": "Editor/Scripts/auto_lod.py"
+ }
+ ]
+}
diff --git a/AutomatedTesting/Passes/MainPipeline.pass b/AutomatedTesting/Passes/MainPipeline.pass
index aa9f3757c4..c34c556983 100644
--- a/AutomatedTesting/Passes/MainPipeline.pass
+++ b/AutomatedTesting/Passes/MainPipeline.pass
@@ -205,6 +205,99 @@
}
]
},
+
+ {
+ // NOTE: HairParentPass does not write into Depth MSAA from Opaque Pass. If new passes downstream
+ // of HairParentPass will need to use Depth MSAA, HairParentPass will need to be updated to use Depth MSAA
+ // instead of regular Depth as DepthStencil. Specifically, HairResolvePPLL.pass and the associated
+ // .azsl file will need to be updated.
+ "Name": "HairParentPass",
+ // Note: The following two lines represent the choice of rendering pipeline for the hair.
+ // You can either choose to use PPLL or ShortCut and accordingly change the flag
+ // 'm_usePPLLRenderTechnique' in the class 'HairFeatureProcessor.cpp'
+// "TemplateName": "HairParentPassTemplate",
+ "TemplateName": "HairParentShortCutPassTemplate",
+ "Enabled": true,
+ "Connections": [
+ // Critical to keep DepthLinear as input - used to set the size of the Head PPLL image buffer.
+ // If DepthLinear is not available - connect to another viewport (non MSAA) image.
+ {
+ "LocalSlot": "DepthLinearInput",
+ "AttachmentRef": {
+ "Pass": "DepthPrePass",
+ "Attachment": "DepthLinear"
+ }
+ },
+ {
+ "LocalSlot": "Depth",
+ "AttachmentRef": {
+ "Pass": "DepthPrePass",
+ "Attachment": "Depth"
+ }
+ },
+ {
+ "LocalSlot": "RenderTargetInputOutput",
+ "AttachmentRef": {
+ "Pass": "OpaquePass",
+ "Attachment": "Output"
+ }
+ },
+ {
+ "LocalSlot": "RenderTargetInputOnly",
+ "AttachmentRef": {
+ "Pass": "OpaquePass",
+ "Attachment": "Output"
+ }
+ },
+
+ // Shadows resources
+ {
+ "LocalSlot": "DirectionalShadowmap",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "DirectionalShadowmap"
+ }
+ },
+ {
+ "LocalSlot": "DirectionalESM",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "DirectionalESM"
+ }
+ },
+ {
+ "LocalSlot": "ProjectedShadowmap",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "ProjectedShadowmap"
+ }
+ },
+ {
+ "LocalSlot": "ProjectedESM",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "ProjectedESM"
+ }
+ },
+
+ // Lighting Resources
+ {
+ "LocalSlot": "TileLightData",
+ "AttachmentRef": {
+ "Pass": "LightCullingPass",
+ "Attachment": "TileLightData"
+ }
+ },
+ {
+ "LocalSlot": "LightListRemapped",
+ "AttachmentRef": {
+ "Pass": "LightCullingPass",
+ "Attachment": "LightListRemapped"
+ }
+ }
+ ]
+ },
+
{
"Name": "TransparentPass",
"TemplateName": "TransparentParentTemplate",
@@ -254,22 +347,22 @@
{
"LocalSlot": "InputLinearDepth",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "DepthLinear"
}
},
{
"LocalSlot": "DepthStencil",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "Depth"
}
},
{
"LocalSlot": "InputOutput",
"AttachmentRef": {
- "Pass": "OpaquePass",
- "Attachment": "Output"
+ "Pass": "HairParentPass",
+ "Attachment": "RenderTargetInputOutput"
}
}
]
@@ -282,22 +375,22 @@
{
"LocalSlot": "InputLinearDepth",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "DepthLinear"
}
},
{
"LocalSlot": "InputDepthStencil",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "Depth"
}
},
{
"LocalSlot": "RenderTargetInputOutput",
"AttachmentRef": {
- "Pass": "TransparentPass",
- "Attachment": "InputOutput"
+ "Pass": "HairParentPass",
+ "Attachment": "RenderTargetInputOutput"
}
}
],
@@ -337,7 +430,7 @@
{
"LocalSlot": "Depth",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "Depth"
}
},
@@ -372,7 +465,7 @@
{
"LocalSlot": "DepthInputOutput",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "Depth"
}
}
@@ -431,7 +524,7 @@
{
"LocalSlot": "DepthInputOutput",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "Depth"
}
}
@@ -451,7 +544,7 @@
{
"LocalSlot": "DepthInputOutput",
"AttachmentRef": {
- "Pass": "DepthPrePass",
+ "Pass": "HairParentPass",
"Attachment": "Depth"
}
}
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/AutomatedTesting/Registry/editorpreferences.setreg b/AutomatedTesting/Registry/editorpreferences.setreg
index b338d6acad..e76e04f9ba 100644
--- a/AutomatedTesting/Registry/editorpreferences.setreg
+++ b/AutomatedTesting/Registry/editorpreferences.setreg
@@ -1,7 +1,7 @@
{
"Amazon": {
"Preferences": {
- "EnablePrefabSystem": false
+ "EnablePrefabSystem": true
}
}
}
\ No newline at end of file
diff --git a/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt b/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt
index d3975ced7c..8084defe84 100644
--- a/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt
+++ b/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt
@@ -2,24 +2,24 @@ These tests are mostly done with files that have a different extension between s
The source scan is done first, and will catch files in the source path.
Product path searching is resolved using "endsWith" logic.
textures/_dev_purple.tif.streamingimage
-Back slashes, and project name in the path
-pc/textures/_dev_stucco.tif.streamingimage
+Back slashes
+textures\_dev_stucco.tif.streamingimage
Double back slashes
textures\\_dev_tan.tif.streamingimage
Casing doesn't match
TEXTURES/_DEV_WHITE.tif.streamingimage
Some files have multiple extensions, this verifies that won't trip up the scanner.
textures/_dev_yellow_light.tif.1002.imagemipchain
-Path inline textures/milestone2/ama_grey_02.tif.streamingimage test
+Path inline textures/_dev_woodland.tif.1002.imagemipchain test
Path after=textures/_dev_woodland.tif.streamingimage equal sign
Multiple paths on one line
-Multiple materials/am_grass1.mtl paths materials/am_rockground.mtl on one line
-Path before a UUID
-Path materials/floor_tile.mtl before B92667DC-9F5B-5D72-A29D-99219DD9B691 a UUID
-Path before an asset ID
-Path ui/milestone2menu.uicanvas before an 2ef92b8D044E5C278E2BB1AC0374A4E7:1002 asset ID
-Path after a UUID
-Path after CEAA362B4E505BCEB827CB92EF40A50E a project.json UUID
-Path after an asset ID
-Path after {A2482826-053D-5634-A27B-084B1326AAE5}:[1002] an libs/particles/milestone2particles.xml asset ID
+Multiple textures/_dev_yellow_light.tif.streamingimage paths textures/_dev_yellow_med.tif.1002.imagemipchain on one line
+Path before a UUID for SelfReferenceUUID text file
+Path textures/lights/flare01.tif.streamingimage before 33BCEE02-F322-5688-ABEE-534F6058593F a UUID
+Path before an asset ID for _dev_red image
+Path textures/test_texture_sequence/test_texture_sequence000.png.streamingimage before an 2ef92b8D044E5C278E2BB1AC0374A4E7:1002 asset ID
+Path after a UUID for SelfReferenceAssetID text file
+Path after 785A05D2-483E-5B43-A2B9-92ACDAE6E938 a textures/test_texture_sequence/test_texture_sequence001.png.streamingimage UUID
+Path after an asset ID for _dev_purple image file
+Path after {A2482826-053D-5634-A27B-084B1326AAE5}:[1002] an textures/_dev_purple_glass.tif.1002.imagemipchain asset ID
diff --git a/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt b/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt
index a5ae046b11..df3bcc896e 100644
--- a/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt
+++ b/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt
@@ -3,6 +3,6 @@ TestAssets/RelativeProductPathsNotDependencies.txt
Back slashes
TestAssets\WildcardScanTest1.txt
Casing doesn't match
-libs/particles/milestone2PARTICLES.XML
-Path inline project.json test
+TESTASSETS/ReportONEmISSINGdEPENDENCY.tXT
+Path inline TestAssets/InvalidAssetIdNoReport.txt test
Path after=textures/_dev_Purple.tif equal sign
diff --git a/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt b/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt
index 4cda459232..0b9df7c99d 100644
--- a/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt
+++ b/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt
@@ -1,5 +1,7 @@
+File extensions are separated from file names, so the missing dependency scanner doesn't find when scanning, and only finds the asset IDs in this file.
+
/textures /_dev_Purple . tif, the product ID is for one of the mips.
{A2482826-053D-5634-A27B-084B1326AAE5}:[1002]
_dev_Red . tif, another mip, different formatting.
-2ef92b8D044E5C278E2BB1AC0374A4E7:1003
+2ef92b8D044E5C278E2BB1AC0374A4E7:1000
_dev_White.tif, {D83B36F1-61A6-5001-B191-4D0CE282E236}-1002 asset ID inline.
diff --git a/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt b/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt
index 436d6fb628..91c518ef2f 100644
--- a/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt
+++ b/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt
@@ -1,18 +1,19 @@
Paths are broken up to avoid having them show up as relative path results.
+All references are to other text files in this folder, extensions are omitted to make sure only UUID scanning finds these references.
-This is the UUID for Materials / Default / AM_UV_v1_1K_source . png
-C67BEA9F-09FF-59AA-A7F0-A52B8F987508
-This is the UUID for libs / particles / milestone2particles . xml. This tests UUIDs without separators.
-6BDE282B49C957F7B0714B26579BCA9A
-This is the UUID for SelfReferenceUUID.txt. This tests UUIDs with mixed casing.
+This is the UUID for InvalidAssetIdNoReport
+E68A85B0-131D-5A82-B2D5-BC58EE4062AE
+This is the UUID for InvalidRelativePathsNoReport. This tests UUIDs without separators.
+B3EF12DD306C520EB0A8A6B0D031A195
+This is the UUID for SelfReferenceUUID. This tests UUIDs with mixed casing.
33bcee02F3225688ABEE534F6058593F
-This is a UUID mid-line B076CDDC-14DF-50F4-A5E9-7518ABB3E851, for project . json
+This is a UUID mid-line DD587FBE-16C8-5B98-AE3C-A9F8750B2692, for SelfReferencePath
-Two UUIDs on the same line
-Two UUIDs 345E5C660D6254FF8D0F7C8EE66A2249 mixed on A26C73D1837E5AE59E68F916FA7C3699 the same line
+InvalidUUIDNoReport and MaxIteration31Deep
+Two UUIDs 837412DF-D05F-576D-81AA-ACF360463749 mixed on 3F642A0FDC825696A70A1DA5709744DF the same line
Test UUIDs and Asset IDs mixed on the same line. Relative paths are handled in the relative path tests.
-UUID: slices / MuzzleFlash . slice, AssetID: TestsAssets / WildcardScanTest1 . txt
-This 747D31D71E62553592226173C49CF97E uuid is on the line with 1CB10C43F3245B93A294C602ADEF95F9:[0] a valid asset ID
-UUID: Objects / Lumbertank_turret . cgf, AssetID: TestsAssets / WildcardScanTest2 . txt
-This D92C4661C8985E19BD3597CB2318CFA6:[0] uuid is on the line with 37108522F50459499CD6C8D47A960CF1 a valid asset ID
+OnlyMatchesCorrectLengthUUIDs and WildcardScanTest1
+This 2545AD8B-1B9B-5F93-859D-D8DC1DC2B480 uuid is on the line with 1CB10C43F3245B93A294C602ADEF95F9:[0] a valid asset ID
+RelativeProductPathsNotDependencies and WildcardScanTest2
+This B772953CA08A5D209491530E87D11504:[0] uuid is on the line with D92C4661C8985E19BD3597CB2318CFA6 a valid asset ID
diff --git a/Code/Editor/2DViewport.h b/Code/Editor/2DViewport.h
index 68823acdb7..e89f4aed34 100644
--- a/Code/Editor/2DViewport.h
+++ b/Code/Editor/2DViewport.h
@@ -62,7 +62,6 @@ public:
// ovverided from CViewport.
float GetScreenScaleFactor(const Vec3& worldPoint) const override;
- float GetScreenScaleFactor([[maybe_unused]] const CCamera& camera, [[maybe_unused]] const Vec3& object_position) override { return 1; } //Eric@conffx
// Overrided from CViewport.
void OnDragSelectRectangle(const QRect &rect, bool bNormalizeRect = false) override;
diff --git a/Code/Editor/AboutDialog.ui b/Code/Editor/AboutDialog.ui
index a36d65e35b..09a7c18841 100644
--- a/Code/Editor/AboutDialog.ui
+++ b/Code/Editor/AboutDialog.ui
@@ -125,7 +125,7 @@
- Stable 21.11
+ development
Qt::AutoText
diff --git a/Code/Editor/Animation/AnimationBipedBoneNames.cpp b/Code/Editor/Animation/AnimationBipedBoneNames.cpp
index d9f1b845ca..72502fe61d 100644
--- a/Code/Editor/Animation/AnimationBipedBoneNames.cpp
+++ b/Code/Editor/Animation/AnimationBipedBoneNames.cpp
@@ -10,24 +10,21 @@
#include "AnimationBipedBoneNames.h"
-namespace EditorAnimationBones
+namespace EditorAnimationBones::Biped
{
- namespace Biped
- {
- const char* Pelvis = "Bip01 Pelvis";
- const char* Head = "Bip01 Head";
- const char* Weapon = "weapon_bone";
+ const char* Pelvis = "Bip01 Pelvis";
+ const char* Head = "Bip01 Head";
+ const char* Weapon = "weapon_bone";
- const char* LeftEye = "eye_bone_left";
- const char* RightEye = "eye_bone_right";
+ const char* LeftEye = "eye_bone_left";
+ const char* RightEye = "eye_bone_right";
- const char* Spine[5] = { "Bip01 Spine", "Bip01 Spine1", "Bip01 Spine2", "Bip01 Spine3", "Bip01 Spine4" };
- const char* Neck[2] = { "Bip01 Neck", "Bip01 Neck1" };
+ const char* Spine[5] = { "Bip01 Spine", "Bip01 Spine1", "Bip01 Spine2", "Bip01 Spine3", "Bip01 Spine4" };
+ const char* Neck[2] = { "Bip01 Neck", "Bip01 Neck1" };
- const char* LeftHeel = "Bip01 L Heel";
- const char* LeftToe[2] = { "Bip01 L Toe0", "Bip01 L Toe1" };
+ const char* LeftHeel = "Bip01 L Heel";
+ const char* LeftToe[2] = { "Bip01 L Toe0", "Bip01 L Toe1" };
- const char* RightHeel = "Bip01 R Heel";
- const char* RightToe[2] = { "Bip01 R Toe0", "Bip01 R Toe1" };
- }
-}
+ const char* RightHeel = "Bip01 R Heel";
+ const char* RightToe[2] = { "Bip01 R Toe0", "Bip01 R Toe1" };
+} // namespace EditorAnimationBones::Biped
diff --git a/Code/Editor/AnimationContext.cpp b/Code/Editor/AnimationContext.cpp
index fce1150878..51dd8deefc 100644
--- a/Code/Editor/AnimationContext.cpp
+++ b/Code/Editor/AnimationContext.cpp
@@ -21,6 +21,8 @@
#include "Include/IObjectManager.h"
#include "Objects/EntityObject.h"
+#include
+
//////////////////////////////////////////////////////////////////////////
// Movie Callback.
//////////////////////////////////////////////////////////////////////////
@@ -499,25 +501,24 @@ void CAnimationContext::Update()
return;
}
- ITimer* pTimer = GetIEditor()->GetSystem()->GetITimer();
+ const AZ::TimeUs frameDeltaTimeUs = AZ::GetSimulationTickDeltaTimeUs();
+ const float frameDeltaTime = AZ::TimeUsToSeconds(frameDeltaTimeUs);
if (!m_bAutoRecording)
{
AnimateActiveSequence();
- float dt = pTimer->GetFrameTime();
- m_currTime += dt * m_fTimeScale;
+ m_currTime += frameDeltaTime * m_fTimeScale;
if (!m_recording)
{
- GetIEditor()->GetMovieSystem()->PreUpdate(dt);
- GetIEditor()->GetMovieSystem()->PostUpdate(dt);
+ GetIEditor()->GetMovieSystem()->PreUpdate(frameDeltaTime);
+ GetIEditor()->GetMovieSystem()->PostUpdate(frameDeltaTime);
}
}
else
{
- float dt = pTimer->GetFrameTime();
- m_fRecordingCurrTime += dt * m_fTimeScale;
+ m_fRecordingCurrTime += frameDeltaTime * m_fTimeScale;
if (fabs(m_fRecordingCurrTime - m_currTime) > m_fRecordingTimeStep)
{
m_currTime += m_fRecordingTimeStep;
@@ -644,7 +645,9 @@ void CAnimationContext::OnPostRender()
{
SAnimContext ac;
ac.dt = 0;
- ac.fps = GetIEditor()->GetSystem()->GetITimer()->GetFrameRate();
+ const AZ::TimeUs frameDeltaTimeUs = AZ::GetSimulationTickDeltaTimeUs();
+ const float frameDeltaTime = AZ::TimeUsToSeconds(frameDeltaTimeUs);
+ ac.fps = 1.0f / frameDeltaTime;
ac.time = m_currTime;
ac.singleFrame = true;
ac.forcePlay = true;
@@ -797,7 +800,9 @@ void CAnimationContext::AnimateActiveSequence()
SAnimContext ac;
ac.dt = 0;
- ac.fps = GetIEditor()->GetSystem()->GetITimer()->GetFrameRate();
+ const AZ::TimeUs frameDeltaTimeUs = AZ::GetSimulationTickDeltaTimeUs();
+ const float frameDeltaTime = AZ::TimeUsToSeconds(frameDeltaTimeUs);
+ ac.fps = 1.0f / frameDeltaTime;
ac.time = m_currTime;
ac.singleFrame = true;
ac.forcePlay = true;
diff --git a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp
index b721b8759e..baa287e47f 100644
--- a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp
+++ b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp
@@ -140,7 +140,7 @@ bool AssetImporterManager::OnBrowseFiles()
bool encounteredCrate = false;
QStringList invalidFiles;
- for (QString path : fileDialog.selectedFiles())
+ for (const QString& path : fileDialog.selectedFiles())
{
QString fileName = GetFileName(path);
QFileInfo info(path);
diff --git a/Code/Editor/BaseLibrary.cpp b/Code/Editor/BaseLibrary.cpp
index 9f26630c2c..15742bd254 100644
--- a/Code/Editor/BaseLibrary.cpp
+++ b/Code/Editor/BaseLibrary.cpp
@@ -14,66 +14,6 @@
#include "Include/IBaseLibraryManager.h"
#include
#include
-#include "Undo/IUndoObject.h"
-
-//////////////////////////////////////////////////////////////////////////
-// Undo functionality for libraries.
-//////////////////////////////////////////////////////////////////////////
-
-class CUndoBaseLibrary
- : public IUndoObject
-{
-public:
- CUndoBaseLibrary(CBaseLibrary* pLib, const QString& description, const QString& selectedItem = QString())
- : m_pLib(pLib)
- , m_description(description)
- , m_redo(nullptr)
- , m_selectedItem(selectedItem)
- {
- assert(m_pLib);
-
- m_undo = GetIEditor()->GetSystem()->CreateXmlNode("Undo");
- m_pLib->Serialize(m_undo, false);
- }
-
- QString GetEditorObjectName() override
- {
- return m_selectedItem;
- }
-
-protected:
- int GetSize() override { return sizeof(CUndoBaseLibrary); }
- QString GetDescription() override { return m_description; };
-
- void Undo(bool bUndo) override
- {
- if (bUndo)
- {
- m_redo = GetIEditor()->GetSystem()->CreateXmlNode("Redo");
- m_pLib->Serialize(m_redo, false);
- }
- m_pLib->Serialize(m_undo, true);
- m_pLib->SetModified();
- GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
- }
-
- void Redo() override
- {
- m_pLib->Serialize(m_redo, true);
- m_pLib->SetModified();
- GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
- }
-
-private:
- QString m_description;
- QString m_selectedItem;
- _smart_ptr m_pLib;
- XmlNodeRef m_undo;
- XmlNodeRef m_redo;
-};
-
-
-
//////////////////////////////////////////////////////////////////////////
// CBaseLibrary implementation.
diff --git a/Code/Editor/BaseLibraryItem.cpp b/Code/Editor/BaseLibraryItem.cpp
index b1fba91fad..e3788bc3e4 100644
--- a/Code/Editor/BaseLibraryItem.cpp
+++ b/Code/Editor/BaseLibraryItem.cpp
@@ -29,7 +29,6 @@ public:
assert(libMgr);
m_itemPath = libItem->GetFullName();
- m_description = "Lib item changed: " + m_itemPath;
//serialize the lib item to undo
m_undoCtx.node = GetIEditor()->GetSystem()->CreateXmlNode("Undo");
@@ -45,13 +44,8 @@ public:
m_size = sizeof(CUndoBaseLibraryItem);
m_size += static_cast(xmlStr.GetAllocatedMemory());
m_size += m_itemPath.length();
- m_size += m_description.length();
}
- QString GetEditorObjectName() override
- {
- return m_itemPath;
- }
protected:
int GetSize() override
@@ -59,11 +53,6 @@ protected:
return m_size;
}
- QString GetDescription() override
- {
- return m_description;
- }
-
void Undo(bool bUndo) override
{
//find the libItem
@@ -111,7 +100,6 @@ protected:
}
private:
- QString m_description;
QString m_itemPath;
IDataBaseItem::SerializeContext m_undoCtx; //saved before operation
IDataBaseItem::SerializeContext m_redoCtx; //saved after operation so used for redo
diff --git a/Code/Editor/BaseLibraryManager.cpp b/Code/Editor/BaseLibraryManager.cpp
index 7346ffaf8c..0e51a5238c 100644
--- a/Code/Editor/BaseLibraryManager.cpp
+++ b/Code/Editor/BaseLibraryManager.cpp
@@ -17,120 +17,6 @@
#include "ErrorReport.h"
#include "Undo/IUndoObject.h"
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Undo functionality for Managers, including add library, remove library, and rename library -- Vera, Confetti
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class CUndoBaseLibraryManager
- : public IUndoObject
-{
-public:
- CUndoBaseLibraryManager(CBaseLibraryManager* pMngr, const QString& description, const QString& modifiedManager = nullptr)
- : m_pMngr(pMngr)
- , m_description(description)
- , m_editorObject(modifiedManager)
- {
- assert(m_pMngr);
- SerializeTo(m_undos);
- }
-
- QString GetEditorObjectName() override
- {
- return m_editorObject;
- }
-
-protected:
- int GetSize() override { return sizeof(CUndoBaseLibraryManager); }
- QString GetDescription() override { return m_description; };
-
- void Undo(bool bUndo) override
- {
- if (bUndo)
- {
- SerializeTo(m_redos);
- }
- m_pMngr->ClearAll();
- UnserializeFrom(m_undos);
- GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
- }
-
- void Redo() override
- {
- m_pMngr->ClearAll();
- UnserializeFrom(m_redos);
- GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
- }
-
-private:
- struct LibUndoNode
- : public _i_reference_target_t
- {
- LibUndoNode()
- {
- node = nullptr;
- fileName = "";
- }
- XmlNodeRef node;
- QString fileName;
- };
-
- static const char* const LIBRARY_TAG;
- static const char* const LEVEL_LIBRARY_TAG;
-
- void SerializeTo(std::vector<_smart_ptr >& undos) // Save Library Undo
- {
- undos.clear();
- for (int i = 0; i < m_pMngr->GetLibraryCount(); i++)
- {
- IDataBaseLibrary* library = m_pMngr->GetLibrary(i);
-
- const char* tag = library->IsLevelLibrary() ? LEVEL_LIBRARY_TAG : LIBRARY_TAG;
- XmlNodeRef node = GetIEditor()->GetSystem()->CreateXmlNode(tag);
- QString file = library->GetFilename().isEmpty() ? library->GetFilename() : library->GetName();
- library->Serialize(node, false);
- if (node && !file.isEmpty())
- {
- _smart_ptr undo = new LibUndoNode();
- undo->fileName = file;
- undo->node = node;
- undos.push_back(undo);
- }
- }
- }
-
- void UnserializeFrom(std::vector<_smart_ptr >& undos) // Load Library Undo
- {
- for (int i = 0; i < undos.size(); i++)
- {
- _smart_ptr undo = undos[i];
- if (undo->node && !undo->fileName.isEmpty())
- {
- //AddLibrary adds a .xml to the end of the library path, this will remove the extra for compatibility
- undo->fileName.replace(m_pMngr->GetLibsPath().toLower(), "");
- undo->fileName.replace(".xml", "");
-
- const bool isLevelLibrary = (strcmp(undo->node->getTag(), LEVEL_LIBRARY_TAG) == 0);
-
- IDataBaseLibrary* library = m_pMngr->AddLibrary(undo->fileName, isLevelLibrary);
- library->Serialize(undo->node, true);
- }
- }
- }
-
-
- QString m_description;
- QString m_editorObject;
- CBaseLibraryManager* m_pMngr;
- std::vector<_smart_ptr > m_undos;
- std::vector<_smart_ptr > m_redos;
-};
-
-const char* const CUndoBaseLibraryManager::LIBRARY_TAG = "UndoLibrary";
-const char* const CUndoBaseLibraryManager::LEVEL_LIBRARY_TAG = "UndoLevelLibrary";
-
-
-
//////////////////////////////////////////////////////////////////////////
// CBaseLibraryManager implementation.
//////////////////////////////////////////////////////////////////////////
@@ -606,11 +492,9 @@ void CBaseLibraryManager::RegisterItem(CBaseLibraryItem* pItem, REFGUID newGuid)
if (m_bUniqGuidMap)
{
- bool bNewItem = true;
REFGUID oldGuid = pItem->GetGUID();
if (!GuidUtil::IsEmpty(oldGuid))
{
- bNewItem = false;
m_itemsGuidMap.erase(oldGuid);
}
if (GuidUtil::IsEmpty(newGuid))
diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt
index e55498203c..3358b49dce 100644
--- a/Code/Editor/CMakeLists.txt
+++ b/Code/Editor/CMakeLists.txt
@@ -249,38 +249,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
RUNTIME_DEPENDENCIES
Gem::LmbrCentral
)
+
ly_add_googletest(
NAME Legacy::EditorLib.Tests
)
- ly_add_target(
- NAME EditorLib.Camera.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
- NAMESPACE Legacy
- FILES_CMAKE
- Lib/Tests/Camera/editor_lib_camera_test_files.cmake
- INCLUDE_DIRECTORIES
- PRIVATE
- .
- BUILD_DEPENDENCIES
- PRIVATE
- AZ::AzCore
- AZ::AzTest
- AZ::AzToolsFramework
- AZ::AzTestShared
- Legacy::EditorLib
- Gem::Camera.Editor
- Gem::AtomToolsFramework.Static
- RUNTIME_DEPENDENCIES
- Legacy::EditorLib
- )
-
- ly_add_source_properties(
- SOURCES Lib/Tests/Camera/test_EditorCamera.cpp
- PROPERTY COMPILE_DEFINITIONS
- VALUES CAMERA_EDITOR_MODULE="$"
- )
-
- ly_add_googletest(
- NAME Legacy::EditorLib.Camera.Tests
- )
endif()
diff --git a/Code/Editor/CVarMenu.h b/Code/Editor/CVarMenu.h
index efcc8e8caf..5195bd99d7 100644
--- a/Code/Editor/CVarMenu.h
+++ b/Code/Editor/CVarMenu.h
@@ -16,9 +16,12 @@
#include
#include
+struct ICVar;
+
class CVarMenu
: public QMenu
{
+ Q_OBJECT
public:
// CVar that can be toggled on and off
struct CVarToggle
diff --git a/Code/Editor/ConfigGroup.cpp b/Code/Editor/ConfigGroup.cpp
index 74fe6f7b5c..42236e43dd 100644
--- a/Code/Editor/ConfigGroup.cpp
+++ b/Code/Editor/ConfigGroup.cpp
@@ -19,10 +19,9 @@ namespace Config
CConfigGroup::~CConfigGroup()
{
- for (TConfigVariables::const_iterator it = m_vars.begin();
- it != m_vars.end(); ++it)
+ for (IConfigVar* var : m_vars)
{
- delete (*it);
+ delete var;
}
}
@@ -31,17 +30,15 @@ namespace Config
m_vars.push_back(var);
}
- uint32 CConfigGroup::GetVarCount()
+ AZ::u32 CConfigGroup::GetVarCount()
{
- return static_cast(m_vars.size());
+ return aznumeric_cast(m_vars.size());
}
IConfigVar* CConfigGroup::GetVar(const char* szName)
{
- for (TConfigVariables::const_iterator it = m_vars.begin();
- it != m_vars.end(); ++it)
+ for (IConfigVar* var : m_vars)
{
- IConfigVar* var = (*it);
if (0 == _stricmp(szName, var->GetName().c_str()))
{
return var;
@@ -53,20 +50,19 @@ namespace Config
const IConfigVar* CConfigGroup::GetVar(const char* szName) const
{
- for (TConfigVariables::const_iterator it = m_vars.begin();
- it != m_vars.end(); ++it)
+ for (const IConfigVar* var : m_vars)
{
- IConfigVar* var = (*it);
if (0 == _stricmp(szName, var->GetName().c_str()))
{
return var;
}
+
}
return nullptr;
}
- IConfigVar* CConfigGroup::GetVar(uint index)
+ IConfigVar* CConfigGroup::GetVar(AZ::u32 index)
{
if (index < m_vars.size())
{
@@ -76,7 +72,7 @@ namespace Config
return nullptr;
}
- const IConfigVar* CConfigGroup::GetVar(uint index) const
+ const IConfigVar* CConfigGroup::GetVar(AZ::u32 index) const
{
if (index < m_vars.size())
{
@@ -89,114 +85,110 @@ namespace Config
void CConfigGroup::SaveToXML(XmlNodeRef node)
{
// save only values that don't have default values
- for (TConfigVariables::const_iterator it = m_vars.begin();
- it != m_vars.end(); ++it)
+ for (const IConfigVar* var : m_vars)
{
- IConfigVar* var = (*it);
- if (!var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
+ if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave) || var->IsDefault())
{
- if (!var->IsDefault())
- {
- const char* szName = var->GetName().c_str();
+ continue;
+ }
- switch (var->GetType())
- {
- case IConfigVar::eType_BOOL:
- {
- bool currentValue = false;
- var->Get(¤tValue);
- node->setAttr(szName, currentValue);
- break;
- }
+ const char* szName = var->GetName().c_str();
- case IConfigVar::eType_INT:
- {
- int currentValue = 0;
- var->Get(¤tValue);
- node->setAttr(szName, currentValue);
- break;
- }
+ switch (var->GetType())
+ {
+ case IConfigVar::eType_BOOL:
+ {
+ bool currentValue = false;
+ var->Get(¤tValue);
+ node->setAttr(szName, currentValue);
+ break;
+ }
- case IConfigVar::eType_FLOAT:
- {
- float currentValue = 0;
- var->Get(¤tValue);
- node->setAttr(szName, currentValue);
- break;
- }
+ case IConfigVar::eType_INT:
+ {
+ int currentValue = 0;
+ var->Get(¤tValue);
+ node->setAttr(szName, currentValue);
+ break;
+ }
- case IConfigVar::eType_STRING:
- {
- AZStd::string currentValue;
- var->Get(¤tValue);
- node->setAttr(szName, currentValue.c_str());
- break;
- }
- }
- }
+ case IConfigVar::eType_FLOAT:
+ {
+ float currentValue = 0;
+ var->Get(¤tValue);
+ node->setAttr(szName, currentValue);
+ break;
+ }
+
+ case IConfigVar::eType_STRING:
+ {
+ AZStd::string currentValue;
+ var->Get(¤tValue);
+ node->setAttr(szName, currentValue.c_str());
+ break;
+ }
}
}
}
void CConfigGroup::LoadFromXML(XmlNodeRef node)
{
- // save only values that don't have default values
- for (TConfigVariables::const_iterator it = m_vars.begin();
- it != m_vars.end(); ++it)
+ // load values that are save-able
+ for (IConfigVar* var : m_vars)
{
- IConfigVar* var = (*it);
- if (!var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
+ if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
{
- const char* szName = var->GetName().c_str();
+ continue;
+ }
+ const char* szName = var->GetName().c_str();
- switch (var->GetType())
+ switch (var->GetType())
+ {
+ case IConfigVar::eType_BOOL:
+ {
+ bool currentValue = false;
+ var->GetDefault(¤tValue);
+ if (node->getAttr(szName, currentValue))
{
- case IConfigVar::eType_BOOL:
- {
- bool currentValue = false;
- var->GetDefault(¤tValue);
- if (node->getAttr(szName, currentValue))
- {
- var->Set(¤tValue);
- }
- break;
+ var->Set(¤tValue);
}
+ break;
+ }
- case IConfigVar::eType_INT:
+ case IConfigVar::eType_INT:
+ {
+ int currentValue = 0;
+ var->GetDefault(¤tValue);
+ if (node->getAttr(szName, currentValue))
{
- int currentValue = 0;
- var->GetDefault(¤tValue);
- if (node->getAttr(szName, currentValue))
- {
- var->Set(¤tValue);
- }
- break;
+ var->Set(¤tValue);
}
+ break;
+ }
- case IConfigVar::eType_FLOAT:
+ case IConfigVar::eType_FLOAT:
+ {
+ float currentValue = 0;
+ var->GetDefault(¤tValue);
+ if (node->getAttr(szName, currentValue))
{
- float currentValue = 0;
- var->GetDefault(¤tValue);
- if (node->getAttr(szName, currentValue))
- {
- var->Set(¤tValue);
- }
- break;
+ var->Set(¤tValue);
}
+ break;
+ }
- case IConfigVar::eType_STRING:
+ case IConfigVar::eType_STRING:
+ {
+ AZStd::string currentValue;
+ var->GetDefault(¤tValue);
+ QString readValue(currentValue.c_str());
+ if (node->getAttr(szName, readValue))
{
- AZStd::string currentValue;
- var->GetDefault(¤tValue);
- QString readValue(currentValue.c_str());
- if (node->getAttr(szName, readValue))
- {
- currentValue = readValue.toUtf8().data();
- var->Set(¤tValue);
- }
- break;
- }
+ currentValue = readValue.toUtf8().data();
+ var->Set(¤tValue);
}
+ break;
+ }
}
}
}
diff --git a/Code/Editor/ConfigGroup.h b/Code/Editor/ConfigGroup.h
index 769a29ba8a..004725e32c 100644
--- a/Code/Editor/ConfigGroup.h
+++ b/Code/Editor/ConfigGroup.h
@@ -8,8 +8,12 @@
#pragma once
-#ifndef CRYINCLUDE_EDITOR_CONFIGGROUP_H
-#define CRYINCLUDE_EDITOR_CONFIGGROUP_H
+#include
+#include
+#include
+
+struct ICVar;
+class XmlNodeRef;
namespace Config
{
@@ -32,7 +36,7 @@ namespace Config
eFlag_DoNotSave = 1 << 2,
};
- IConfigVar(const char* szName, const char* szDescription, EType varType, uint8 flags)
+ IConfigVar(const char* szName, const char* szDescription, EType varType, AZ::u8 flags)
: m_name(szName)
, m_description(szDescription)
, m_type(varType)
@@ -42,22 +46,22 @@ namespace Config
virtual ~IConfigVar() = default;
- ILINE EType GetType() const
+ AZ_FORCE_INLINE EType GetType() const
{
return m_type;
}
- ILINE const AZStd::string& GetName() const
+ AZ_FORCE_INLINE const AZStd::string& GetName() const
{
return m_name;
}
- ILINE const AZStd::string& GetDescription() const
+ AZ_FORCE_INLINE const AZStd::string& GetDescription() const
{
return m_description;
}
- ILINE bool IsFlagSet(EFlags flag) const
+ AZ_FORCE_INLINE bool IsFlagSet(EFlags flag) const
{
return 0 != (m_flags & flag);
}
@@ -68,73 +72,28 @@ namespace Config
virtual void GetDefault(void* outPtr) const = 0;
virtual void Reset() = 0;
- static EType TranslateType(const bool&) { return eType_BOOL; }
- static EType TranslateType(const int&) { return eType_INT; }
- static EType TranslateType(const float&) { return eType_FLOAT; }
- static EType TranslateType(const AZStd::string&) { return eType_STRING; }
+ static constexpr EType TranslateType(const bool&) { return eType_BOOL; }
+ static constexpr EType TranslateType(const int&) { return eType_INT; }
+ static constexpr EType TranslateType(const float&) { return eType_FLOAT; }
+ static constexpr EType TranslateType(const AZStd::string&) { return eType_STRING; }
protected:
EType m_type;
- uint8 m_flags;
+ AZ::u8 m_flags;
AZStd::string m_name;
AZStd::string m_description;
void* m_ptr;
ICVar* m_pCVar;
};
- // Typed wrapper for config variable
- template
- class TConfigVar
- : public IConfigVar
- {
- private:
- T m_default;
-
- public:
- TConfigVar(const char* szName, const char* szDescription, uint8 flags, T& ptr, const T& defaultValue)
- : IConfigVar(szName, szDescription, IConfigVar::TranslateType(ptr), flags)
- , m_default(defaultValue)
- {
- m_ptr = &ptr;
-
- // reset to default value on initializations
- ptr = defaultValue;
- }
-
- virtual void Get(void* outPtr) const
- {
- *reinterpret_cast(outPtr) = *reinterpret_cast(m_ptr);
- }
-
- virtual void Set(const void* ptr)
- {
- *reinterpret_cast(m_ptr) = *reinterpret_cast(ptr);
- }
-
- virtual void Reset()
- {
- *reinterpret_cast(m_ptr) = m_default;
- }
-
- virtual void GetDefault(void* outPtr) const
- {
- *reinterpret_cast(outPtr) = m_default;
- }
-
- virtual bool IsDefault() const
- {
- return *reinterpret_cast(m_ptr) == m_default;
- }
- };
-
// Group of configuration variables with optional mapping to CVars
class CConfigGroup
{
private:
- typedef std::vector TConfigVariables;
+ using TConfigVariables = AZStd::vector ;
TConfigVariables m_vars;
- typedef std::vector TConsoleVariables;
+ using TConsoleVariables = AZStd::vector;
TConsoleVariables m_consoleVars;
public:
@@ -142,20 +101,13 @@ namespace Config
virtual ~CConfigGroup();
void AddVar(IConfigVar* var);
- uint32 GetVarCount();
+ AZ::u32 GetVarCount();
IConfigVar* GetVar(const char* szName);
- IConfigVar* GetVar(uint index);
+ IConfigVar* GetVar(AZ::u32 index);
const IConfigVar* GetVar(const char* szName) const;
- const IConfigVar* GetVar(uint index) const;
+ const IConfigVar* GetVar(AZ::u32 index) const;
void SaveToXML(XmlNodeRef node);
void LoadFromXML(XmlNodeRef node);
-
- template
- void AddVar(const char* szName, const char* szDescription, T& var, const T& defaultValue, uint8 flags = 0)
- {
- AddVar(new TConfigVar(szName, szDescription, flags, var, defaultValue));
- }
};
};
-#endif // CRYINCLUDE_EDITOR_CONFIGGROUP_H
diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyMiscCtrl.h b/Code/Editor/Controls/ReflectedPropertyControl/PropertyMiscCtrl.h
index 5ec24b679d..849e44cedd 100644
--- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyMiscCtrl.h
+++ b/Code/Editor/Controls/ReflectedPropertyControl/PropertyMiscCtrl.h
@@ -6,8 +6,6 @@
*
*/
-#ifndef CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
-#define CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
#pragma once
#if !defined(Q_MOC_RUN)
@@ -53,6 +51,7 @@ private:
class UserPopupWidgetHandler : public QObject, public AzToolsFramework::PropertyHandler < CReflectedVarUser, UserPropertyEditor>
{
+ Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(UserPopupWidgetHandler, AZ::SystemAllocator, 0);
bool IsDefaultHandler() const override { return false; }
@@ -67,6 +66,7 @@ public:
class FloatCurveHandler : public QObject, public AzToolsFramework::PropertyHandler < CReflectedVarSpline, CSplineCtrl>
{
+ Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(FloatCurveHandler, AZ::SystemAllocator, 0);
bool IsDefaultHandler() const override { return false; }
@@ -80,5 +80,3 @@ public:
void OnSplineChange(CSplineCtrl*);
};
-
-#endif // CRYINCLUDE_EDITOR_UTILS_PROPERTYMISCCTRL_H
diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp b/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp
index c5ccc599d6..d26e978ae8 100644
--- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp
+++ b/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp
@@ -58,17 +58,9 @@ private:
void OnClicked() override
{
QString tempValue("");
- QString ext("");
- if (m_path.isEmpty() == false)
+ if (!m_path.isEmpty() && !Path::GetExt(m_path).isEmpty())
{
- if (Path::GetExt(m_path) == "")
- {
- tempValue = "";
- }
- else
- {
- tempValue = m_path;
- }
+ tempValue = m_path;
}
AssetSelectionModel selection;
diff --git a/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.h b/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.h
index fa30eba034..087ee9f1db 100644
--- a/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.h
+++ b/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.h
@@ -99,6 +99,7 @@ class FileResourceSelectorWidgetHandler
: QObject
, public AzToolsFramework::PropertyHandler < CReflectedVarResource, FileResourceSelectorWidget >
{
+ Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(FileResourceSelectorWidgetHandler, AZ::SystemAllocator, 0);
diff --git a/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp b/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp
index 1151137bfc..c5bf6a4d81 100644
--- a/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp
+++ b/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp
@@ -671,7 +671,7 @@ AzToolsFramework::PropertyRowWidget* ReflectedPropertyControl::FindPropertyRowWi
return nullptr;
}
const AzToolsFramework::ReflectedPropertyEditor::WidgetList& widgets = m_editor->GetWidgets();
- for (auto instance : widgets)
+ for (const auto& instance : widgets)
{
if (instance.second->label() == item->GetPropertyName())
{
diff --git a/Code/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp b/Code/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp
index b3f1b35461..2320938f08 100644
--- a/Code/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp
+++ b/Code/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp
@@ -446,41 +446,54 @@ void ReflectedVarUserAdapter::SetVariable(IVariable *pVariable)
m_reflectedVar.reset(new CReflectedVarUser( pVariable->GetHumanName().toUtf8().data()));
}
-void ReflectedVarUserAdapter::SyncReflectedVarToIVar(IVariable *pVariable)
+void ReflectedVarUserAdapter::SyncReflectedVarToIVar(IVariable* pVariable)
{
QString value;
pVariable->Get(value);
m_reflectedVar->m_value = value.toUtf8().data();
- //extract the list of custom items from the IVariable user data
- IVariable::IGetCustomItems* pGetCustomItems = static_cast (pVariable->GetUserData().value());
- if (pGetCustomItems != nullptr)
- {
- std::vector items;
- QString dlgTitle;
- // call the user supplied callback to fill-in items and get dialog title
- bool bShowIt = pGetCustomItems->GetItems(pVariable, items, dlgTitle);
- if (bShowIt) // if func didn't veto, show the dialog
- {
- m_reflectedVar->m_enableEdit = true;
- m_reflectedVar->m_useTree = pGetCustomItems->UseTree();
- m_reflectedVar->m_treeSeparator = pGetCustomItems->GetTreeSeparator();
- m_reflectedVar->m_dialogTitle = dlgTitle.toUtf8().data();
- m_reflectedVar->m_itemNames.resize(items.size());
- m_reflectedVar->m_itemDescriptions.resize(items.size());
-
- QByteArray ba;
- int i = -1;
- std::generate(m_reflectedVar->m_itemNames.begin(), m_reflectedVar->m_itemNames.end(), [&items, &i, &ba]() { ++i; ba = items[i].name.toUtf8(); return ba.data(); });
- i = -1;
- std::generate(m_reflectedVar->m_itemDescriptions.begin(), m_reflectedVar->m_itemDescriptions.end(), [&items, &i, &ba]() { ++i; ba = items[i].desc.toUtf8(); return ba.data(); });
-
- }
- }
- else
+ // extract the list of custom items from the IVariable user data
+ IVariable::IGetCustomItems* pGetCustomItems = static_cast(pVariable->GetUserData().value());
+ if (pGetCustomItems == nullptr)
{
m_reflectedVar->m_enableEdit = false;
+ return;
}
+
+ std::vector items;
+ QString dlgTitle;
+ // call the user supplied callback to fill-in items and get dialog title
+ bool bShowIt = pGetCustomItems->GetItems(pVariable, items, dlgTitle);
+ if (!bShowIt) // if func vetoed it, don't show the dialog
+ {
+ return;
+ }
+ m_reflectedVar->m_enableEdit = true;
+ m_reflectedVar->m_useTree = pGetCustomItems->UseTree();
+ m_reflectedVar->m_treeSeparator = pGetCustomItems->GetTreeSeparator();
+ m_reflectedVar->m_dialogTitle = dlgTitle.toUtf8().data();
+ m_reflectedVar->m_itemNames.resize(items.size());
+ m_reflectedVar->m_itemDescriptions.resize(items.size());
+
+ QByteArray ba;
+ int i = -1;
+ AZStd::generate(
+ m_reflectedVar->m_itemNames.begin(), m_reflectedVar->m_itemNames.end(),
+ [&items, &i, &ba]()
+ {
+ ++i;
+ ba = items[i].name.toUtf8();
+ return ba.data();
+ });
+ i = -1;
+ AZStd::generate(
+ m_reflectedVar->m_itemDescriptions.begin(), m_reflectedVar->m_itemDescriptions.end(),
+ [&items, &i, &ba]()
+ {
+ ++i;
+ ba = items[i].desc.toUtf8();
+ return ba.data();
+ });
}
void ReflectedVarUserAdapter::SyncIVarToReflectedVar(IVariable *pVariable)
diff --git a/Code/Editor/Controls/SplineCtrlEx.cpp b/Code/Editor/Controls/SplineCtrlEx.cpp
index 1dc2ff19e1..bff75af169 100644
--- a/Code/Editor/Controls/SplineCtrlEx.cpp
+++ b/Code/Editor/Controls/SplineCtrlEx.cpp
@@ -82,7 +82,6 @@ protected:
}
int GetSize() override { return sizeof(*this); }
- QString GetDescription() override { return "UndoSplineCtrlEx"; };
void Undo(bool bUndo) override
{
diff --git a/Code/Editor/Controls/TimelineCtrl.cpp b/Code/Editor/Controls/TimelineCtrl.cpp
index aa30c326ac..3890b46b2b 100644
--- a/Code/Editor/Controls/TimelineCtrl.cpp
+++ b/Code/Editor/Controls/TimelineCtrl.cpp
@@ -126,7 +126,6 @@ void TimelineWidget::DrawTicks(QPainter* painter)
const QPen pOldPen = painter->pen();
const QPen ltgray(QColor(110, 110, 110));
- const QPen black(palette().color(QPalette::Normal, QPalette::Text));
const QPen redpen(QColor(255, 0, 255));
// Draw time ticks every tick step seconds.
@@ -598,7 +597,6 @@ void TimelineWidget::DrawSecondTicks(QPainter* painter)
{
const QPen ltgray(QColor(110, 110, 110));
const QPen black(palette().color(QPalette::Normal, QPalette::Text));
- const QPen redpen(QColor(255, 0, 255));
for (int gx = m_grid.firstGridLine.x(); gx < m_grid.firstGridLine.x() + m_grid.numGridLines.x() + 1; gx++)
{
diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp
index dffe222f42..3890a9e59a 100644
--- a/Code/Editor/CryEdit.cpp
+++ b/Code/Editor/CryEdit.cpp
@@ -33,6 +33,7 @@ AZ_POP_DISABLE_WARNING
#include
#include
#include
+#include
#include
// Aws Native SDK
@@ -80,7 +81,6 @@ AZ_POP_DISABLE_WARNING
#include
// CryCommon
-#include
#include
// Editor
@@ -546,7 +546,6 @@ public:
{ "BatchMode", m_bConsoleMode },
{ "NullRenderer", m_bNullRenderer },
{ "devmode", m_bDeveloperMode },
- { "VTUNE", dummy },
{ "runpython", m_bRunPythonScript },
{ "runpythontest", m_bRunPythonTestScript },
{ "version", m_bShowVersionInfo },
@@ -2811,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)
{
@@ -3818,7 +3814,8 @@ void CCryEditApp::OnOpenQuickAccessBar()
}
QRect geo = m_pQuickAccessBar->geometry();
- geo.moveCenter(MainWindow::instance()->geometry().center());
+ auto mainWindow = MainWindow::instance();
+ geo.moveCenter(mainWindow->mapToGlobal(mainWindow->geometry().center()));
m_pQuickAccessBar->setGeometry(geo);
m_pQuickAccessBar->setVisible(true);
m_pQuickAccessBar->setFocus();
@@ -3830,7 +3827,7 @@ void CCryEditApp::SetEditorWindowTitle(QString sTitleStr, QString sPreTitleStr,
{
if (sTitleStr.isEmpty())
{
- sTitleStr = QObject::tr("O3DE Editor [Stable 21.11]");
+ sTitleStr = QObject::tr("O3DE Editor [Developer Preview]");
}
if (!sPreTitleStr.isEmpty())
@@ -4017,7 +4014,7 @@ void CCryEditApp::OnError(AzFramework::AssetSystem::AssetSystemErrors error)
break;
}
- CryMessageBox(errorMessage.c_str(), "Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
+ QMessageBox::critical(nullptr,"Error",errorMessage.c_str());
}
void CCryEditApp::OnOpenProceduralMaterialEditor()
@@ -4132,7 +4129,15 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware);
Editor::EditorQtApplication* app = Editor::EditorQtApplication::newInstance(argc, argv);
- if (app->arguments().contains("-autotest_mode"))
+ QStringList qArgs = app->arguments();
+ const bool is_automated_test = AZStd::any_of(qArgs.begin(), qArgs.end(),
+ [](const QString& elem)
+ {
+ return elem.endsWith("autotest_mode") || elem.endsWith("runpythontest");
+ }
+ );
+
+ if (is_automated_test)
{
// Nullroute all stdout to null for automated tests, this way we make sure
// that the test result output is not polluted with unrelated output data.
diff --git a/Code/Editor/CryEdit.h b/Code/Editor/CryEdit.h
index dd597dcc55..8c514170ae 100644
--- a/Code/Editor/CryEdit.h
+++ b/Code/Editor/CryEdit.h
@@ -432,6 +432,7 @@ public:
class CCrySingleDocTemplate
: public QObject
{
+ Q_OBJECT
private:
explicit CCrySingleDocTemplate(const QMetaObject* pDocClass)
: QObject()
diff --git a/Code/Editor/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp
index 4944c3bff5..3bcba4d5e0 100644
--- a/Code/Editor/CryEditDoc.cpp
+++ b/Code/Editor/CryEditDoc.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
@@ -50,7 +51,6 @@
#include "GameExporter.h"
#include "MainWindow.h"
#include "LevelFileDialog.h"
-#include "StatObjBus.h"
#include "Undo/Undo.h"
#include
@@ -60,15 +60,6 @@
#include
#include // for LmbrCentral::EditorLightComponentRequestBus
-//#define PROFILE_LOADING_WITH_VTUNE
-
-// profilers api.
-//#include "pure.h"
-#ifdef PROFILE_LOADING_WITH_VTUNE
-#include "C:\Program Files\Intel\Vtune\Analyzer\Include\VTuneApi.h"
-#pragma comment(lib,"C:\\Program Files\\Intel\\Vtune\\Analyzer\\Lib\\VTuneApi.lib")
-#endif
-
static const char* kAutoBackupFolder = "_autobackup";
static const char* kHoldFolder = "$tmp_hold"; // conform to the ignored file types $tmp[0-9]*_ regex
static const char* kSaveBackupFolder = "_savebackup";
@@ -254,9 +245,6 @@ void CCryEditDoc::DeleteContents()
EBUS_EVENT(AzToolsFramework::EditorEntityContextRequestBus, ResetEditorContext);
- // [LY-90904] move this to the EditorVegetationManager component
- InstanceStatObjEventBus::Broadcast(&InstanceStatObjEventBus::Events::ReleaseData);
-
//////////////////////////////////////////////////////////////////////////
// Clear all undo info.
//////////////////////////////////////////////////////////////////////////
@@ -316,8 +304,6 @@ void CCryEditDoc::Save(TDocMultiArchive& arrXmlAr)
// Fog settings ///////////////////////////////////////////////////////
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
-
- SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
}
}
AfterSave();
@@ -408,9 +394,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
int t0 = GetTickCount();
-#ifdef PROFILE_LOADING_WITH_VTUNE
- VTResume();
-#endif
// Load level-specific audio data.
AZStd::string levelFileName{ fileName.toUtf8().constData() };
AZStd::to_lower(levelFileName.begin(), levelFileName.end());
@@ -466,12 +449,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
}
}
- if (!isPrefabEnabled)
- {
- // Name Selection groups
- SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
- }
-
{
CAutoLogTime logtime("Post Load");
@@ -484,10 +461,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
CSurfaceTypeValidator().Validate();
-#ifdef PROFILE_LOADING_WITH_VTUNE
- VTPause();
-#endif
-
LogLoadTime(GetTickCount() - t0);
// Loaded with success, remove event from log file
GetIEditor()->GetSettingsManager()->UnregisterEvent(loadEvent);
@@ -610,16 +583,6 @@ void CCryEditDoc::SerializeFogSettings(CXmlArchive& xmlAr)
}
}
-void CCryEditDoc::SerializeNameSelection(CXmlArchive& xmlAr)
-{
- IObjectManager* pObjManager = GetIEditor()->GetObjectManager();
-
- if (pObjManager)
- {
- pObjManager->SerializeNameSelection(xmlAr.root, xmlAr.bLoading);
- }
-}
-
void CCryEditDoc::SetModifiedModules(EModifiedModule eModifiedModule, bool boSet)
{
if (!boSet)
@@ -765,7 +728,9 @@ bool CCryEditDoc::OnOpenDocument(const QString& lpszPathName)
bool CCryEditDoc::BeforeOpenDocument(const QString& lpszPathName, TOpenDocContext& context)
{
- CTimeValue loading_start_time = gEnv->pTimer->GetAsyncTime();
+ const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
+ const double timeSec = AZ::TimeMsToSecondsDouble(timeMs);
+ const CTimeValue loading_start_time(timeSec);
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
@@ -806,7 +771,7 @@ bool CCryEditDoc::BeforeOpenDocument(const QString& lpszPathName, TOpenDocContex
bool CCryEditDoc::DoOpenDocument(TOpenDocContext& context)
{
- CTimeValue& loading_start_time = context.loading_start_time;
+ const CTimeValue& loading_start_time = context.loading_start_time;
bool isPrefabEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
@@ -876,7 +841,9 @@ bool CCryEditDoc::DoOpenDocument(TOpenDocContext& context)
StartStreamingLoad();
- CTimeValue loading_end_time = gEnv->pTimer->GetAsyncTime();
+ const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
+ const double timeSec = AZ::TimeMsToSecondsDouble(timeMs);
+ const CTimeValue loading_end_time(timeSec);
CLogFile::FormatLine("-----------------------------------------------------------");
CLogFile::FormatLine("Successfully opened document %s", context.absoluteLevelPath.toUtf8().data());
@@ -1139,7 +1106,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
const QString oldLevelPattern = QDir(oldLevelFolder).absoluteFilePath("*.*");
const QString oldLevelName = Path::GetFile(GetLevelPathName());
const QString oldLevelXml = Path::ReplaceExtension(oldLevelName, "xml");
- AZ::IO::ArchiveFileIterator findHandle = pIPak->FindFirst(oldLevelPattern.toUtf8().data(), AZ::IO::IArchive::eFileSearchType_AllowOnDiskAndInZips);
+ AZ::IO::ArchiveFileIterator findHandle = pIPak->FindFirst(oldLevelPattern.toUtf8().data(), AZ::IO::FileSearchLocation::Any);
if (findHandle)
{
do
diff --git a/Code/Editor/CryEditDoc.h b/Code/Editor/CryEditDoc.h
index e64bdb1308..f7e97d308e 100644
--- a/Code/Editor/CryEditDoc.h
+++ b/Code/Editor/CryEditDoc.h
@@ -24,7 +24,6 @@
#include
#endif
-class CClouds;
struct LightingSettings;
struct IVariable;
struct ICVar;
@@ -124,7 +123,6 @@ public: // Create from serialization only
const char* GetTemporaryLevelName() const;
void DeleteTemporaryLevel();
- CClouds* GetClouds() { return m_pClouds; }
void SetWaterColor(const QColor& col) { m_waterColor = col; }
QColor GetWaterColor() const { return m_waterColor; }
XmlNodeRef& GetFogTemplate() { return m_fogTemplate; }
@@ -163,7 +161,6 @@ protected:
bool LoadEntitiesFromSlice(const QString& sliceFile);
void SerializeFogSettings(CXmlArchive& xmlAr);
virtual void SerializeViewSettings(CXmlArchive& xmlAr);
- void SerializeNameSelection(CXmlArchive& xmlAr);
void LogLoadTime(int time) const;
struct TSaveDocContext
@@ -195,7 +192,6 @@ protected:
QColor m_waterColor = QColor(0, 0, 255);
XmlNodeRef m_fogTemplate;
XmlNodeRef m_environmentTemplate;
- CClouds* m_pClouds;
std::list m_listeners;
bool m_bDocumentReady = false;
ICVar* doc_validate_surface_types = nullptr;
diff --git a/Code/Editor/CustomResolutionDlg.h b/Code/Editor/CustomResolutionDlg.h
index 5dd9acaae8..e1b8035c65 100644
--- a/Code/Editor/CustomResolutionDlg.h
+++ b/Code/Editor/CustomResolutionDlg.h
@@ -12,8 +12,6 @@
// Notice : Refer to ViewportTitleDlg.cpp for a use case.
-#ifndef CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
-#define CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
#pragma once
#if !defined(Q_MOC_RUN)
@@ -28,6 +26,7 @@ namespace Ui
class CCustomResolutionDlg
: public QDialog
{
+ Q_OBJECT
public:
CCustomResolutionDlg(int w, int h, QWidget* pParent = nullptr);
~CCustomResolutionDlg();
@@ -42,5 +41,3 @@ protected:
QScopedPointer m_ui;
};
-
-#endif // CRYINCLUDE_EDITOR_CUSTOMRESOLUTIONDLG_H
diff --git a/Code/Editor/CustomizeKeyboardDialog.cpp b/Code/Editor/CustomizeKeyboardDialog.cpp
index ce09f8d878..280d6c5323 100644
--- a/Code/Editor/CustomizeKeyboardDialog.cpp
+++ b/Code/Editor/CustomizeKeyboardDialog.cpp
@@ -211,9 +211,9 @@ public:
void Reset(QAction& action)
{
- emit beginResetModel();
+ beginResetModel();
m_action = &action;
- emit endResetModel();
+ endResetModel();
}
private:
@@ -266,7 +266,7 @@ QStringList CustomizeKeyboardDialog::BuildModels(QWidget* parent)
categories.append(category);
QMenu* menu = menuAction->menu();
- m_menuActions[category] = GetAllActionsForMenu(menu, QStringLiteral(""));
+ m_menuActions[category] = GetAllActionsForMenu(menu, QString());
}
return categories;
diff --git a/Code/Editor/Dialogs/PythonScriptsDialog.cpp b/Code/Editor/Dialogs/PythonScriptsDialog.cpp
index 35047947ac..06b1acdbc8 100644
--- a/Code/Editor/Dialogs/PythonScriptsDialog.cpp
+++ b/Code/Editor/Dialogs/PythonScriptsDialog.cpp
@@ -40,10 +40,10 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
namespace
{
// File name extension for python files
- const QString s_kPythonFileNameSpec = "*.py";
+ const QString s_kPythonFileNameSpec("*.py");
// Tree root element name
- const QString s_kRootElementName = "Python Scripts";
+ const QString s_kRootElementName("Python Scripts");
}
//////////////////////////////////////////////////////////////////////////
diff --git a/Code/Editor/EditorDefs.h b/Code/Editor/EditorDefs.h
index 4115e8433a..97c03b2b45 100644
--- a/Code/Editor/EditorDefs.h
+++ b/Code/Editor/EditorDefs.h
@@ -105,7 +105,6 @@
#include
#include
#include
-#include
#include
#include
diff --git a/Code/Editor/EditorEnvironment.cpp b/Code/Editor/EditorEnvironment.cpp
index 463fec8d08..2d675275ec 100644
--- a/Code/Editor/EditorEnvironment.cpp
+++ b/Code/Editor/EditorEnvironment.cpp
@@ -17,7 +17,7 @@ void SetEditorEnvironment(SSystemGlobalEnvironment* pEnv)
void AttachEditorAZEnvironment(AZ::EnvironmentInstance azEnv)
{
- AZ::Environment::Attach(azEnv, true);
+ AZ::Environment::Attach(azEnv);
}
void DetachEditorAZEnvironment()
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/EditorPreferencesPageViewportManipulator.cpp b/Code/Editor/EditorPreferencesPageViewportManipulator.cpp
index ea00d6a7f0..32e0e5b573 100644
--- a/Code/Editor/EditorPreferencesPageViewportManipulator.cpp
+++ b/Code/Editor/EditorPreferencesPageViewportManipulator.cpp
@@ -10,6 +10,8 @@
#include "EditorPreferencesPageViewportManipulator.h"
+#include
+
// Editor
#include "EditorViewportSettings.h"
#include "Settings.h"
@@ -19,7 +21,17 @@ void CEditorPreferencesPage_ViewportManipulator::Reflect(AZ::SerializeContext& s
serialize.Class()
->Version(1)
->Field("LineBoundWidth", &Manipulators::m_manipulatorLineBoundWidth)
- ->Field("CircleBoundWidth", &Manipulators::m_manipulatorCircleBoundWidth);
+ ->Field("CircleBoundWidth", &Manipulators::m_manipulatorCircleBoundWidth)
+ ->Field("LinearManipulatorAxisLength", &Manipulators::m_linearManipulatorAxisLength)
+ ->Field("PlanarManipulatorAxisLength", &Manipulators::m_planarManipulatorAxisLength)
+ ->Field("SurfaceManipulatorRadius", &Manipulators::m_surfaceManipulatorRadius)
+ ->Field("SurfaceManipulatorOpacity", &Manipulators::m_surfaceManipulatorOpacity)
+ ->Field("LinearManipulatorConeLength", &Manipulators::m_linearManipulatorConeLength)
+ ->Field("LinearManipulatorConeRadius", &Manipulators::m_linearManipulatorConeRadius)
+ ->Field("ScaleManipulatorBoxHalfExtent", &Manipulators::m_scaleManipulatorBoxHalfExtent)
+ ->Field("RotationManipulatorRadius", &Manipulators::m_rotationManipulatorRadius)
+ ->Field("ManipulatorViewBaseScale", &Manipulators::m_manipulatorViewBaseScale)
+ ->Field("FlipManipulatorAxesTowardsView", &Manipulators::m_flipManipulatorAxesTowardsView);
serialize.Class()->Version(2)->Field(
"Manipulators", &CEditorPreferencesPage_ViewportManipulator::m_manipulators);
@@ -36,7 +48,55 @@ void CEditorPreferencesPage_ViewportManipulator::Reflect(AZ::SerializeContext& s
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_manipulatorCircleBoundWidth, "Circle Bound Width",
"Manipulator Circle Bound Width")
->Attribute(AZ::Edit::Attributes::Min, 0.001f)
- ->Attribute(AZ::Edit::Attributes::Max, 2.0f);
+ ->Attribute(AZ::Edit::Attributes::Max, 2.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorAxisLength, "Linear Manipulator Axis Length",
+ "Length of default Linear Manipulator (for Translation and Scale Manipulators)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.1f)
+ ->Attribute(AZ::Edit::Attributes::Max, 5.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_planarManipulatorAxisLength, "Planar Manipulator Axis Length",
+ "Length of default Planar Manipulator (for Translation Manipulators)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.1f)
+ ->Attribute(AZ::Edit::Attributes::Max, 5.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_surfaceManipulatorRadius, "Surface Manipulator Radius",
+ "Radius of default Surface Manipulator (for Translation Manipulators)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.05f)
+ ->Attribute(AZ::Edit::Attributes::Max, 1.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_surfaceManipulatorOpacity, "Surface Manipulator Opacity",
+ "Opacity of default Surface Manipulator (for Translation Manipulators)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.01f)
+ ->Attribute(AZ::Edit::Attributes::Max, 1.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorConeLength, "Linear Manipulator Cone Length",
+ "Length of cone for default Linear Manipulator (for Translation Manipulators)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.05f)
+ ->Attribute(AZ::Edit::Attributes::Max, 1.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorConeRadius, "Linear Manipulator Cone Radius",
+ "Radius of cone for default Linear Manipulator (for Translation Manipulators)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.05f)
+ ->Attribute(AZ::Edit::Attributes::Max, 0.5f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_scaleManipulatorBoxHalfExtent, "Scale Manipulator Box Half Extent",
+ "Half extent of box for default Scale Manipulator")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.05f)
+ ->Attribute(AZ::Edit::Attributes::Max, 1.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_rotationManipulatorRadius, "Rotation Manipulator Radius",
+ "Radius of default Angular Manipulators (for Rotation Manipulators)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.5f)
+ ->Attribute(AZ::Edit::Attributes::Max, 5.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_manipulatorViewBaseScale, "Manipulator View Base Scale",
+ "The base scale to apply to all Manipulator Views (default is 1.0)")
+ ->Attribute(AZ::Edit::Attributes::Min, 0.5f)
+ ->Attribute(AZ::Edit::Attributes::Max, 2.0f)
+ ->DataElement(
+ AZ::Edit::UIHandlers::CheckBox, &Manipulators::m_flipManipulatorAxesTowardsView, "Flip Manipulator Axes Towards View",
+ "Determines whether Planar and Linear Manipulators should switch to face the view (camera) in the Editor");
editContext
->Class("Manipulator Viewport Preferences", "Manipulator Viewport Preferences")
@@ -82,10 +142,32 @@ void CEditorPreferencesPage_ViewportManipulator::OnApply()
{
SandboxEditor::SetManipulatorLineBoundWidth(m_manipulators.m_manipulatorLineBoundWidth);
SandboxEditor::SetManipulatorCircleBoundWidth(m_manipulators.m_manipulatorCircleBoundWidth);
+
+ AzToolsFramework::SetLinearManipulatorAxisLength(m_manipulators.m_linearManipulatorAxisLength);
+ AzToolsFramework::SetPlanarManipulatorAxisLength(m_manipulators.m_planarManipulatorAxisLength);
+ AzToolsFramework::SetSurfaceManipulatorRadius(m_manipulators.m_surfaceManipulatorRadius);
+ AzToolsFramework::SetSurfaceManipulatorOpacity(m_manipulators.m_surfaceManipulatorOpacity);
+ AzToolsFramework::SetLinearManipulatorConeLength(m_manipulators.m_linearManipulatorConeLength);
+ AzToolsFramework::SetLinearManipulatorConeRadius(m_manipulators.m_linearManipulatorConeRadius);
+ AzToolsFramework::SetScaleManipulatorBoxHalfExtent(m_manipulators.m_scaleManipulatorBoxHalfExtent);
+ AzToolsFramework::SetRotationManipulatorRadius(m_manipulators.m_rotationManipulatorRadius);
+ AzToolsFramework::SetFlipManipulatorAxesTowardsView(m_manipulators.m_flipManipulatorAxesTowardsView);
+ AzToolsFramework::SetManipulatorViewBaseScale(m_manipulators.m_manipulatorViewBaseScale);
}
void CEditorPreferencesPage_ViewportManipulator::InitializeSettings()
{
m_manipulators.m_manipulatorLineBoundWidth = SandboxEditor::ManipulatorLineBoundWidth();
m_manipulators.m_manipulatorCircleBoundWidth = SandboxEditor::ManipulatorCircleBoundWidth();
+
+ m_manipulators.m_linearManipulatorAxisLength = AzToolsFramework::LinearManipulatorAxisLength();
+ m_manipulators.m_planarManipulatorAxisLength = AzToolsFramework::PlanarManipulatorAxisLength();
+ m_manipulators.m_surfaceManipulatorRadius = AzToolsFramework::SurfaceManipulatorRadius();
+ m_manipulators.m_surfaceManipulatorOpacity = AzToolsFramework::SurfaceManipulatorOpacity();
+ m_manipulators.m_linearManipulatorConeLength = AzToolsFramework::LinearManipulatorConeLength();
+ m_manipulators.m_linearManipulatorConeRadius = AzToolsFramework::LinearManipulatorConeRadius();
+ m_manipulators.m_scaleManipulatorBoxHalfExtent = AzToolsFramework::ScaleManipulatorBoxHalfExtent();
+ m_manipulators.m_rotationManipulatorRadius = AzToolsFramework::RotationManipulatorRadius();
+ m_manipulators.m_flipManipulatorAxesTowardsView = AzToolsFramework::FlipManipulatorAxesTowardsView();
+ m_manipulators.m_manipulatorViewBaseScale = AzToolsFramework::ManipulatorViewBaseScale();
}
diff --git a/Code/Editor/EditorPreferencesPageViewportManipulator.h b/Code/Editor/EditorPreferencesPageViewportManipulator.h
index 93db6a7035..eb76cec2c5 100644
--- a/Code/Editor/EditorPreferencesPageViewportManipulator.h
+++ b/Code/Editor/EditorPreferencesPageViewportManipulator.h
@@ -41,6 +41,16 @@ private:
float m_manipulatorLineBoundWidth = 0.0f;
float m_manipulatorCircleBoundWidth = 0.0f;
+ float m_linearManipulatorAxisLength = 0.0f;
+ float m_planarManipulatorAxisLength = 0.0f;
+ float m_surfaceManipulatorRadius = 0.0f;
+ float m_surfaceManipulatorOpacity = 0.0f;
+ float m_linearManipulatorConeLength = 0.0f;
+ float m_linearManipulatorConeRadius = 0.0f;
+ float m_scaleManipulatorBoxHalfExtent = 0.0f;
+ float m_rotationManipulatorRadius = 0.0f;
+ float m_manipulatorViewBaseScale = 0.0f;
+ bool m_flipManipulatorAxesTowardsView = false;
};
Manipulators m_manipulators;
diff --git a/Code/Editor/EditorViewportSettings.cpp b/Code/Editor/EditorViewportSettings.cpp
index ae188c7d98..e06b9696e1 100644
--- a/Code/Editor/EditorViewportSettings.cpp
+++ b/Code/Editor/EditorViewportSettings.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
namespace SandboxEditor
{
@@ -57,31 +58,6 @@ namespace SandboxEditor
constexpr AZStd::string_view CameraDefaultStartingPositionY = "/Amazon/Preferences/Editor/Camera/DefaultStartingPosition/y";
constexpr AZStd::string_view CameraDefaultStartingPositionZ = "/Amazon/Preferences/Editor/Camera/DefaultStartingPosition/z";
- template
- void SetRegistry(const AZStd::string_view setting, T&& value)
- {
- if (auto* registry = AZ::SettingsRegistry::Get())
- {
- registry->Set(setting, AZStd::forward(value));
- }
- }
-
- template
- AZStd::remove_cvref_t GetRegistry(const AZStd::string_view setting, T&& defaultValue)
- {
- AZStd::remove_cvref_t value = AZStd::forward(defaultValue);
- if (const auto* registry = AZ::SettingsRegistry::Get())
- {
- T potentialValue;
- if (registry->Get(potentialValue, setting))
- {
- value = AZStd::move(potentialValue);
- }
- }
-
- return value;
- }
-
struct EditorViewportSettingsCallbacksImpl : public EditorViewportSettingsCallbacks
{
EditorViewportSettingsCallbacksImpl()
@@ -118,399 +94,409 @@ namespace SandboxEditor
AZ::Vector3 CameraDefaultEditorPosition()
{
return AZ::Vector3(
- aznumeric_cast(GetRegistry(CameraDefaultStartingPositionX, 0.0)),
- aznumeric_cast(GetRegistry(CameraDefaultStartingPositionY, -10.0)),
- aznumeric_cast(GetRegistry(CameraDefaultStartingPositionZ, 4.0)));
+ aznumeric_cast(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionX, 0.0)),
+ aznumeric_cast(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionY, -10.0)),
+ aznumeric_cast(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionZ, 4.0)));
}
void SetCameraDefaultEditorPosition(const AZ::Vector3& defaultCameraPosition)
{
- SetRegistry(CameraDefaultStartingPositionX, defaultCameraPosition.GetX());
- SetRegistry(CameraDefaultStartingPositionY, defaultCameraPosition.GetY());
- SetRegistry(CameraDefaultStartingPositionZ, defaultCameraPosition.GetZ());
+ AzToolsFramework::SetRegistry(CameraDefaultStartingPositionX, defaultCameraPosition.GetX());
+ AzToolsFramework::SetRegistry(CameraDefaultStartingPositionY, defaultCameraPosition.GetY());
+ AzToolsFramework::SetRegistry(CameraDefaultStartingPositionZ, defaultCameraPosition.GetZ());
}
AZ::u64 MaxItemsShownInAssetBrowserSearch()
{
- return GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast(50));
+ return AzToolsFramework::GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast(50));
}
void SetMaxItemsShownInAssetBrowserSearch(const AZ::u64 numberOfItemsShown)
{
- SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
+ AzToolsFramework::SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
}
bool GridSnappingEnabled()
{
- return GetRegistry(GridSnappingSetting, false);
+ return AzToolsFramework::GetRegistry(GridSnappingSetting, false);
}
void SetGridSnapping(const bool enabled)
{
- SetRegistry(GridSnappingSetting, enabled);
+ AzToolsFramework::SetRegistry(GridSnappingSetting, enabled);
}
float GridSnappingSize()
{
- return aznumeric_cast(GetRegistry(GridSizeSetting, 0.1));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(GridSizeSetting, 0.1));
}
void SetGridSnappingSize(const float size)
{
- SetRegistry(GridSizeSetting, size);
+ AzToolsFramework::SetRegistry(GridSizeSetting, size);
}
bool AngleSnappingEnabled()
{
- return GetRegistry(AngleSnappingSetting, false);
+ return AzToolsFramework::GetRegistry(AngleSnappingSetting, false);
}
void SetAngleSnapping(const bool enabled)
{
- SetRegistry(AngleSnappingSetting, enabled);
+ AzToolsFramework::SetRegistry(AngleSnappingSetting, enabled);
}
float AngleSnappingSize()
{
- return aznumeric_cast(GetRegistry(AngleSizeSetting, 5.0));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(AngleSizeSetting, 5.0));
}
void SetAngleSnappingSize(const float size)
{
- SetRegistry(AngleSizeSetting, size);
+ AzToolsFramework::SetRegistry(AngleSizeSetting, size);
}
bool ShowingGrid()
{
- return GetRegistry(ShowGridSetting, false);
+ return AzToolsFramework::GetRegistry(ShowGridSetting, false);
}
void SetShowingGrid(const bool showing)
{
- SetRegistry(ShowGridSetting, showing);
+ AzToolsFramework::SetRegistry(ShowGridSetting, showing);
}
bool StickySelectEnabled()
{
- return GetRegistry(StickySelectSetting, false);
+ return AzToolsFramework::GetRegistry(StickySelectSetting, false);
}
void SetStickySelectEnabled(const bool enabled)
{
- SetRegistry(StickySelectSetting, enabled);
+ AzToolsFramework::SetRegistry(StickySelectSetting, enabled);
}
float ManipulatorLineBoundWidth()
{
- return aznumeric_cast(GetRegistry(ManipulatorLineBoundWidthSetting, 0.1));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(ManipulatorLineBoundWidthSetting, 0.1));
}
void SetManipulatorLineBoundWidth(const float lineBoundWidth)
{
- SetRegistry(ManipulatorLineBoundWidthSetting, lineBoundWidth);
+ AzToolsFramework::SetRegistry(ManipulatorLineBoundWidthSetting, lineBoundWidth);
}
float ManipulatorCircleBoundWidth()
{
- return aznumeric_cast(GetRegistry(ManipulatorCircleBoundWidthSetting, 0.1));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(ManipulatorCircleBoundWidthSetting, 0.1));
}
void SetManipulatorCircleBoundWidth(const float circleBoundWidth)
{
- SetRegistry(ManipulatorCircleBoundWidthSetting, circleBoundWidth);
+ AzToolsFramework::SetRegistry(ManipulatorCircleBoundWidthSetting, circleBoundWidth);
}
float CameraTranslateSpeed()
{
- return aznumeric_cast(GetRegistry(CameraTranslateSpeedSetting, 10.0));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraTranslateSpeedSetting, 10.0));
}
void SetCameraTranslateSpeed(const float speed)
{
- SetRegistry(CameraTranslateSpeedSetting, speed);
+ AzToolsFramework::SetRegistry(CameraTranslateSpeedSetting, speed);
}
float CameraBoostMultiplier()
{
- return aznumeric_cast(GetRegistry(CameraBoostMultiplierSetting, 3.0));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraBoostMultiplierSetting, 3.0));
}
void SetCameraBoostMultiplier(const float multiplier)
{
- SetRegistry(CameraBoostMultiplierSetting, multiplier);
+ AzToolsFramework::SetRegistry(CameraBoostMultiplierSetting, multiplier);
}
float CameraRotateSpeed()
{
- return aznumeric_cast(GetRegistry(CameraRotateSpeedSetting, 0.005));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraRotateSpeedSetting, 0.005));
}
void SetCameraRotateSpeed(const float speed)
{
- SetRegistry(CameraRotateSpeedSetting, speed);
+ AzToolsFramework::SetRegistry(CameraRotateSpeedSetting, speed);
}
float CameraScrollSpeed()
{
- return aznumeric_cast(GetRegistry(CameraScrollSpeedSetting, 0.02));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraScrollSpeedSetting, 0.02));
}
void SetCameraScrollSpeed(const float speed)
{
- SetRegistry(CameraScrollSpeedSetting, speed);
+ AzToolsFramework::SetRegistry(CameraScrollSpeedSetting, speed);
}
float CameraDollyMotionSpeed()
{
- return aznumeric_cast(GetRegistry(CameraDollyMotionSpeedSetting, 0.01));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraDollyMotionSpeedSetting, 0.01));
}
void SetCameraDollyMotionSpeed(const float speed)
{
- SetRegistry(CameraDollyMotionSpeedSetting, speed);
+ AzToolsFramework::SetRegistry(CameraDollyMotionSpeedSetting, speed);
}
bool CameraOrbitYawRotationInverted()
{
- return GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
+ return AzToolsFramework::GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
}
void SetCameraOrbitYawRotationInverted(const bool inverted)
{
- SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
+ AzToolsFramework::SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
}
bool CameraPanInvertedX()
{
- return GetRegistry(CameraPanInvertedXSetting, true);
+ return AzToolsFramework::GetRegistry(CameraPanInvertedXSetting, true);
}
void SetCameraPanInvertedX(const bool inverted)
{
- SetRegistry(CameraPanInvertedXSetting, inverted);
+ AzToolsFramework::SetRegistry(CameraPanInvertedXSetting, inverted);
}
bool CameraPanInvertedY()
{
- return GetRegistry(CameraPanInvertedYSetting, true);
+ return AzToolsFramework::GetRegistry(CameraPanInvertedYSetting, true);
}
void SetCameraPanInvertedY(const bool inverted)
{
- SetRegistry(CameraPanInvertedYSetting, inverted);
+ AzToolsFramework::SetRegistry(CameraPanInvertedYSetting, inverted);
}
float CameraPanSpeed()
{
- return aznumeric_cast(GetRegistry(CameraPanSpeedSetting, 0.01));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraPanSpeedSetting, 0.01));
}
void SetCameraPanSpeed(float speed)
{
- SetRegistry(CameraPanSpeedSetting, speed);
+ AzToolsFramework::SetRegistry(CameraPanSpeedSetting, speed);
}
float CameraRotateSmoothness()
{
- return aznumeric_cast(GetRegistry(CameraRotateSmoothnessSetting, 5.0));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraRotateSmoothnessSetting, 5.0));
}
void SetCameraRotateSmoothness(const float smoothness)
{
- SetRegistry(CameraRotateSmoothnessSetting, smoothness);
+ AzToolsFramework::SetRegistry(CameraRotateSmoothnessSetting, smoothness);
}
float CameraTranslateSmoothness()
{
- return aznumeric_cast(GetRegistry(CameraTranslateSmoothnessSetting, 5.0));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraTranslateSmoothnessSetting, 5.0));
}
void SetCameraTranslateSmoothness(const float smoothness)
{
- SetRegistry(CameraTranslateSmoothnessSetting, smoothness);
+ AzToolsFramework::SetRegistry(CameraTranslateSmoothnessSetting, smoothness);
}
bool CameraRotateSmoothingEnabled()
{
- return GetRegistry(CameraRotateSmoothingSetting, true);
+ return AzToolsFramework::GetRegistry(CameraRotateSmoothingSetting, true);
}
void SetCameraRotateSmoothingEnabled(const bool enabled)
{
- SetRegistry(CameraRotateSmoothingSetting, enabled);
+ AzToolsFramework::SetRegistry(CameraRotateSmoothingSetting, enabled);
}
bool CameraTranslateSmoothingEnabled()
{
- return GetRegistry(CameraTranslateSmoothingSetting, true);
+ return AzToolsFramework::GetRegistry(CameraTranslateSmoothingSetting, true);
}
void SetCameraTranslateSmoothingEnabled(const bool enabled)
{
- SetRegistry(CameraTranslateSmoothingSetting, enabled);
+ AzToolsFramework::SetRegistry(CameraTranslateSmoothingSetting, enabled);
}
bool CameraCaptureCursorForLook()
{
- return GetRegistry(CameraCaptureCursorLookSetting, true);
+ return AzToolsFramework::GetRegistry(CameraCaptureCursorLookSetting, true);
}
void SetCameraCaptureCursorForLook(const bool capture)
{
- SetRegistry(CameraCaptureCursorLookSetting, capture);
+ AzToolsFramework::SetRegistry(CameraCaptureCursorLookSetting, capture);
}
float CameraDefaultOrbitDistance()
{
- return aznumeric_cast(GetRegistry(CameraDefaultOrbitDistanceSetting, 20.0));
+ return aznumeric_cast(AzToolsFramework::GetRegistry(CameraDefaultOrbitDistanceSetting, 20.0));
}
void SetCameraDefaultOrbitDistance(const float distance)
{
- SetRegistry(CameraDefaultOrbitDistanceSetting, distance);
+ AzToolsFramework::SetRegistry(CameraDefaultOrbitDistanceSetting, distance);
}
AzFramework::InputChannelId CameraTranslateForwardChannelId()
{
return AzFramework::InputChannelId(
- GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str());
+ AzToolsFramework::GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str());
}
void SetCameraTranslateForwardChannelId(AZStd::string_view cameraTranslateForwardId)
{
- SetRegistry(CameraTranslateForwardIdSetting, cameraTranslateForwardId);
+ AzToolsFramework::SetRegistry(CameraTranslateForwardIdSetting, cameraTranslateForwardId);
}
AzFramework::InputChannelId CameraTranslateBackwardChannelId()
{
return AzFramework::InputChannelId(
- GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str());
+ AzToolsFramework::GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str());
}
void SetCameraTranslateBackwardChannelId(AZStd::string_view cameraTranslateBackwardId)
{
- SetRegistry(CameraTranslateBackwardIdSetting, cameraTranslateBackwardId);
+ AzToolsFramework::SetRegistry(CameraTranslateBackwardIdSetting, cameraTranslateBackwardId);
}
AzFramework::InputChannelId CameraTranslateLeftChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str());
}
void SetCameraTranslateLeftChannelId(AZStd::string_view cameraTranslateLeftId)
{
- SetRegistry(CameraTranslateLeftIdSetting, cameraTranslateLeftId);
+ AzToolsFramework::SetRegistry(CameraTranslateLeftIdSetting, cameraTranslateLeftId);
}
AzFramework::InputChannelId CameraTranslateRightChannelId()
{
return AzFramework::InputChannelId(
- GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str());
+ AzToolsFramework::GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str());
}
void SetCameraTranslateRightChannelId(AZStd::string_view cameraTranslateRightId)
{
- SetRegistry(CameraTranslateRightIdSetting, cameraTranslateRightId);
+ AzToolsFramework::SetRegistry(CameraTranslateRightIdSetting, cameraTranslateRightId);
}
AzFramework::InputChannelId CameraTranslateUpChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str());
}
void SetCameraTranslateUpChannelId(AZStd::string_view cameraTranslateUpId)
{
- SetRegistry(CameraTranslateUpIdSetting, cameraTranslateUpId);
+ AzToolsFramework::SetRegistry(CameraTranslateUpIdSetting, cameraTranslateUpId);
}
AzFramework::InputChannelId CameraTranslateDownChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str());
}
void SetCameraTranslateDownChannelId(AZStd::string_view cameraTranslateDownId)
{
- SetRegistry(CameraTranslateDownIdSetting, cameraTranslateDownId);
+ AzToolsFramework::SetRegistry(CameraTranslateDownIdSetting, cameraTranslateDownId);
}
AzFramework::InputChannelId CameraTranslateBoostChannelId()
{
return AzFramework::InputChannelId(
- GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str());
+ AzToolsFramework::GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str());
}
void SetCameraTranslateBoostChannelId(AZStd::string_view cameraTranslateBoostId)
{
- SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
+ AzToolsFramework::SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
}
AzFramework::InputChannelId CameraOrbitChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
}
void SetCameraOrbitChannelId(AZStd::string_view cameraOrbitId)
{
- SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
+ AzToolsFramework::SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
}
AzFramework::InputChannelId CameraFreeLookChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraFreeLookIdSetting, AZStd::string("mouse_button_right")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraFreeLookIdSetting, AZStd::string("mouse_button_right")).c_str());
}
void SetCameraFreeLookChannelId(AZStd::string_view cameraFreeLookId)
{
- SetRegistry(CameraFreeLookIdSetting, cameraFreeLookId);
+ AzToolsFramework::SetRegistry(CameraFreeLookIdSetting, cameraFreeLookId);
}
AzFramework::InputChannelId CameraFreePanChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str());
}
void SetCameraFreePanChannelId(AZStd::string_view cameraFreePanId)
{
- SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
+ AzToolsFramework::SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
}
AzFramework::InputChannelId CameraOrbitLookChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
}
void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId)
{
- SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
+ AzToolsFramework::SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
}
AzFramework::InputChannelId CameraOrbitDollyChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
}
void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId)
{
- SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
+ AzToolsFramework::SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
}
AzFramework::InputChannelId CameraOrbitPanChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
}
void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId)
{
- SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
+ AzToolsFramework::SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
}
AzFramework::InputChannelId CameraFocusChannelId()
{
- return AzFramework::InputChannelId(GetRegistry(CameraFocusIdSetting, AZStd::string("keyboard_key_alphanumeric_X")).c_str());
+ return AzFramework::InputChannelId(
+ AzToolsFramework::GetRegistry(CameraFocusIdSetting, AZStd::string("keyboard_key_alphanumeric_X")).c_str());
}
void SetCameraFocusChannelId(AZStd::string_view cameraFocusId)
{
- SetRegistry(CameraFocusIdSetting, cameraFocusId);
+ AzToolsFramework::SetRegistry(CameraFocusIdSetting, cameraFocusId);
}
} // namespace SandboxEditor
diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp
index 8f94afd514..7323da9e95 100644
--- a/Code/Editor/EditorViewportWidget.cpp
+++ b/Code/Editor/EditorViewportWidget.cpp
@@ -53,7 +53,6 @@
#include
// CryCommon
-#include
#include
// AzFramework
@@ -98,9 +97,6 @@
#include
-#include
-#include
-
AZ_CVAR(
bool, ed_visibility_logTiming, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Output the timing of the new IVisibilitySystem query");
@@ -476,7 +472,7 @@ void EditorViewportWidget::Update()
{
auto start = std::chrono::steady_clock::now();
- m_entityVisibilityQuery.UpdateVisibility(GetCameraState());
+ m_entityVisibilityQuery.UpdateVisibility(m_renderViewport->GetCameraState());
if (ed_visibility_logTiming)
{
@@ -552,22 +548,6 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
// this should only occur for the main viewport and no others.
ShowCursor();
- // If the user has selected game mode, enable outputting to any attached HMD and properly size the context
- // to the resolution specified by the VR device.
- if (gSettings.bEnableGameModeVR)
- {
- const AZ::VR::HMDDeviceInfo* deviceInfo = nullptr;
- EBUS_EVENT_RESULT(deviceInfo, AZ::VR::HMDDeviceRequestBus, GetDeviceInfo);
- AZ_Warning("Render Viewport", deviceInfo, "No VR device detected");
-
- if (deviceInfo)
- {
- // Note: This may also need to adjust the viewport size
- SetActiveWindow();
- SetFocus();
- SetSelected(true);
- }
- }
SetCurrentCursor(STD_CURSOR_GAME);
if (ShouldPreviewFullscreen())
@@ -734,7 +714,7 @@ void EditorViewportWidget::RenderAll()
m_debugDisplay->DepthTestOff();
m_manipulatorManager->DrawManipulators(
- *m_debugDisplay, GetCameraState(),
+ *m_debugDisplay, m_renderViewport->GetCameraState(),
BuildMouseInteractionInternal(
AztfVi::MouseButtons(AztfVi::TranslateMouseButtons(QGuiApplication::mouseButtons())), keyboardModifiers,
BuildMousePick(WidgetToViewport(mapFromGlobal(QCursor::pos())))));
@@ -898,31 +878,11 @@ void EditorViewportWidget::OnMenuSelectCurrentCamera()
}
}
-AzFramework::CameraState EditorViewportWidget::GetCameraState()
-{
- return m_renderViewport->GetCameraState();
-}
-
-AZ::Vector3 EditorViewportWidget::PickTerrain(const AzFramework::ScreenPoint& point)
-{
- return LYVec3ToAZVec3(ViewToWorld(AzToolsFramework::ViewportInteraction::QPointFromScreenPoint(point), nullptr, true));
-}
-
-float EditorViewportWidget::TerrainHeight(const AZ::Vector2& position)
-{
- return GetIEditor()->GetTerrainElevation(position.GetX(), position.GetY());
-}
-
void EditorViewportWidget::FindVisibleEntities(AZStd::vector& visibleEntitiesOut)
{
visibleEntitiesOut.assign(m_entityVisibilityQuery.Begin(), m_entityVisibilityQuery.End());
}
-AzFramework::ScreenPoint EditorViewportWidget::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
-{
- return m_renderViewport->ViewportWorldToScreen(worldPosition);
-}
-
QWidget* EditorViewportWidget::GetWidgetForViewportContextMenu()
{
return this;
@@ -1759,13 +1719,6 @@ float EditorViewportWidget::GetScreenScaleFactor([[maybe_unused]] const Vec3& wo
AZ_Error("CryLegacy", false, "EditorViewportWidget::GetScreenScaleFactor not implemented");
return 1.f;
}
-//////////////////////////////////////////////////////////////////////////
-float EditorViewportWidget::GetScreenScaleFactor(const CCamera& camera, const Vec3& object_position)
-{
- Vec3 camPos = camera.GetPosition();
- float dist = camPos.GetDistance(object_position);
- return dist;
-}
//////////////////////////////////////////////////////////////////////////
bool EditorViewportWidget::CheckRespondToInput() const
@@ -1786,7 +1739,6 @@ bool EditorViewportWidget::CheckRespondToInput() const
//////////////////////////////////////////////////////////////////////////
bool EditorViewportWidget::HitTest(const QPoint& point, HitContext& hitInfo)
{
- hitInfo.camera = nullptr;
hitInfo.pExcludedObject = GetCameraObject();
return QtViewport::HitTest(point, hitInfo);
}
@@ -2160,7 +2112,7 @@ bool EditorViewportWidget::GetActiveCameraState(AzFramework::CameraState& camera
{
if (m_pPrimaryViewport == this)
{
- cameraState = GetCameraState();
+ cameraState = m_renderViewport->GetCameraState();
return true;
}
@@ -2491,12 +2443,6 @@ bool EditorViewportWidget::ShouldPreviewFullscreen() const
return false;
}
- // Not supported in VR
- if (gSettings.bEnableGameModeVR)
- {
- return false;
- }
-
// If level not loaded, don't preview in fullscreen (preview shouldn't work at all without a level, but it does)
if (auto ge = GetIEditor()->GetGameEngine())
{
diff --git a/Code/Editor/EditorViewportWidget.h b/Code/Editor/EditorViewportWidget.h
index 7d8daba8c5..3d52b2416d 100644
--- a/Code/Editor/EditorViewportWidget.h
+++ b/Code/Editor/EditorViewportWidget.h
@@ -10,7 +10,6 @@
#pragma once
#if !defined(Q_MOC_RUN)
-#include
#include
@@ -171,7 +170,6 @@ private:
void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const override;
Vec3 ViewToWorldNormal(const QPoint& vp, bool onlyTerrain, bool bTestRenderMesh = false) override;
float GetScreenScaleFactor(const Vec3& worldPoint) const override;
- float GetScreenScaleFactor(const CCamera& camera, const Vec3& object_position) override;
float GetAspectRatio() const override;
bool HitTest(const QPoint& point, HitContext& hitInfo) override;
bool IsBoundsVisible(const AABB& box) const override;
@@ -207,8 +205,6 @@ private:
void* GetSystemCursorConstraintWindow() const override;
// AzToolsFramework::MainEditorViewportInteractionRequestBus overrides ...
- AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) override;
- float TerrainHeight(const AZ::Vector2& position) override;
bool ShowingWorldSpace() override;
QWidget* GetWidgetForViewportContextMenu() override;
@@ -295,9 +291,6 @@ private:
// This switches the active camera to the next one in the list of (default, all custom cams).
void CycleCamera();
- AzFramework::CameraState GetCameraState();
- AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition);
-
QPoint WidgetToViewport(const QPoint& point) const;
QPoint ViewportToWidget(const QPoint& point) const;
QSize WidgetToViewport(const QSize& size) const;
diff --git a/Code/Editor/ErrorDialog.cpp b/Code/Editor/ErrorDialog.cpp
index 0a45b2bf89..e43df75947 100644
--- a/Code/Editor/ErrorDialog.cpp
+++ b/Code/Editor/ErrorDialog.cpp
@@ -25,9 +25,9 @@ namespace SandboxEditor
connect(m_ui->okButton, &QPushButton::clicked, this, &ErrorDialog::OnOK);
connect(
m_ui->messages,
- SIGNAL(itemSelectionChanged()),
+ &QTreeWidget::itemSelectionChanged,
this,
- SLOT(MessageSelectionChanged()));
+ &ErrorDialog::MessageSelectionChanged);
}
ErrorDialog::~ErrorDialog()
diff --git a/Code/Editor/Export/ExportManager.cpp b/Code/Editor/Export/ExportManager.cpp
index 5527aa6ce6..b27b7e0387 100644
--- a/Code/Editor/Export/ExportManager.cpp
+++ b/Code/Editor/Export/ExportManager.cpp
@@ -35,20 +35,8 @@
#include "Resource.h"
#include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h"
-#include
-#include
-
namespace
{
- inline Export::Vector3D Vec3ToVector3D(const Vec3& vec)
- {
- Export::Vector3D ret;
- ret.x = vec.x;
- ret.y = vec.y;
- ret.z = vec.z;
- return ret;
- }
-
const float kTangentDelta = 0.01f;
const float kAspectRatio = 1.777778f;
const int kReserveCount = 7; // x,y,z,rot_x,rot_y,rot_z,fov
@@ -106,22 +94,22 @@ void Export::CData::Clear()
// CExportManager
CExportManager::CExportManager()
: m_isPrecaching(false)
- , m_pBaseObj(nullptr)
- , m_FBXBakedExportFPS(0.0f)
, m_fScale(100.0f)
+ , m_bAnimationExport(false)
+ , m_pBaseObj(nullptr)
, // this scale is used by CryEngine RC
- m_bAnimationExport(false)
+ m_FBXBakedExportFPS(0.0f)
, m_bExportLocalCoords(false)
+ , m_bExportOnlyPrimaryCamera(false)
, m_numberOfExportFrames(0)
, m_pivotEntityObject(nullptr)
, m_bBakedKeysSequenceExport(true)
, m_animTimeExportPrimarySequenceCurrentTime(0.0f)
, m_animKeyTimeExport(true)
, m_soundKeyTimeExport(true)
- , m_bExportOnlyPrimaryCamera(false)
{
- RegisterExporter(new COBJExporter());
- RegisterExporter(new COCMExporter());
+ CExportManager::RegisterExporter(new COBJExporter());
+ CExportManager::RegisterExporter(new COCMExporter());
}
@@ -313,203 +301,6 @@ void CExportManager::AddEntityAnimationData(AZ::EntityId entityId)
ProcessEntityAnimationTrack(entityId, pObj, AnimParamType::Rotation);
}
-
-void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh, Matrix34A* pTm)
-{
- if (m_isPrecaching || !pObj)
- {
- return;
- }
-
- pObj->m_MeshHash = reinterpret_cast(pIndMesh);
- IIndexedMesh::SMeshDescription meshDesc;
- pIndMesh->GetMeshDescription(meshDesc);
-
- // if we have subset of meshes we need to duplicate vertices,
- // keep transformation of submesh,
- // and store new offset for indices
- int newOffsetIndex = pObj->GetVertexCount();
-
- if (meshDesc.m_nVertCount)
- {
- pObj->m_vertices.reserve(meshDesc.m_nVertCount + newOffsetIndex);
- pObj->m_normals.reserve(meshDesc.m_nVertCount + newOffsetIndex);
- }
-
- for (int v = 0; v < meshDesc.m_nVertCount; ++v)
- {
- Vec3 n = meshDesc.m_pNorms[v].GetN();
- Vec3 tmp = (meshDesc.m_pVerts ? meshDesc.m_pVerts[v] : meshDesc.m_pVertsF16[v].ToVec3());
- if (pTm)
- {
- tmp = pTm->TransformPoint(tmp);
- }
-
- pObj->m_vertices.push_back(Vec3ToVector3D(tmp * m_fScale));
- pObj->m_normals.push_back(Vec3ToVector3D(n));
- }
-
- if (meshDesc.m_nCoorCount)
- {
- pObj->m_texCoords.reserve(meshDesc.m_nCoorCount + newOffsetIndex);
- }
-
- for (int v = 0; v < meshDesc.m_nCoorCount; ++v)
- {
- Vec2 uv = meshDesc.m_pTexCoord[v].GetUV();
- uv.y = 1.0f - uv.y;
- pObj->m_texCoords.push_back({uv.x,uv.y});
- }
-
- if (pIndMesh->GetSubSetCount() && !(pIndMesh->GetSubSetCount() == 1 && pIndMesh->GetSubSet(0).nNumIndices == 0))
- {
- for (int i = 0; i < pIndMesh->GetSubSetCount(); ++i)
- {
- Export::CMesh* pMesh = new Export::CMesh();
-
- const SMeshSubset& sms = pIndMesh->GetSubSet(i);
- const vtx_idx* pIndices = &meshDesc.m_pIndices[sms.nFirstIndexId];
- int nTris = sms.nNumIndices / 3;
- pMesh->m_faces.reserve(nTris);
- for (int f = 0; f < nTris; ++f)
- {
- Export::Face face;
- face.idx[0] = *(pIndices++) + newOffsetIndex;
- face.idx[1] = *(pIndices++) + newOffsetIndex;
- face.idx[2] = *(pIndices++) + newOffsetIndex;
- pMesh->m_faces.push_back(face);
- }
-
- pObj->m_meshes.push_back(pMesh);
- }
- }
- else
- {
- Export::CMesh* pMesh = new Export::CMesh();
- if (meshDesc.m_nFaceCount == 0 && meshDesc.m_nIndexCount != 0 && meshDesc.m_pIndices != nullptr)
- {
- const vtx_idx* pIndices = &meshDesc.m_pIndices[0];
- int nTris = meshDesc.m_nIndexCount / 3;
- pMesh->m_faces.reserve(nTris);
- for (int f = 0; f < nTris; ++f)
- {
- Export::Face face;
- face.idx[0] = *(pIndices++) + newOffsetIndex;
- face.idx[1] = *(pIndices++) + newOffsetIndex;
- face.idx[2] = *(pIndices++) + newOffsetIndex;
- pMesh->m_faces.push_back(face);
- }
- }
- else
- {
- pMesh->m_faces.reserve(meshDesc.m_nFaceCount);
- for (int f = 0; f < meshDesc.m_nFaceCount; ++f)
- {
- Export::Face face;
- face.idx[0] = meshDesc.m_pFaces[f].v[0];
- face.idx[1] = meshDesc.m_pFaces[f].v[1];
- face.idx[2] = meshDesc.m_pFaces[f].v[2];
- pMesh->m_faces.push_back(face);
- }
- }
-
- pObj->m_meshes.push_back(pMesh);
- }
-}
-
-
-bool CExportManager::AddStatObj(Export::CObject* pObj, IStatObj* pStatObj, Matrix34A* pTm)
-{
- IIndexedMesh* pIndMesh = nullptr;
-
- if (pStatObj->GetSubObjectCount())
- {
- for (int i = 0; i < pStatObj->GetSubObjectCount(); i++)
- {
- IStatObj::SSubObject* pSubObj = pStatObj->GetSubObject(i);
- if (pSubObj && pSubObj->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj)
- {
- pIndMesh = nullptr;
- if (m_isOccluder)
- {
- if (pSubObj->pStatObj->GetLodObject(2))
- {
- pIndMesh = pSubObj->pStatObj->GetLodObject(2)->GetIndexedMesh(true);
- }
- if (!pIndMesh && pSubObj->pStatObj->GetLodObject(1))
- {
- pIndMesh = pSubObj->pStatObj->GetLodObject(1)->GetIndexedMesh(true);
- }
- }
- if (!pIndMesh)
- {
- pIndMesh = pSubObj->pStatObj->GetIndexedMesh(true);
- }
- if (pIndMesh)
- {
- AddMesh(pObj, pIndMesh, pTm);
- }
- }
- }
- }
-
- if (!pIndMesh)
- {
- if (m_isOccluder)
- {
- if (pStatObj->GetLodObject(2))
- {
- pIndMesh = pStatObj->GetLodObject(2)->GetIndexedMesh(true);
- }
- if (!pIndMesh && pStatObj->GetLodObject(1))
- {
- pIndMesh = pStatObj->GetLodObject(1)->GetIndexedMesh(true);
- }
- }
- if (!pIndMesh)
- {
- pIndMesh = pStatObj->GetIndexedMesh(true);
- }
- if (pIndMesh)
- {
- AddMesh(pObj, pIndMesh, pTm);
- }
- }
-
- return true;
-}
-
-bool CExportManager::AddMeshes(Export::CObject* pObj)
-{
- if (m_pBaseObj->GetType() == OBJTYPE_AZENTITY)
- {
- CEntityObject* pEntityObject = (CEntityObject*)m_pBaseObj;
- IRenderNode* pEngineNode = pEntityObject->GetEngineNode();
-
- if (pEngineNode)
- {
- if (!m_isPrecaching)
- {
- for (int i = 0; i < pEngineNode->GetSlotCount(); ++i)
- {
- Matrix34A tm;
- IStatObj* pStatObj = pEngineNode->GetEntityStatObj(i, 0, &tm);
- if (pStatObj)
- {
- Matrix34A objTM = m_pBaseObj->GetWorldTM();
- objTM.Invert();
- tm = objTM * tm;
- AddStatObj(pObj, pStatObj, &tm);
- }
- }
- }
- }
- }
-
- return true;
-}
-
-
bool CExportManager::AddObject(CBaseObject* pBaseObj)
{
if (m_isOccluder)
@@ -531,7 +322,6 @@ bool CExportManager::AddObject(CBaseObject* pBaseObj)
if (m_isPrecaching)
{
- AddMeshes(nullptr);
return true;
}
@@ -542,7 +332,6 @@ bool CExportManager::AddObject(CBaseObject* pBaseObj)
m_objectMap[pBaseObj] = int(m_data.m_objects.size() - 1);
- AddMeshes(pObj);
m_pBaseObj = nullptr;
return true;
@@ -1227,15 +1016,6 @@ bool CExportManager::ImportFromFile(const char* filename)
return bRet;
}
-bool CExportManager::ExportSingleStatObj(IStatObj* pStatObj, const char* filename)
-{
- Export::CObject* pObj = new Export::CObject(Path::GetFileName(filename).toUtf8().data());
- AddStatObj(pObj, pStatObj);
- m_data.m_objects.push_back(pObj);
- ExportToFile(filename, true);
- return true;
-}
-
void CExportManager::SaveNodeKeysTimeToXML()
{
CTrackViewSequence* pSequence = GetIEditor()->GetAnimation()->GetSequence();
diff --git a/Code/Editor/Export/ExportManager.h b/Code/Editor/Export/ExportManager.h
index 14318be957..6908bcf0f7 100644
--- a/Code/Editor/Export/ExportManager.h
+++ b/Code/Editor/Export/ExportManager.h
@@ -139,18 +139,11 @@ public:
bool ImportFromFile(const char* filename);
const Export::CData& GetData() const {return m_data; };
- //! Exports the stat obj to the obj file specified
- //! returns true if succeeded, otherwise false
- bool ExportSingleStatObj(IStatObj* pStatObj, const char* filename) override;
-
void SetBakedKeysSequenceExport(bool bBaked){m_bBakedKeysSequenceExport = bBaked; };
void SaveNodeKeysTimeToXML();
private:
- void AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh, Matrix34A* pTm = nullptr);
- bool AddStatObj(Export::CObject* pObj, IStatObj* pStatObj, Matrix34A* pTm = nullptr);
- bool AddMeshes(Export::CObject* pObj);
bool AddObject(CBaseObject* pBaseObj);
void SolveHierarchy();
diff --git a/Code/Editor/GameEngine.cpp b/Code/Editor/GameEngine.cpp
index 5f3545e593..e82832fc21 100644
--- a/Code/Editor/GameEngine.cpp
+++ b/Code/Editor/GameEngine.cpp
@@ -35,7 +35,6 @@
// CryCommon
#include
-#include
#include
// Editor
@@ -49,9 +48,6 @@
#include "Include/IObjectManager.h"
#include "ActionManager.h"
-// Including this too early will result in a linker error
-#include
-
// Implementation of System Callback structure.
struct SSystemUserCallback
: public ISystemUserCallback
@@ -160,20 +156,20 @@ struct SSystemUserCallback
}
}
- int ShowMessage(const char* text, const char* caption, unsigned int uType) override
+ void ShowMessage(const char* text, const char* caption, unsigned int uType) override
{
if (CCryEditApp::instance()->IsInAutotestMode())
{
- return IDOK;
+ return;
}
const UINT kMessageBoxButtonMask = 0x000f;
if (!GetIEditor()->IsInGameMode() && (uType == 0 || uType == MB_OK || !(uType & kMessageBoxButtonMask)))
{
static_cast(GetIEditor())->AddErrorMessage(text, caption);
- return IDOK;
+ return;
}
- return CryMessageBox(text, caption, uType);
+ CryMessageBox(text, caption, uType);
}
void OnSplashScreenDone()
@@ -242,8 +238,7 @@ private:
AZ_PUSH_DISABLE_WARNING(4273, "-Wunknown-warning-option")
CGameEngine::CGameEngine()
- : m_gameDll(nullptr)
- , m_bIgnoreUpdates(false)
+ : m_bIgnoreUpdates(false)
, m_ePendingGameMode(ePGM_NotPending)
, m_modalWindowDismisser(nullptr)
AZ_POP_DISABLE_WARNING
@@ -253,7 +248,7 @@ AZ_POP_DISABLE_WARNING
m_bInGameMode = false;
m_bSimulationMode = false;
m_bSyncPlayerPosition = true;
- m_hSystemHandle = nullptr;
+ m_hSystemHandle.reset(nullptr);
m_bJustCreated = false;
m_levelName = "Untitled";
m_levelExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
@@ -268,18 +263,10 @@ AZ_POP_DISABLE_WARNING
GetIEditor()->UnregisterNotifyListener(this);
m_pISystem->GetIMovieSystem()->SetCallback(nullptr);
- if (m_gameDll)
- {
- CryFreeLibrary(m_gameDll);
- }
-
delete m_pISystem;
m_pISystem = nullptr;
- if (m_hSystemHandle)
- {
- CryFreeLibrary(m_hSystemHandle);
- }
+ m_hSystemHandle.reset(nullptr);
delete m_pSystemUserCallback;
}
@@ -347,18 +334,19 @@ AZ::Outcome CGameEngine::Init(
HWND hwndForInputSystem)
{
m_pSystemUserCallback = new SSystemUserCallback(logo);
- m_hSystemHandle = CryLoadLibraryDefName("CrySystem");
- if (!m_hSystemHandle)
+ constexpr const char* crySystemLibraryName = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX "CrySystem" AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION;
+
+ m_hSystemHandle = AZ::DynamicModuleHandle::Create(crySystemLibraryName);
+ if (!m_hSystemHandle->Load(true))
{
- auto errorMessage = AZStd::string::format("%s Loading Failed", CryLibraryDefName("CrySystem"));
+ auto errorMessage = AZStd::string::format("%s Loading Failed", crySystemLibraryName);
Error(errorMessage.c_str());
return AZ::Failure(errorMessage);
}
PFNCREATESYSTEMINTERFACE pfnCreateSystemInterface =
- (PFNCREATESYSTEMINTERFACE)CryGetProcAddress(m_hSystemHandle, "CreateSystemInterface");
-
+ m_hSystemHandle->GetFunction("CreateSystemInterface");
SSystemInitParams sip;
@@ -606,13 +594,6 @@ void CGameEngine::SwitchToInEditor()
// Enable accelerators.
GetIEditor()->EnableAcceleratos(true);
-
- // reset UI system
- if (gEnv->pLyShine)
- {
- gEnv->pLyShine->Reset();
- }
-
// [Anton] - order changed, see comments for CGameEngine::SetSimulationMode
//! Send event to switch out of game.
GetIEditor()->GetObjectManager()->SendEvent(EVENT_OUTOFGAME);
@@ -833,7 +814,7 @@ void CGameEngine::Update()
if (gEnv->pSystem)
{
gEnv->pSystem->UpdatePreTickBus();
- componentApplication->Tick(gEnv->pTimer->GetFrameTime(ITimer::ETIMER_GAME));
+ componentApplication->Tick();
gEnv->pSystem->UpdatePostTickBus();
}
@@ -849,7 +830,7 @@ void CGameEngine::Update()
unsigned int updateFlags = ESYSUPDATE_EDITOR;
GetIEditor()->GetAnimation()->Update();
GetIEditor()->GetSystem()->UpdatePreTickBus(updateFlags);
- componentApplication->Tick(gEnv->pTimer->GetFrameTime(ITimer::ETIMER_GAME));
+ componentApplication->Tick();
GetIEditor()->GetSystem()->UpdatePostTickBus(updateFlags);
}
}
diff --git a/Code/Editor/GameEngine.h b/Code/Editor/GameEngine.h
index 4d183cc38e..5a77fc2fb1 100644
--- a/Code/Editor/GameEngine.h
+++ b/Code/Editor/GameEngine.h
@@ -8,17 +8,11 @@
// Description : The game engine for editor
-
-
-#ifndef CRYINCLUDE_EDITOR_GAMEENGINE_H
-#define CRYINCLUDE_EDITOR_GAMEENGINE_H
-
#pragma once
#if !defined(Q_MOC_RUN)
#include
#include "LogFile.h"
-#include "CryListenerSet.h"
#include "Util/ModalWindowDismisser.h"
#endif
@@ -28,6 +22,8 @@ struct IInitializeUIInfo;
#include
#include
+#include
+
class ThreadedOnErrorHandler : public QObject
{
Q_OBJECT
@@ -124,11 +120,6 @@ public:
return s_pakModifyMutex;
}
- inline HMODULE GetGameModule() const
- {
- return m_gameDll;
- }
-
private:
void SetGameMode(bool inGame);
void SwitchToInGame();
@@ -150,8 +141,7 @@ private:
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
Matrix34 m_playerViewTM;
struct SSystemUserCallback* m_pSystemUserCallback;
- HMODULE m_hSystemHandle;
- HMODULE m_gameDll;
+ AZStd::unique_ptr m_hSystemHandle;
enum EPendingGameMode
{
ePGM_NotPending,
@@ -163,5 +153,3 @@ private:
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
-
-#endif // CRYINCLUDE_EDITOR_GAMEENGINE_H
diff --git a/Code/Editor/GameExporter.cpp b/Code/Editor/GameExporter.cpp
index ae1095b03a..a768861b90 100644
--- a/Code/Editor/GameExporter.cpp
+++ b/Code/Editor/GameExporter.cpp
@@ -146,13 +146,11 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
exportSuccessful = false;
}
- if (exportSuccessful)
+ if (exportSuccessful && m_bAutoExportMode)
{
- if (m_bAutoExportMode)
- {
- // Remove read-only flags.
- CrySetFileAttributes(m_levelPak.m_sPath.toUtf8().data(), FILE_ATTRIBUTE_NORMAL);
- }
+ // Remove read-only flags.
+ auto perms = QFile::permissions(m_levelPak.m_sPath) | QFile::Permission::WriteOwner;
+ QFile::setPermissions(m_levelPak.m_sPath, perms);
}
//////////////////////////////////////////////////////////////////////////
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/IEditor.h b/Code/Editor/IEditor.h
index 7c49819d83..48c8392f32 100644
--- a/Code/Editor/IEditor.h
+++ b/Code/Editor/IEditor.h
@@ -508,8 +508,6 @@ struct IEditor
virtual CBaseObject* NewObject(const char* typeName, const char* fileName = "", const char* name = "", float x = 0.0f, float y = 0.0f, float z = 0.0f, bool modifyDoc = true) = 0;
//! Delete object
virtual void DeleteObject(CBaseObject* obj) = 0;
- //! Clone object
- virtual CBaseObject* CloneObject(CBaseObject* obj) = 0;
//! Get current selection group
virtual CSelectionGroup* GetSelection() = 0;
virtual CBaseObject* GetSelectedObject() = 0;
diff --git a/Code/Editor/IEditorImpl.cpp b/Code/Editor/IEditorImpl.cpp
index 66c64d5bef..e5df6be58e 100644
--- a/Code/Editor/IEditorImpl.cpp
+++ b/Code/Editor/IEditorImpl.cpp
@@ -397,11 +397,6 @@ void CEditorImpl::Update()
// Make sure this is not called recursively
m_bUpdates = false;
- //@FIXME: Restore this latter.
- //if (GetGameEngine() && GetGameEngine()->IsLevelLoaded())
- {
- m_pObjectManager->Update();
- }
if (IsInPreviewMode())
{
SetModifiedFlag(false);
@@ -687,13 +682,6 @@ void CEditorImpl::DeleteObject(CBaseObject* obj)
GetObjectManager()->DeleteObject(obj);
}
-CBaseObject* CEditorImpl::CloneObject(CBaseObject* obj)
-{
- SetModifiedFlag();
- GetIEditor()->SetModifiedModule(eModifiedBrushes);
- return GetObjectManager()->CloneObject(obj);
-}
-
CBaseObject* CEditorImpl::GetSelectedObject()
{
if (m_pObjectManager->GetSelection()->GetCount() != 1)
diff --git a/Code/Editor/IEditorImpl.h b/Code/Editor/IEditorImpl.h
index 26701edec2..4976c0c1ca 100644
--- a/Code/Editor/IEditorImpl.h
+++ b/Code/Editor/IEditorImpl.h
@@ -141,7 +141,6 @@ public:
const SGizmoParameters& GetGlobalGizmoParameters() override;
CBaseObject* NewObject(const char* typeName, const char* fileName = "", const char* name = "", float x = 0.0f, float y = 0.0f, float z = 0.0f, bool modifyDoc = true) override;
void DeleteObject(CBaseObject* obj) override;
- CBaseObject* CloneObject(CBaseObject* obj) override;
IObjectManager* GetObjectManager() override;
// This will return a null pointer if CrySystem is not loaded before
// Global Sandbox Settings are loaded from the registry before CrySystem
diff --git a/Code/Editor/IconManager.cpp b/Code/Editor/IconManager.cpp
index 820213bbd9..a9d31aef7b 100644
--- a/Code/Editor/IconManager.cpp
+++ b/Code/Editor/IconManager.cpp
@@ -21,8 +21,6 @@
#include "Util/Image.h"
#include "Util/ImageUtil.h"
-#include
-
#define HELPER_MATERIAL "Objects/Helper"
namespace
@@ -38,7 +36,6 @@ namespace
CIconManager::CIconManager()
{
ZeroStruct(m_icons);
- ZeroStruct(m_objects);
}
//////////////////////////////////////////////////////////////////////////
@@ -61,13 +58,7 @@ void CIconManager::Done()
void CIconManager::Reset()
{
// Do not unload objects. but clears them.
- int i;
- for (i = 0; i < sizeof(m_objects) / sizeof(m_objects[0]); i++)
- {
- delete m_objects[i];
- m_objects[i] = nullptr;
- }
- for (i = 0; i < eIcon_COUNT; i++)
+ for (int i = 0; i < eIcon_COUNT; i++)
{
m_icons[i] = 0;
}
@@ -110,12 +101,6 @@ int CIconManager::GetIconTexture(EIcon icon)
return m_icons[icon];
}
-//////////////////////////////////////////////////////////////////////////
-IStatObj* CIconManager::GetObject(EStatObject)
-{
- return nullptr;
-}
-
//////////////////////////////////////////////////////////////////////////
QImage* CIconManager::GetIconBitmap(const char* filename, bool& bHaveAlpha, uint32 effects /*=0*/)
{
diff --git a/Code/Editor/IconManager.h b/Code/Editor/IconManager.h
index 7183f036ed..7e9be63665 100644
--- a/Code/Editor/IconManager.h
+++ b/Code/Editor/IconManager.h
@@ -8,11 +8,6 @@
// Description : Manages Textures used by Icon.
-
-
-#ifndef CRYINCLUDE_EDITOR_ICONMANAGER_H
-#define CRYINCLUDE_EDITOR_ICONMANAGER_H
-
#pragma once
#include "Include/IIconManager.h" // for IIconManager
@@ -31,7 +26,7 @@ class CIconManager
public:
// Construction
CIconManager();
- ~CIconManager();
+ ~CIconManager() override;
void Init();
void Done();
@@ -41,8 +36,6 @@ public:
// Operations
virtual int GetIconTexture(EIcon icon);
-
- virtual IStatObj* GetObject(EStatObject object);
virtual int GetIconTexture(const char* iconName);
//////////////////////////////////////////////////////////////////////////
@@ -61,7 +54,6 @@ public:
private:
StdMap m_textures;
- IStatObj* m_objects[eStatObject_COUNT];
int m_icons[eIcon_COUNT];
//////////////////////////////////////////////////////////////////////////
@@ -70,5 +62,3 @@ private:
typedef std::map IconsMap;
IconsMap m_iconBitmapsMap;
};
-
-#endif // CRYINCLUDE_EDITOR_ICONMANAGER_H
diff --git a/Code/Editor/Include/HitContext.h b/Code/Editor/Include/HitContext.h
index 186124555f..ceff0adb22 100644
--- a/Code/Editor/Include/HitContext.h
+++ b/Code/Editor/Include/HitContext.h
@@ -19,7 +19,6 @@ class CBaseObject;
struct IDisplayViewport;
class CDeepSelection;
struct AABB;
-class CCamera;
#include
#include
@@ -68,8 +67,6 @@ struct HitContext
QRect rect;
//! Optional limiting bounding box for hit testing.
AABB* bounds;
- //! Optional camera for culling perspective viewports.
- CCamera* camera;
//! Testing performed in 2D viewport.
bool b2DViewport;
@@ -120,7 +117,6 @@ struct HitContext
rect = QRect();
b2DViewport = false;
view = 0;
- camera = 0;
point2d = QPoint();
axis = 0;
distanceTolerance = 0;
diff --git a/Code/Editor/Include/IDisplayViewport.h b/Code/Editor/Include/IDisplayViewport.h
index 637d19e39b..2dab2802c7 100644
--- a/Code/Editor/Include/IDisplayViewport.h
+++ b/Code/Editor/Include/IDisplayViewport.h
@@ -6,15 +6,11 @@
*
*/
-
-#ifndef CRYINCLUDE_EDITOR_INCLUDE_IDISPLAYVIEWPORT_H
-#define CRYINCLUDE_EDITOR_INCLUDE_IDISPLAYVIEWPORT_H
#pragma once
struct DisplayContext;
class CBaseObjectsCache;
class QPoint;
-class CCamera;
struct AABB;
class CViewport;
@@ -23,8 +19,6 @@ struct IDisplayViewport
{
virtual void Update() = 0;
virtual float GetScreenScaleFactor(const Vec3& position) const = 0;
- virtual float GetScreenScaleFactor(const CCamera& camera, const Vec3& object_position) = 0;
- virtual bool HitTestLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& hitpoint, int pixelRadius, float* pToCameraDistance = 0) const = 0;
/**
* Gets the distance of the point on screen to the line defined by the two points, converted to screenspace.
@@ -50,12 +44,9 @@ struct IDisplayViewport
virtual Vec3 WorldToView3D(const Vec3& worldPoint, int flags = 0) const = 0;
virtual Vec3 ViewToWorld(const QPoint& vp, bool* collideWithTerrain = nullptr, bool onlyTerrain = false, bool bSkipVegetation = false, bool bTestRenderMesh = false, bool* collideWithObject = nullptr) const = 0;
virtual void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const = 0;
- virtual float GetGridStep() const = 0;
virtual void setRay(QPoint& vp, Vec3& raySrc, Vec3& rayDir) = 0;
- virtual void setHitcontext(QPoint& vp, Vec3& raySrc, Vec3& rayDir) = 0;
virtual float GetAspectRatio() const = 0;
- virtual const ::Plane* GetConstructionPlane() const = 0;
virtual bool IsBoundsVisible(const AABB& box) const = 0;
@@ -64,5 +55,3 @@ struct IDisplayViewport
virtual CViewport *asCViewport() { return nullptr; }
};
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_IDISPLAYVIEWPORT_H
diff --git a/Code/Editor/Include/IExportManager.h b/Code/Editor/Include/IExportManager.h
index ea802134b6..ce79e52e15 100644
--- a/Code/Editor/Include/IExportManager.h
+++ b/Code/Editor/Include/IExportManager.h
@@ -8,14 +8,9 @@
// Description : Export geometry interfaces
-
-
-#ifndef CRYINCLUDE_EDITOR_INCLUDE_IEXPORTMANAGER_H
-#define CRYINCLUDE_EDITOR_INCLUDE_IEXPORTMANAGER_H
#pragma once
#define EXP_NAMESIZE 32
-struct IStatObj;
enum class AnimParamType;
namespace Export
@@ -178,18 +173,10 @@ struct IExporter
virtual void Release() = 0;
};
-
-
// IExportManager: interface to export manager
struct IExportManager
{
//! Register exporter
//! return true if succeed, otherwise false
virtual bool RegisterExporter(IExporter* pExporter) = 0;
-
- virtual bool ExportSingleStatObj(IStatObj* pStatObj, const char* filename) = 0;
};
-
-
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_IEXPORTMANAGER_H
diff --git a/Code/Editor/Include/IIconManager.h b/Code/Editor/Include/IIconManager.h
index 4925e47ae8..2407ea31bd 100644
--- a/Code/Editor/Include/IIconManager.h
+++ b/Code/Editor/Include/IIconManager.h
@@ -6,12 +6,8 @@
*
*/
-
-#ifndef CRYINCLUDE_EDITOR_INCLUDE_IICONMANAGER_H
-#define CRYINCLUDE_EDITOR_INCLUDE_IICONMANAGER_H
#pragma once
-struct IStatObj;
struct IMaterial;
class CBitmap;
@@ -56,12 +52,9 @@ enum EIconEffect
struct IIconManager
{
virtual ~IIconManager() = default;
- virtual IStatObj* GetObject(EStatObject object) = 0;
virtual int GetIconTexture(EIcon icon) = 0;
virtual int GetIconTexture(const char* iconName) = 0;
virtual QImage* GetIconBitmap(const char* filename, bool& haveAlpha, uint32 effects = 0) = 0;
// Register an Icon for the specific command
virtual void RegisterCommandIcon([[maybe_unused]] const char* filename, [[maybe_unused]] int nCommandId) {}
};
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_IICONMANAGER_H
diff --git a/Code/Editor/Include/IObjectManager.h b/Code/Editor/Include/IObjectManager.h
index 0a7bc8dcca..b612bcb80c 100644
--- a/Code/Editor/Include/IObjectManager.h
+++ b/Code/Editor/Include/IObjectManager.h
@@ -5,10 +5,6 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
-
-
-#ifndef CRYINCLUDE_EDITOR_INCLUDE_IOBJECTMANAGER_H
-#define CRYINCLUDE_EDITOR_INCLUDE_IOBJECTMANAGER_H
#pragma once
#include
@@ -29,32 +25,15 @@ class CObjectArchive;
class CViewport;
struct HitContext;
enum class ImageRotationDegrees;
-struct IStatObj;
class CBaseObject;
class XmlNodeRef;
#include "ObjectEvent.h"
-enum SerializeFlags
-{
- SERIALIZE_ALL = 0,
- SERIALIZE_ONLY_SHARED = 1,
- SERIALIZE_ONLY_NOTSHARED = 2,
-};
-
//////////////////////////////////////////////////////////////////////////
typedef std::vector CBaseObjectsArray;
typedef std::pair< bool(CALLBACK*)(CBaseObject const&, void*), void* > BaseObjectFilterFunctor;
-struct IObjectSelectCallback
-{
- //! Called when object is selected.
- //! Return true if selection should proceed, or false to abort object selection.
- virtual bool OnSelectObject(CBaseObject* obj) = 0;
- //! Return true if object can be selected.
- virtual bool CanSelectObject(CBaseObject* obj) = 0;
-};
-
//////////////////////////////////////////////////////////////////////////
//
// Interface to access editor objects scene graph.
@@ -78,10 +57,6 @@ public:
virtual void DeleteObject(CBaseObject* obj) = 0;
virtual void DeleteSelection(CSelectionGroup* pSelection) = 0;
virtual void DeleteAllObjects() = 0;
- virtual CBaseObject* CloneObject(CBaseObject* obj) = 0;
-
- virtual void BeginEditParams(CBaseObject* obj, int flags) = 0;
- virtual void EndEditParams(int flags = 0) = 0;
//! Get number of objects manager by ObjectManager (not contain sub objects of groups).
virtual int GetObjectCount() const = 0;
@@ -90,27 +65,9 @@ public:
//! @param layer if 0 get objects for all layers, or layer to get objects from.
virtual void GetObjects(CBaseObjectsArray& objects) const = 0;
- //! Get array of objects that pass the filter.
- //! @param filter The filter functor, return true if you want to get the certain obj, return false if want to skip it.
- virtual void GetObjects(CBaseObjectsArray& objects, BaseObjectFilterFunctor const& filter) const = 0;
-
//! Display objects on specified display context.
virtual void Display(DisplayContext& dc) = 0;
- //! Called when selecting without selection helpers - this is needed since
- //! the visible object cache is normally not updated when not displaying helpers.
- virtual void ForceUpdateVisibleObjectCache(DisplayContext& dc) = 0;
-
- //! Check intersection with objects.
- //! Find intersection with nearest to ray origin object hit by ray.
- //! If distance tollerance is specified certain relaxation applied on collision test.
- //! @return true if hit any object, and fills hitInfo structure.
- virtual bool HitTest(HitContext& hitInfo) = 0;
-
- //! Check intersection with an object.
- //! @return true if hit, and fills hitInfo structure.
- virtual bool HitTestObject(CBaseObject* obj, HitContext& hc) = 0;
-
//! Gets a radius to be used for hit tests on the axis helpers, like the transform gizmo.
//! @return the axis helper hit radius.
virtual int GetAxisHelperHitRadius() const = 0;
@@ -137,59 +94,18 @@ public:
//! Find objects which intersect with a given AABB.
virtual void FindObjectsInAABB(const AABB& aabb, std::vector& result) const = 0;
- //////////////////////////////////////////////////////////////////////////
- // Operations on objects.
- //////////////////////////////////////////////////////////////////////////
- //! Makes object visible or invisible.
- virtual void HideObject(CBaseObject* obj, bool hide) = 0;
- //! Shows the last hidden object based on hidden ID
- virtual void ShowLastHiddenObject() = 0;
- //! Freeze object, making it unselectable.
- virtual void FreezeObject(CBaseObject* obj, bool freeze) = 0;
- //! Unhide all hidden objects.
- virtual void UnhideAll() = 0;
- //! Unfreeze all frozen objects.
- virtual void UnfreezeAll() = 0;
-
//////////////////////////////////////////////////////////////////////////
// Object Selection.
//////////////////////////////////////////////////////////////////////////
virtual bool SelectObject(CBaseObject* obj, bool bUseMask = true) = 0;
virtual void UnselectObject(CBaseObject* obj) = 0;
- //! Select objects within specified distance from given position.
- //! Return number of selected objects.
- virtual int SelectObjects(const AABB& box, bool bUnselect = false) = 0;
-
- virtual void SelectEntities(std::set& s) = 0;
-
- virtual int MoveObjects(const AABB& box, const Vec3& offset, ImageRotationDegrees rotation, bool bIsCopy = false) = 0;
-
- //! Selects/Unselects all objects within 2d rectangle in given viewport.
- virtual void SelectObjectsInRect(CViewport* view, const QRect& rect, bool bSelect) = 0;
- virtual void FindObjectsInRect(CViewport* view, const QRect& rect, std::vector& guids) = 0;
-
//! Clear default selection set.
//! @Return number of objects removed from selection.
virtual int ClearSelection() = 0;
- //! Deselect all current selected objects and selects object that were unselected.
- //! @Return number of selected objects.
- virtual int InvertSelection() = 0;
-
//! Get current selection.
virtual CSelectionGroup* GetSelection() const = 0;
- //! Get named selection.
- virtual CSelectionGroup* GetSelection(const QString& name) const = 0;
- // Get selection group names
- virtual void GetNameSelectionStrings(QStringList& names) = 0;
- //! Change name of current selection group.
- //! And store it in list.
- virtual void NameSelection(const QString& name) = 0;
- //! Set one of name selections as current selection.
- virtual void SetSelection(const QString& name) = 0;
- //! Removes one of named selections.
- virtual void RemoveSelection(const QString& name) = 0;
//! Delete all objects in current selection group.
virtual void DeleteSelection() = 0;
@@ -198,54 +114,11 @@ public:
virtual QString GenerateUniqueObjectName(const QString& typeName) = 0;
//! Register object name in object manager, needed for generating uniq names.
virtual void RegisterObjectName(const QString& name) = 0;
- //! Enable/Disable generating of unique object names (Enabled by default).
- //! Return previous value.
- virtual bool EnableUniqObjectNames(bool bEnable) = 0;
//! Find object class by name.
virtual CObjectClassDesc* FindClass(const QString& className) = 0;
- virtual void GetClassCategories(QStringList& categories) = 0;
- virtual void GetClassCategoryToolClassNamePairs(std::vector< std::pair >& categoryToolClassNamePairs) = 0;
- virtual void GetClassTypes(const QString& category, QStringList& types) = 0;
-
- //! Export objects to xml.
- //! When onlyShared is true ony objects with shared flags exported, overwise only not shared object exported.
- virtual void Export(const QString& levelPath, XmlNodeRef& rootNode, bool onlyShared) = 0;
- //! Export only entities to xml.
- virtual void ExportEntities(XmlNodeRef& rootNode) = 0;
-
- //! Serialize Objects in manager to specified XML Node.
- //! @param flags Can be one of SerializeFlags.
- virtual void Serialize(XmlNodeRef& rootNode, bool bLoading, int flags = SERIALIZE_ALL) = 0;
- virtual void SerializeNameSelection(XmlNodeRef& rootNode, bool bLoading) = 0;
-
- //! Load objects from object archive.
- //! @param bSelect if set newly loaded object will be selected.
- virtual void LoadObjects(CObjectArchive& ar, bool bSelect) = 0;
virtual void ChangeObjectId(REFGUID oldId, REFGUID newId) = 0;
- virtual bool IsDuplicateObjectName(const QString& newName) const = 0;
- virtual void ShowDuplicationMsgWarning(CBaseObject* obj, const QString& newName, bool bShowMsgBox) const = 0;
- virtual void ChangeObjectName(CBaseObject* obj, const QString& newName) = 0;
-
- //! while loading PreFabs we need to force this IDs
- //! to force always the same IDs, on each load.
- //! needed for RAM-maps assignments
- virtual uint32 ForceID() const = 0;
- virtual void ForceID(uint32 FID) = 0;
-
- //! Convert object of one type to object of another type.
- //! Original object is deleted.
- virtual bool ConvertToType(CBaseObject* pObject, const QString& typeName) = 0;
-
- //! Set new selection callback.
- //! @return previous selection callback.
- virtual IObjectSelectCallback* SetSelectCallback(IObjectSelectCallback* callback) = 0;
-
- // Enables/Disables creating of game objects.
- virtual void SetCreateGameObject(bool enable) = 0;
- //! Return true if objects loaded from xml should immidiatly create game objects associated with them.
- virtual bool IsCreateGameObjects() const = 0;
virtual IGizmoManager* GetGizmoManager() = 0;
@@ -253,34 +126,9 @@ public:
//! Invalidate visibily settings of objects.
virtual void InvalidateVisibleList() = 0;
- //////////////////////////////////////////////////////////////////////////
- // ObjectManager notification Callbacks.
- //////////////////////////////////////////////////////////////////////////
- virtual void AddObjectEventListener(EventListener* listener) = 0;
- virtual void RemoveObjectEventListener(EventListener* listener) = 0;
-
- //////////////////////////////////////////////////////////////////////////
- // Used to indicate starting and ending of objects loading.
- //////////////////////////////////////////////////////////////////////////
- virtual void StartObjectsLoading(int numObjects) = 0;
- virtual void EndObjectsLoading() = 0;
-
//////////////////////////////////////////////////////////////////////////
// Gathers all resources used by all objects.
virtual void GatherUsedResources(CUsedResources& resources) = 0;
virtual bool IsLightClass(CBaseObject* pObject) = 0;
-
- virtual void FindAndRenameProperty2(const char* property2Name, const QString& oldValue, const QString& newValue) = 0;
- virtual void FindAndRenameProperty2If(const char* property2Name, const QString& oldValue, const QString& newValue, const char* otherProperty2Name, const QString& otherValue) = 0;
-
- virtual bool IsReloading() const = 0;
-
- // Set bSkipUpdate to true if you want to skip update objects on the idle loop.
- virtual void SetSkipUpdate(bool bSkipUpdate) = 0;
-
- virtual void SetExportingLevel(bool bExporting) = 0;
- virtual bool IsExportingLevelInprogress() const = 0;
};
-
-#endif // CRYINCLUDE_EDITOR_INCLUDE_IOBJECTMANAGER_H
diff --git a/Code/Editor/Include/ObjectEvent.h b/Code/Editor/Include/ObjectEvent.h
index e59bca6111..a117a8f8f1 100644
--- a/Code/Editor/Include/ObjectEvent.h
+++ b/Code/Editor/Include/ObjectEvent.h
@@ -14,7 +14,6 @@
//! Standart objects types.
enum ObjectType
{
- OBJTYPE_DUMMY = 1 << 20,
OBJTYPE_AZENTITY = 1 << 21,
};
diff --git a/Code/Editor/KeyboardCustomizationSettings.cpp b/Code/Editor/KeyboardCustomizationSettings.cpp
index c4f9133f66..81d9375850 100644
--- a/Code/Editor/KeyboardCustomizationSettings.cpp
+++ b/Code/Editor/KeyboardCustomizationSettings.cpp
@@ -240,7 +240,7 @@ QJsonObject KeyboardCustomizationSettings::ExportGroup()
void KeyboardCustomizationSettings::ImportFromFile(QWidget* parent)
{
- QString fileName = QFileDialog::getOpenFileName(parent, QObject::tr("Export Keyboard Shortcuts"), QStringLiteral(""), QObject::tr("Keyboard Settings (*.keys)"));
+ QString fileName = QFileDialog::getOpenFileName(parent, QObject::tr("Export Keyboard Shortcuts"), QString(), QObject::tr("Keyboard Settings (*.keys)"));
if (fileName.isEmpty())
{
return;
diff --git a/Code/Editor/LayoutWnd.cpp b/Code/Editor/LayoutWnd.cpp
index aa2a008844..ea125ca3d4 100644
--- a/Code/Editor/LayoutWnd.cpp
+++ b/Code/Editor/LayoutWnd.cpp
@@ -487,7 +487,6 @@ bool CLayoutWnd::LoadConfig()
CreateLayout((EViewLayout)layout, false);
- bool bRebindViewports = false;
if (m_splitWnd)
{
const QString str = settings.value("Viewports").toString();
@@ -498,14 +497,12 @@ bool CLayoutWnd::LoadConfig()
{
break;
}
- bRebindViewports = true;
if (!resToken.isEmpty())
{
m_viewType[nIndex] = resToken;
}
nIndex++;
}
- ;
}
BindViewports();
diff --git a/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp b/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp
index 76e23466f7..0dcda3be33 100644
--- a/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp
+++ b/Code/Editor/Lib/Tests/Camera/test_EditorCamera.cpp
@@ -15,28 +15,19 @@
#include
#include
+#include
+
namespace UnitTest
{
- class EditorCameraTestEnvironment : public AZ::Test::GemTestEnvironment
- {
- // AZ::Test::GemTestEnvironment overrides ...
- void AddGemsAndComponents() override;
- };
-
- void EditorCameraTestEnvironment::AddGemsAndComponents()
- {
- AddDynamicModulePaths({ CAMERA_EDITOR_MODULE });
- AddComponentDescriptors({ AzToolsFramework::Components::TransformComponent::CreateDescriptor() });
- }
-
class EditorCameraFixture : public ::testing::Test
{
public:
+ AZ::ComponentApplication* m_application = nullptr;
AtomToolsFramework::ModularCameraViewportContext* m_cameraViewportContextView = nullptr;
AZStd::unique_ptr m_editorModularViewportCameraComposer;
- AZStd::unique_ptr m_editorLibHandle;
AzFramework::ViewportControllerListPtr m_controllerList;
- AZStd::unique_ptr m_entity;
+ AZ::Entity* m_entity = nullptr;
+ AZ::ComponentDescriptor* m_transformComponent = nullptr;
static inline constexpr AzFramework::ViewportId TestViewportId = 2345;
static inline constexpr float HalfInterpolateToTransformDuration =
@@ -44,18 +35,19 @@ namespace UnitTest
void SetUp() override
{
- m_editorLibHandle = AZ::DynamicModuleHandle::Create("EditorLib");
- [[maybe_unused]] const bool loaded = m_editorLibHandle->Load(true);
- AZ_Assert(loaded, "EditorLib could not be loaded");
+ m_application = aznew AZ::ComponentApplication;
+ AZ::ComponentApplication::Descriptor appDesc;
+ m_entity = m_application->Create(appDesc);
+ m_transformComponent = AzToolsFramework::Components::TransformComponent::CreateDescriptor();
+ m_application->RegisterComponentDescriptor(m_transformComponent);
- m_controllerList = AZStd::make_shared();
- m_controllerList->RegisterViewportContext(TestViewportId);
-
- m_entity = AZStd::make_unique();
m_entity->Init();
m_entity->CreateComponent();
m_entity->Activate();
+ m_controllerList = AZStd::make_shared();
+ m_controllerList->RegisterViewportContext(TestViewportId);
+
m_editorModularViewportCameraComposer = AZStd::make_unique(TestViewportId);
auto controller = m_editorModularViewportCameraComposer->CreateModularViewportCameraController();
@@ -74,8 +66,17 @@ namespace UnitTest
{
m_editorModularViewportCameraComposer.reset();
m_cameraViewportContextView = nullptr;
- m_entity.reset();
- m_editorLibHandle = {};
+
+ if (m_application)
+ {
+ m_application->UnregisterComponentDescriptor(m_transformComponent);
+ delete m_transformComponent;
+ m_transformComponent = nullptr;
+
+ m_application->Destroy();
+ delete m_application;
+ m_application = nullptr;
+ }
}
};
@@ -258,16 +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
-
-// required to support running integration tests with the Camera Gem
-AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv)
-{
- ::testing::InitGoogleMock(&argc, argv);
- AZ::Test::printUnusedParametersWarning(argc, argv);
- AZ::Test::addTestEnvironments({ new UnitTest::EditorCameraTestEnvironment() });
- int result = RUN_ALL_TESTS();
- return result;
-}
-
-IMPLEMENT_TEST_EXECUTABLE_MAIN();
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..1fd70cb88c 100644
--- a/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp
+++ b/Code/Editor/Lib/Tests/test_DisplaySettingsPythonBindings.cpp
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
@@ -22,7 +23,7 @@ namespace DisplaySettingsPythonBindingsUnitTests
{
class DisplaySettingsPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -30,7 +31,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 +52,7 @@ namespace DisplaySettingsPythonBindingsUnitTests
}
class DisplaySettingsComponentFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -60,7 +60,6 @@ namespace DisplaySettingsPythonBindingsUnitTests
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
- appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
m_app.RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsComponent::CreateDescriptor());
diff --git a/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp b/Code/Editor/Lib/Tests/test_EditorPythonBindings.cpp
index 1006c339ee..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
@@ -25,7 +26,6 @@
#include
#include
#include
-#include
#include
#include "IEditorMock.h"
@@ -80,7 +80,7 @@ namespace EditorPythonBindingsUnitTests
};
class EditorPythonBindingsFixture
- : public testing::Test
+ : public ::UnitTest::ScopedAllocatorSetupFixture
{
public:
AzToolsFramework::ToolsApplication m_app;
@@ -88,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_Main.cpp b/Code/Editor/Lib/Tests/test_Main.cpp
index 6250c540db..91369ee8b6 100644
--- a/Code/Editor/Lib/Tests/test_Main.cpp
+++ b/Code/Editor/Lib/Tests/test_Main.cpp
@@ -9,12 +9,13 @@
#include "EditorDefs.h"
#include
#include
+#include
#include
#include
class EditorLibTestEnvironment
- : public AZ::Test::ITestEnvironment
+ : public ::UnitTest::TraceBusHook
{
public:
~EditorLibTestEnvironment() override = default;
@@ -22,16 +23,20 @@ public:
protected:
void SetupEnvironment() override
{
+ ::UnitTest::TraceBusHook::SetupEnvironment();
+
AZ::Environment::Create(nullptr);
- AttachEditorAZEnvironment(AZ::Environment::GetInstance());
AZ::AllocatorInstance::Create();
+ AttachEditorAZEnvironment(AZ::Environment::GetInstance());
}
void TeardownEnvironment() override
{
- AZ::AllocatorInstance::Destroy();
DetachEditorAZEnvironment();
+ AZ::AllocatorInstance::Destroy();
AZ::Environment::Destroy();
+
+ ::UnitTest::TraceBusHook::TeardownEnvironment();
}
};
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_ModularViewportCameraController.cpp b/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp
index 656440f16e..67d89ad967 100644
--- a/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp
+++ b/Code/Editor/Lib/Tests/test_ModularViewportCameraController.cpp
@@ -9,7 +9,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/Code/Editor/Lib/Tests/test_ObjectManagerPythonBindings.cpp b/Code/Editor/Lib/Tests/test_ObjectManagerPythonBindings.cpp
index 39a89670ef..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
@@ -63,16 +63,6 @@ namespace ObjectManagerPythonBindingsUnitTests
EXPECT_TRUE(behaviorContext->m_methods.find("get_selection_center") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("get_selection_aabb") != behaviorContext->m_methods.end());
- EXPECT_TRUE(behaviorContext->m_methods.find("hide_object") != behaviorContext->m_methods.end());
- EXPECT_TRUE(behaviorContext->m_methods.find("is_object_hidden") != behaviorContext->m_methods.end());
- EXPECT_TRUE(behaviorContext->m_methods.find("unhide_object") != behaviorContext->m_methods.end());
- EXPECT_TRUE(behaviorContext->m_methods.find("hide_all_objects") != behaviorContext->m_methods.end());
- EXPECT_TRUE(behaviorContext->m_methods.find("unhide_all_objects") != behaviorContext->m_methods.end());
-
- EXPECT_TRUE(behaviorContext->m_methods.find("freeze_object") != behaviorContext->m_methods.end());
- EXPECT_TRUE(behaviorContext->m_methods.find("is_object_frozen") != behaviorContext->m_methods.end());
- EXPECT_TRUE(behaviorContext->m_methods.find("unfreeze_object") != behaviorContext->m_methods.end());
-
EXPECT_TRUE(behaviorContext->m_methods.find("delete_object") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("delete_selected") != behaviorContext->m_methods.end());
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 191596f4ae..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