merge latest
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -12,6 +12,7 @@ Editor/EditorEventLog.xml
|
||||
Editor/EditorLayout.xml
|
||||
**/*egg-info/**
|
||||
**/*egg-link
|
||||
**/[Rr]estricted
|
||||
UserSettings.xml
|
||||
[Uu]ser/
|
||||
FrameCapture/**
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:27f87510ae07771dbad3e430e31502b1d1d13dee868f143b7f1de2a7febc8eb9
|
||||
size 7046400
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"$type": "ScriptProcessorRule",
|
||||
"scriptFilename": "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
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:011454252e40c927343cce16296412f02f45d1f345c75c036651bdcca473bda5
|
||||
size 2672
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7bafcc4aefab827e1414e64bcdde235500b51392e52c9ccd588b2d7a24b865a0
|
||||
size 20214
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ac841c02e81c9ae23476522b7e517889d746d4ff32b3251ac4360168f39b30a3
|
||||
size 450708
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3653ca7fb42c7e5991815c17fc9ebeab14a1aa861bfb1d37e233ada66a835f00
|
||||
size 7188
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a30b85428202c548e77cdcc0a595f9f26e82d29622be26891d569f4779a75830
|
||||
size 1802388
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a3d76b7c93f8873ca7c4013dcc4eff887c25552c9c5847290481306656b22069
|
||||
size 3668
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:219f57137c5bd44093762ea9d0fc24308679956b980f26bf194edd3a1798fcda
|
||||
size 3668
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:96ed61c66d1d1f71e940ab75899ee253007e704004e1157c900c6308151a8bf1
|
||||
size 1802388
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:70a7dc4e2455624067e842b059954f6c4bb9b0debc3cb1ffa783b14bffc61786
|
||||
size 7188
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7f5a945c61f92f3da77dfd9fdd2c95aa257f4df6bcb82483c608ab660bb72e5f
|
||||
size 450708
|
||||
-2
@@ -5,5 +5,3 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
add_subdirectory(Code)
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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))
|
||||
@@ -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)
|
||||
|
||||
@@ -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(/.+)$"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<Component
|
||||
Name="NetworkTestPlayerComponent"
|
||||
Namespace="AutomatedTesting"
|
||||
OverrideComponent="false"
|
||||
OverrideController="false"
|
||||
OverrideInclude=""
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<ComponentRelation Constraint="Required" HasController="true" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />
|
||||
|
||||
<NetworkInput Type="float" Name="FwdBack" Init="0.0f" ExposeToScript="true"/>
|
||||
<NetworkInput Type="float" Name="LeftRight" Init="0.0f" ExposeToScript="true"/>
|
||||
|
||||
<RemoteProcedure Name="AutonomousToAuthority" InvokeFrom="Autonomous" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
|
||||
<Param Type="float" Name="SomeFloat" />
|
||||
</RemoteProcedure>
|
||||
|
||||
<RemoteProcedure Name="AutonomousToAuthorityNoParams" InvokeFrom="Autonomous" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
|
||||
|
||||
<RemoteProcedure Name="AuthorityToAutonomous" InvokeFrom="Authority" HandleOn="Autonomous" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
|
||||
<Param Type="float" Name="SomeFloat" />
|
||||
</RemoteProcedure>
|
||||
|
||||
<RemoteProcedure Name="AuthorityToAutonomousNoParams" InvokeFrom="Authority" HandleOn="Autonomous" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
|
||||
|
||||
<RemoteProcedure Name="AuthorityToClient" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
|
||||
<Param Type="float" Name="SomeFloat" />
|
||||
</RemoteProcedure>
|
||||
|
||||
<RemoteProcedure Name="AuthorityToClientNoParams" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
|
||||
|
||||
<RemoteProcedure Name="ServerToAuthority" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" >
|
||||
<Param Type="float" Name="SomeFloat" />
|
||||
</RemoteProcedure>
|
||||
|
||||
<RemoteProcedure Name="ServerToAuthorityNoParam" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="false" GenerateEventBindings="true" Description="" />
|
||||
|
||||
|
||||
</Component>
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Module/Module.h>
|
||||
#include <Source/AutoGen/AutoComponentTypes.h>
|
||||
|
||||
#include <AutomatedTestingSystemComponent.h>
|
||||
|
||||
@@ -27,6 +28,8 @@ namespace AutomatedTesting
|
||||
m_descriptors.insert(m_descriptors.end(), {
|
||||
AutomatedTestingSystemComponent::CreateDescriptor(),
|
||||
});
|
||||
|
||||
CreateComponentDescriptors(m_descriptors); //< Register multiplayer components
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
#include <Source/AutoGen/AutoComponentTypes.h>
|
||||
|
||||
#include <AutomatedTestingSystemComponent.h>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -11,4 +11,5 @@ set(FILES
|
||||
Source/AutomatedTestingModule.cpp
|
||||
Source/AutomatedTestingSystemComponent.cpp
|
||||
Source/AutomatedTestingSystemComponent.h
|
||||
Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml
|
||||
)
|
||||
|
||||
@@ -56,4 +56,5 @@ set(ENABLED_GEMS
|
||||
AudioSystem
|
||||
Terrain
|
||||
Profiler
|
||||
Multiplayer
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
+109
@@ -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)
|
||||
+124
@@ -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)
|
||||
-238
@@ -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()
|
||||
@@ -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)
|
||||
+67
-41
@@ -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__":
|
||||
|
||||
+193
@@ -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)
|
||||
+82
-47
@@ -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__":
|
||||
|
||||
+187
@@ -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)
|
||||
+71
-41
@@ -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__":
|
||||
|
||||
+93
-45
@@ -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__":
|
||||
|
||||
+158
@@ -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)
|
||||
+95
-52
@@ -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__":
|
||||
|
||||
+74
-41
@@ -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__":
|
||||
|
||||
@@ -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)
|
||||
+192
@@ -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)
|
||||
+177
@@ -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)
|
||||
+57
-30
@@ -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__":
|
||||
|
||||
+211
@@ -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)
|
||||
+9
-11
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
+159
@@ -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)
|
||||
+60
-31
@@ -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__":
|
||||
|
||||
+9
-7
@@ -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())
|
||||
|
||||
+6
-6
@@ -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.
|
||||
|
||||
+87
-45
@@ -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__":
|
||||
|
||||
+9
-9
@@ -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",
|
||||
|
||||
+28
-20
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+2
-1
@@ -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,
|
||||
)
|
||||
|
||||
-24
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
+199
-22
@@ -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])
|
||||
|
||||
+26
@@ -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):
|
||||
"""
|
||||
|
||||
+7
-2
@@ -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():
|
||||
|
||||
|
||||
+8
@@ -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:
|
||||
|
||||
|
||||
+85
-2
@@ -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
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
+115
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
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)
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+3
-3
@@ -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)
|
||||
+3
-3
@@ -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)
|
||||
+3
-3
@@ -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)
|
||||
+99
@@ -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)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user