fix merge conflict
Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>
This commit is contained in:
@@ -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,116 +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 shows basic usage of LuaSymbolsReporterBus,
|
||||
# Which can be used to report all symbols available for
|
||||
# game scripting with Lua.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import azlmbr.bus as azbus
|
||||
import azlmbr.script as azscript
|
||||
import azlmbr.legacy.general as azgeneral
|
||||
|
||||
|
||||
def _dump_class_symbol(class_symbol: azlmbr.script.LuaClassSymbol):
|
||||
print(f"** {class_symbol}")
|
||||
print("Properties:")
|
||||
for property_symbol in class_symbol.properties:
|
||||
print(f" - {property_symbol}")
|
||||
print("Methods:")
|
||||
for method_symbol in class_symbol.methods:
|
||||
print(f" - {method_symbol}")
|
||||
|
||||
|
||||
def _dump_lua_classes():
|
||||
class_symbols = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfClasses")
|
||||
print("======== Classes ==========")
|
||||
sorted_classes_by_named = sorted(class_symbols, key=lambda class_symbol: class_symbol.name)
|
||||
for class_symbol in sorted_classes_by_named:
|
||||
_dump_class_symbol(class_symbol)
|
||||
print("\n\n")
|
||||
|
||||
|
||||
def _dump_lua_globals():
|
||||
global_properties = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfGlobalProperties")
|
||||
print("======== Global Properties ==========")
|
||||
sorted_properties_by_name = sorted(global_properties, key=lambda symbol: symbol.name)
|
||||
for property_symbol in sorted_properties_by_name:
|
||||
print(f"- {property_symbol}")
|
||||
print("\n\n")
|
||||
global_functions = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfGlobalFunctions")
|
||||
print("======== Global Functions ==========")
|
||||
sorted_functions_by_name = sorted(global_functions, key=lambda symbol: symbol.name)
|
||||
for function_symbol in sorted_functions_by_name:
|
||||
print(f"- {function_symbol}")
|
||||
print("\n\n")
|
||||
|
||||
|
||||
def _dump_lua_ebus(ebus_symbol: azlmbr.script.LuaEBusSymbol):
|
||||
print(f">> {ebus_symbol}")
|
||||
sorted_senders = sorted(ebus_symbol.senders, key=lambda symbol: symbol.name)
|
||||
for sender in sorted_senders:
|
||||
print(f" - {sender}")
|
||||
print("\n")
|
||||
|
||||
|
||||
def _dump_lua_ebuses():
|
||||
ebuses = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfEBuses")
|
||||
print("======== Ebus List ==========")
|
||||
sorted_ebuses_by_name = sorted(ebuses, key=lambda symbol: symbol.name)
|
||||
for ebus_symbol in sorted_ebuses_by_name:
|
||||
_dump_lua_ebus(ebus_symbol)
|
||||
print("\n\n")
|
||||
|
||||
|
||||
class WhatToDo:
|
||||
DumpClasses = "c"
|
||||
DumpGlobals = "g"
|
||||
DumpEBuses = "e"
|
||||
|
||||
if __name__ == "__main__":
|
||||
redirecting_stdout = False
|
||||
orig_stdout = sys.stdout
|
||||
if len(sys.argv) > 1:
|
||||
output_file_name = sys.argv[1]
|
||||
if not os.path.isabs(output_file_name):
|
||||
game_root_path = os.path.normpath(azgeneral.get_game_folder())
|
||||
output_file_name = os.path.join(game_root_path, output_file_name)
|
||||
try:
|
||||
file_obj = open(output_file_name, 'wt')
|
||||
sys.stdout = file_obj
|
||||
redirecting_stdout = True
|
||||
except Exception as e:
|
||||
print(f"Failed to open {output_file_name}: {e}")
|
||||
sys.exit(-1)
|
||||
|
||||
what_to_do = [action.lower() for action in sys.argv[2:]]
|
||||
|
||||
# If the user did not specify what to do, then let's dump
|
||||
# all the symbols.
|
||||
if len(what_to_do) < 1:
|
||||
what_to_do = [WhatToDo.DumpClasses, WhatToDo.DumpGlobals, WhatToDo.DumpEBuses]
|
||||
|
||||
for action in what_to_do:
|
||||
if action == WhatToDo.DumpClasses:
|
||||
_dump_lua_classes()
|
||||
elif action == WhatToDo.DumpGlobals:
|
||||
_dump_lua_globals()
|
||||
elif action == WhatToDo.DumpEBuses:
|
||||
_dump_lua_ebuses()
|
||||
|
||||
if redirecting_stdout:
|
||||
sys.stdout.close()
|
||||
sys.stdout = orig_stdout
|
||||
print(f" Lua Symbols Are available in: {output_file_name}")
|
||||
@@ -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,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)
|
||||
|
||||
@@ -12,6 +12,7 @@ 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__)
|
||||
@@ -159,3 +160,17 @@ class TestMaterialEditorBasicTests(object):
|
||||
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
|
||||
|
||||
@@ -18,6 +18,13 @@ LIGHT_TYPES = {
|
||||
'simple_spot': 7,
|
||||
}
|
||||
|
||||
# Qualiity Level settings for Diffuse Global Illumination level component
|
||||
GLOBAL_ILLUMINATION_QUALITY = {
|
||||
'Low': 0,
|
||||
'Medium': 1,
|
||||
'High': 2,
|
||||
}
|
||||
|
||||
|
||||
class AtomComponentProperties:
|
||||
"""
|
||||
@@ -116,6 +123,21 @@ class AtomComponentProperties:
|
||||
}
|
||||
return properties[property]
|
||||
|
||||
@staticmethod
|
||||
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:
|
||||
"""
|
||||
@@ -148,12 +170,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]
|
||||
|
||||
@@ -390,7 +417,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)
|
||||
+44
-24
@@ -5,16 +5,8 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
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")
|
||||
@@ -39,6 +31,12 @@ class Tests:
|
||||
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")
|
||||
@@ -68,19 +66,23 @@ 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 and asserts.
|
||||
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
|
||||
|
||||
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
|
||||
@@ -97,7 +99,7 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
|
||||
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(AtomComponentProperties.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()))
|
||||
@@ -126,33 +128,51 @@ def AtomEditorComponents_DisplayMapper_AddedToEntity():
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, display_mapper_entity.exists())
|
||||
|
||||
# 5. Enter/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. 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)
|
||||
|
||||
# 6. Test IsHidden.
|
||||
# 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 and asserts.
|
||||
# 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}")
|
||||
|
||||
-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,8 +26,8 @@ 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
|
||||
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:
|
||||
|
||||
+108
-1
@@ -107,7 +107,6 @@ class EditorComponent:
|
||||
return type_ids
|
||||
|
||||
|
||||
|
||||
def convert_to_azvector3(xyz) -> azlmbr.math.Vector3:
|
||||
"""
|
||||
Converts a vector3-like element into a azlmbr.math.Vector3
|
||||
@@ -120,6 +119,7 @@ def convert_to_azvector3(xyz) -> azlmbr.math.Vector3:
|
||||
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.
|
||||
@@ -459,3 +459,110 @@ class EditorEntity:
|
||||
"""
|
||||
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])
|
||||
|
||||
+32
@@ -34,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
|
||||
|
||||
@@ -98,38 +98,32 @@ class FileManagement:
|
||||
"""
|
||||
file_map = FileManagement._load_file_map()
|
||||
backup_path = FileManagement.backup_folder_path
|
||||
backup_file_name = "{}.bak".format(file_name)
|
||||
backup_file = os.path.join(backup_path, backup_file_name)
|
||||
# If backup directory DNE, make one
|
||||
if not os.path.exists(backup_path):
|
||||
os.mkdir(backup_path)
|
||||
# If "traditional" backup file exists, delete it (myFile.txt.bak)
|
||||
if os.path.exists(backup_file):
|
||||
fs.delete([backup_file], True, False)
|
||||
# Find my next storage name (myFile_1.txt.bak)
|
||||
backup_storage_file_name = FileManagement._next_available_name(backup_file_name, file_map)
|
||||
if backup_storage_file_name is None:
|
||||
|
||||
# Find my next storage name (myFile_1.txt)
|
||||
backup_file_name = FileManagement._next_available_name(file_name, file_map)
|
||||
if backup_file_name is None:
|
||||
# If _next_available_name returns None, we have backed up MAX_BACKUPS of files name [file_name]
|
||||
raise Exception(
|
||||
"FileManagement class ran out of backups per name. Max: {}".format(FileManagement.MAX_BACKUPS)
|
||||
)
|
||||
backup_storage_file = os.path.join(backup_path, backup_storage_file_name)
|
||||
|
||||
# If this backup file already exists, delete it.
|
||||
backup_storage_file = "{}.bak".format(os.path.normpath(os.path.join(backup_path, backup_file_name)))
|
||||
if os.path.exists(backup_storage_file):
|
||||
# This file should not exists, but if it does it's about to get clobbered!
|
||||
fs.unlock_file(backup_storage_file)
|
||||
# Create "traditional" backup file (myFile.txt.bak)
|
||||
fs.create_backup(os.path.join(file_path, file_name), backup_path)
|
||||
# Copy "traditional" backup file into storage backup (myFile_1.txt.bak)
|
||||
FileManagement._copy_file(backup_file_name, backup_path, backup_storage_file_name, backup_path)
|
||||
fs.lock_file(backup_storage_file)
|
||||
# Delete "traditional" back up file
|
||||
fs.unlock_file(backup_file)
|
||||
fs.delete([backup_file], True, False)
|
||||
fs.delete([backup_storage_file], True, False)
|
||||
|
||||
# Create backup file (myFile_1.txt.bak)
|
||||
original_file = os.path.normpath(os.path.join(file_path, file_name))
|
||||
fs.create_backup(original_file, backup_path, backup_file_name)
|
||||
|
||||
# Update file map with new file
|
||||
file_map[os.path.join(file_path, file_name)] = backup_storage_file_name
|
||||
file_map[original_file] = backup_file_name
|
||||
FileManagement._save_file_map(file_map)
|
||||
# Unlock original file to get it ready to be edited by the test
|
||||
fs.unlock_file(os.path.join(file_path, file_name))
|
||||
fs.unlock_file(original_file)
|
||||
|
||||
@staticmethod
|
||||
def _restore_file(file_name, file_path):
|
||||
@@ -143,20 +137,15 @@ class FileManagement:
|
||||
"""
|
||||
file_map = FileManagement._load_file_map()
|
||||
backup_path = FileManagement.backup_folder_path
|
||||
src_file = os.path.join(file_path, file_name)
|
||||
src_file = os.path.normpath(os.path.join(file_path, file_name))
|
||||
if src_file in file_map:
|
||||
backup_file = os.path.join(backup_path, file_map[src_file])
|
||||
if os.path.exists(backup_file):
|
||||
fs.unlock_file(backup_file)
|
||||
fs.unlock_file(src_file)
|
||||
# Make temporary copy of backed up file to restore from
|
||||
temp_file = "{}.bak".format(file_name)
|
||||
FileManagement._copy_file(file_map[src_file], backup_path, temp_file, backup_path)
|
||||
fs.restore_backup(src_file, backup_path)
|
||||
fs.lock_file(src_file)
|
||||
# Delete backup file
|
||||
fs.delete([os.path.join(backup_path, temp_file)], True, False)
|
||||
backup_file_name = file_map[src_file]
|
||||
backup_file = "{}.bak".format(os.path.join(backup_path, backup_file_name))
|
||||
|
||||
fs.unlock_file(src_file)
|
||||
if fs.restore_backup(src_file, backup_path, backup_file_name):
|
||||
fs.delete([backup_file], True, False)
|
||||
|
||||
# Remove from file map
|
||||
del file_map[src_file]
|
||||
FileManagement._save_file_map(file_map)
|
||||
|
||||
@@ -12,7 +12,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
NAME AutomatedTesting::PrefabTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -61,3 +61,11 @@ class TestAutomation(TestAutomationBase):
|
||||
def test_CreatePrefab_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
|
||||
from Prefab.tests.create_prefab import CreatePrefab_UnderAnotherPrefab as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
|
||||
|
||||
def test_DeleteEntity_UnderAnotherPrefab(self, request, workspace, editor, launcher_platform):
|
||||
from Prefab.tests.delete_entity import DeleteEntity_UnderAnotherPrefab as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
|
||||
|
||||
def test_DeleteEntity_UnderLevelPrefab(self, request, workspace, editor, launcher_platform):
|
||||
from Prefab.tests.delete_entity import DeleteEntity_UnderLevelPrefab as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
|
||||
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomationNoAutoTestMode(EditorTestSuite):
|
||||
|
||||
# Enable only -BatchMode for these tests. Some tests cannot run in -autotest_mode due to UI interactions
|
||||
global_extra_cmdline_args = ["-BatchMode"]
|
||||
|
||||
class test_CreatePrefab_UnderAnEntity(EditorSharedTest):
|
||||
from .tests.create_prefab import CreatePrefab_UnderAnEntity as test_module
|
||||
|
||||
class test_CreatePrefab_UnderAnotherPrefab(EditorSharedTest):
|
||||
from .tests.create_prefab import CreatePrefab_UnderAnotherPrefab as test_module
|
||||
|
||||
class test_DeleteEntity_UnderAnotherPrefab(EditorSharedTest):
|
||||
from .tests.delete_entity import DeleteEntity_UnderAnotherPrefab as test_module
|
||||
|
||||
class test_DeleteEntity_UnderLevelPrefab(EditorSharedTest):
|
||||
from .tests.delete_entity import DeleteEntity_UnderLevelPrefab as test_module
|
||||
|
||||
class test_ReparentPrefab_UnderAnotherPrefab(EditorSharedTest):
|
||||
from .tests.reparent_prefab import ReparentPrefab_UnderAnotherPrefab as test_module
|
||||
|
||||
class test_DetachPrefab_UnderAnotherPrefab(EditorSharedTest):
|
||||
from .tests.detach_prefab import DetachPrefab_UnderAnotherPrefab as test_module
|
||||
|
||||
class test_OpenLevel_ContainingTwoEntities(EditorSharedTest):
|
||||
from .tests.open_level import OpenLevel_ContainingTwoEntities as test_module
|
||||
|
||||
class test_CreatePrefab_WithSingleEntity(EditorSharedTest):
|
||||
from .tests.create_prefab import CreatePrefab_WithSingleEntity as test_module
|
||||
|
||||
class test_InstantiatePrefab_ContainingASingleEntity(EditorSharedTest):
|
||||
from .tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
|
||||
|
||||
class test_DeletePrefab_ContainingASingleEntity(EditorSharedTest):
|
||||
from .tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
|
||||
|
||||
class test_DuplicatePrefab_ContainingASingleEntity(EditorSharedTest):
|
||||
from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module
|
||||
+1
@@ -24,6 +24,7 @@ def CreatePrefab_WithSingleEntity():
|
||||
# Creates a prefab from the new entity
|
||||
Prefab.create_prefab(car_prefab_entities, CAR_PREFAB_FILE_NAME)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(CreatePrefab_WithSingleEntity)
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
def DeleteEntity_UnderAnotherPrefab():
|
||||
"""
|
||||
Test description:
|
||||
- Creates an entity.
|
||||
- Creates a prefab out of the above entity.
|
||||
- Focuses on the created prefab and destroys the entity within.
|
||||
Checks that the entity is correctly destroyed.
|
||||
"""
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
import Prefab.tests.PrefabTestUtils as prefab_test_utils
|
||||
|
||||
prefab_test_utils.open_base_tests_level()
|
||||
|
||||
PREFAB_FILE_NAME = 'some_prefab'
|
||||
|
||||
# Creates a new entity at the root level
|
||||
entity = EditorEntity.create_editor_entity()
|
||||
assert entity.id.IsValid(), "Couldn't create entity."
|
||||
|
||||
# Asserts if prefab creation doesn't succeed
|
||||
child_prefab, child_instance = Prefab.create_prefab([entity], PREFAB_FILE_NAME)
|
||||
child_entity_ids_inside_prefab = child_instance.get_direct_child_entities()
|
||||
assert len(
|
||||
child_entity_ids_inside_prefab) == 1, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \
|
||||
f" when there should have been just 1 entity"
|
||||
|
||||
child_entity_inside_prefab = child_entity_ids_inside_prefab[0]
|
||||
child_entity_inside_prefab.focus_on_owning_prefab()
|
||||
|
||||
child_entity_inside_prefab.delete()
|
||||
|
||||
# Wait till prefab propagation finishes before validating entity deletion.
|
||||
azlmbr.legacy.general.idle_wait_frames(1)
|
||||
|
||||
child_entity_ids_inside_prefab = child_instance.get_direct_child_entities()
|
||||
assert len(
|
||||
child_entity_ids_inside_prefab) == 0, f"{len(child_entity_ids_inside_prefab)} entities found inside prefab" \
|
||||
f" when there should have been 0 entities"
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(DeleteEntity_UnderAnotherPrefab)
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
def DeleteEntity_UnderLevelPrefab():
|
||||
"""
|
||||
Test description:
|
||||
- Creates an entity.
|
||||
- Destroys the created entity.
|
||||
Checks that the entity is correctly destroyed.
|
||||
"""
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
import Prefab.tests.PrefabTestUtils as prefab_test_utils
|
||||
|
||||
prefab_test_utils.open_base_tests_level()
|
||||
|
||||
# Creates a new Entity at the root level
|
||||
# Asserts if creation didn't succeed
|
||||
entity = EditorEntity.create_editor_entity_at((100.0, 100.0, 100.0), name = "TestEntity")
|
||||
assert entity.id.IsValid(), "Couldn't create entity"
|
||||
|
||||
level_container_entity = EditorEntity(entity.get_parent_id())
|
||||
entity.delete()
|
||||
|
||||
# Wait till prefab propagation finishes before validating entity deletion.
|
||||
azlmbr.legacy.general.idle_wait_frames(1)
|
||||
level_container_child_entities_count = len(level_container_entity.get_children_ids())
|
||||
assert level_container_child_entities_count == 0, f"The level still has {level_container_child_entities_count}" \
|
||||
f" children when it should have 0."
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(DeleteEntity_UnderLevelPrefab)
|
||||
+2
-2
@@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
def DetachPrefab_UnderAnotherPrefab():
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab'
|
||||
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab'
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab2'
|
||||
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab2'
|
||||
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
class HeightTests:
|
||||
single_gradient_height_correct = (
|
||||
"Successfully retrieved height for gradient1.",
|
||||
"Failed to retrieve height for gradient1."
|
||||
)
|
||||
double_gradient_height_correct = (
|
||||
"Successfully retrieved height when two gradients exist.",
|
||||
"Failed to retrieve height when two gradients exist."
|
||||
)
|
||||
triple_gradient_height_correct = (
|
||||
"Successfully retrieved height when three gradients exist.",
|
||||
"Failed to retrieve height when three gradients exist."
|
||||
)
|
||||
terrain_data_changed_call_count_correct = (
|
||||
"OnTerrainDataChanged called expected number of times.",
|
||||
"OnTerrainDataChanged call count incorrect."
|
||||
)
|
||||
|
||||
def TerrainHeightGradientList_AddRemoveGradientWorks():
|
||||
"""
|
||||
Summary:
|
||||
Test aspects of the TerrainHeightGradientList through the BehaviorContext and the Property Tree.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
import math as sys_math
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.math as math
|
||||
import azlmbr.terrain as terrain
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.vegetation as vegetation
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
|
||||
terrain_changed_call_count = 0
|
||||
expected_terrain_changed_calls = 0
|
||||
|
||||
aabb_component_name = "Axis Aligned Box Shape"
|
||||
gradientlist_component_name = "Terrain Height Gradient List"
|
||||
layerspawner_component_name = "Terrain Layer Spawner"
|
||||
|
||||
gradient_value_path = "Configuration|Value"
|
||||
|
||||
def create_entity_at(entity_name, components_to_add, x, y, z):
|
||||
entity = hydra.Entity(entity_name)
|
||||
entity.create_entity(math.Vector3(x, y, z), components_to_add)
|
||||
|
||||
return entity
|
||||
|
||||
def on_terrain_changed(args):
|
||||
nonlocal terrain_changed_call_count
|
||||
|
||||
terrain_changed_call_count += 1
|
||||
|
||||
def set_component_path_val(entity, component, path, value):
|
||||
entity.get_set_test(component, path, value)
|
||||
|
||||
def set_gradients_check_height(main_entity, gradient_list, expected_height, test_results):
|
||||
nonlocal expected_terrain_changed_calls
|
||||
|
||||
test_tolerance = 0.01
|
||||
gradient_list_path = "Configuration|Gradient Entities"
|
||||
|
||||
set_component_path_val(main_entity, 1, gradient_list_path, gradient_list)
|
||||
|
||||
expected_terrain_changed_calls += 1
|
||||
|
||||
# Wait until the terrain data has been updated.
|
||||
helper.wait_for_condition(lambda: terrain_changed_call_count == expected_terrain_changed_calls, 2.0)
|
||||
|
||||
# Get the height at the origin.
|
||||
height = terrain.TerrainDataRequestBus(bus.Broadcast, "GetHeightFromFloats", 0.0, 0.0, 0)
|
||||
|
||||
Report.result(test_results, sys_math.isclose(height, expected_height, abs_tol=test_tolerance))
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# Open a level.
|
||||
helper.open_level("Physics", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# Add a terrain world component
|
||||
world_component = hydra.add_level_component("Terrain World")
|
||||
|
||||
aabb_height = 1024.0
|
||||
box_dimensions = math.Vector3(1.0, 1.0, aabb_height);
|
||||
|
||||
# Create a main entity with a LayerSpawner, AAbb and HeightGradientList.
|
||||
main_entity = create_entity_at("entity2", [layerspawner_component_name, gradientlist_component_name, aabb_component_name], 0.0, 0.0, aabb_height/2.0)
|
||||
|
||||
# Create three gradient entities.
|
||||
gradient_entity1 = create_entity_at("Constant Gradient1", ["Constant Gradient"], 0.0, 0.0, 0.0);
|
||||
gradient_entity2 = create_entity_at("Constant Gradient2", ["Constant Gradient"], 0.0, 0.0, 0.0);
|
||||
gradient_entity3 = create_entity_at("Constant Gradient3", ["Constant Gradient"], 0.0, 0.0, 0.0);
|
||||
|
||||
# Give everything a chance to finish initializing.
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# Set the gradients to different values.
|
||||
gradient_values = [0.5, 0.8, 0.3]
|
||||
set_component_path_val(gradient_entity1, 0, gradient_value_path, gradient_values[0])
|
||||
set_component_path_val(gradient_entity2, 0, gradient_value_path, gradient_values[1])
|
||||
set_component_path_val(gradient_entity3, 0, gradient_value_path, gradient_values[2])
|
||||
|
||||
# Give the TerrainSystem time to tick.
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# Set the dimensions of the Aabb.
|
||||
set_component_path_val(main_entity, 2, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
|
||||
|
||||
# Set up a handler to wait for notifications from the TerrainSystem.
|
||||
handler = azlmbr.terrain.TerrainDataNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback("OnTerrainDataChanged", on_terrain_changed)
|
||||
|
||||
# Add a gradient to GradientList, then check the height returned from the TerrainSystem is correct.
|
||||
set_gradients_check_height(main_entity, [gradient_entity1.id], aabb_height * gradient_values[0], HeightTests.single_gradient_height_correct)
|
||||
|
||||
# Add gradient2 and check height at the origin, this should have changed to match the second gradient value.
|
||||
set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id], aabb_height * gradient_values[1], HeightTests.double_gradient_height_correct)
|
||||
|
||||
# Add gradient3, the height should still be the second value, as that was the highest.
|
||||
set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id, gradient_entity3.id], aabb_height * gradient_values[1], HeightTests.triple_gradient_height_correct)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(TerrainHeightGradientList_AddRemoveGradientWorks)
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
class VegetationTests:
|
||||
vegetation_on_gradient_1 = (
|
||||
"Vegetation detected at correct position on Gradient1",
|
||||
"Vegetation not detected at correct position on Gradient1"
|
||||
)
|
||||
vegetation_on_gradient_2 = (
|
||||
"Vegetation detected at correct position on Gradient2",
|
||||
"Vegetation not detected at correct position on Gradient2"
|
||||
)
|
||||
unfiltered_vegetation_count_correct = (
|
||||
"Unfiltered vegetation spawn count correct",
|
||||
"Unfiltered vegetation spawn count incorrect"
|
||||
)
|
||||
|
||||
testTag2_excluded_vegetation_count_correct = (
|
||||
"TestTag2 filtered vegetation count correct",
|
||||
"TestTag2 filtered vegetation count incorrect"
|
||||
)
|
||||
testTag2_excluded_vegetation_z_correct = (
|
||||
"TestTag2 filtered vegetation spawned in correct position",
|
||||
"TestTag2 filtered vegetation failed to spawn in correct position"
|
||||
)
|
||||
|
||||
testTag3_excluded_vegetation_count_correct = (
|
||||
"TestTag3 filtered vegetation count correct",
|
||||
"TestTag3 filtered vegetation count incorrect"
|
||||
)
|
||||
testTag3_excluded_vegetation_z_correct = (
|
||||
"TestTag3 filtered vegetation spawned in correct position",
|
||||
"TestTag3 filtered vegetation failed to spawn in correct position"
|
||||
)
|
||||
|
||||
cleared_exclusion_vegetation_count_correct = (
|
||||
"Cleared filter vegetation count correct",
|
||||
"Cleared filter vegetation count incorrect"
|
||||
)
|
||||
|
||||
def TerrainSystem_VegetationSpawnsOnTerrainSurfaces():
|
||||
"""
|
||||
Summary:
|
||||
Load an empty level,
|
||||
Create two entities with constant gradient components with different values.
|
||||
Create two entities with TerrainLayerSpawners
|
||||
Create an entity to spawn vegetation
|
||||
Ensure that vegetation spawns at the correct heights
|
||||
Add a VegetationSurfaceMaskFilter and ensure it responds correctly to surface changes.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import math as sys_math
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.math as math
|
||||
|
||||
import azlmbr.areasystem as areasystem
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.vegetation as vegetation
|
||||
import azlmbr.terrain as terrain
|
||||
import azlmbr.entity as EntityId
|
||||
import azlmbr.surface_data as surface_data
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def create_entity_at(entity_name, components_to_add, x, y, z):
|
||||
entity = hydra.Entity(entity_name)
|
||||
entity.create_entity(math.Vector3(x, y, z), components_to_add)
|
||||
|
||||
return entity
|
||||
|
||||
def FindHighestAndLowestZValuesInArea(aabb):
|
||||
vegetation_items = areasystem.AreaSystemRequestBus(bus.Broadcast, 'GetInstancesInAabb', aabb)
|
||||
|
||||
lowest_z = min([item.position.z for item in vegetation_items])
|
||||
highest_z = max([item.position.z for item in vegetation_items])
|
||||
|
||||
return highest_z, lowest_z
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# Open an empty level.
|
||||
helper.open_level("Physics", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
box_height = 20.0
|
||||
box_y_position = 10.0
|
||||
box_dimensions = math.Vector3(20.0, 20.0, box_height)
|
||||
|
||||
# Add Terrain Rendering
|
||||
hydra.add_level_component("Terrain World")
|
||||
hydra.add_level_component("Terrain World Renderer")
|
||||
|
||||
# Create two terrain entities at adjoining positions
|
||||
terrain_entity_1 = create_entity_at("Terrain1", ["Terrain Layer Spawner", "Axis Aligned Box Shape", "Terrain Height Gradient List", "Terrain Surface Gradient List"], 0.0, box_y_position, box_height/2.0)
|
||||
terrain_entity_1.get_set_test(1, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
|
||||
|
||||
terrain_entity_2 = create_entity_at("Terrain2", ["Terrain Layer Spawner", "Axis Aligned Box Shape", "Terrain Height Gradient List", "Terrain Surface Gradient List"], 20.0, box_y_position, box_height/2.0)
|
||||
terrain_entity_2.get_set_test(1, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
|
||||
|
||||
# Create two gradient entities.
|
||||
gradient_value_1 = 0.25
|
||||
gradient_value_2 = 0.5
|
||||
|
||||
gradient_entity_1 = create_entity_at("Gradient1", ["Constant Gradient"], 0.0, 0.0, 0.0)
|
||||
gradient_entity_1.get_set_test(0, "Configuration|Value", gradient_value_1)
|
||||
|
||||
gradient_entity_2 = create_entity_at("Gradient2", ["Constant Gradient"], 0.0, 0.0, 0.0)
|
||||
gradient_entity_2.get_set_test(0, "Configuration|Value", gradient_value_2)
|
||||
|
||||
mapping = terrain.TerrainSurfaceGradientMapping()
|
||||
mapping.gradientEntityId = gradient_entity_1.id
|
||||
pte = hydra.get_property_tree(terrain_entity_1.components[3])
|
||||
pte.add_container_item("Configuration|Gradient to Surface Mappings", 0, mapping)
|
||||
|
||||
mapping = terrain.TerrainSurfaceGradientMapping()
|
||||
mapping.gradientEntityId = gradient_entity_2.id
|
||||
pte = hydra.get_property_tree(terrain_entity_2.components[3])
|
||||
pte.add_container_item("Configuration|Gradient to Surface Mappings", 0, mapping)
|
||||
|
||||
# create a vegetation entity that overlaps both terrain entities.
|
||||
vegetation_entity = create_entity_at("Vegetation", ["Vegetation Layer Spawner", "Axis Aligned Box Shape", "Vegetation Asset List", "Vegetation Surface Mask Filter"], 10.0, box_y_position, box_height/2.0)
|
||||
vegetation_entity.get_set_test(1, "Axis Aligned Box Shape|Box Configuration|Dimensions", box_dimensions)
|
||||
|
||||
# Set the vegetation area to a PrefabInstanceSpawner with a specific prefab asset selected.
|
||||
prefab_spawner = vegetation.PrefabInstanceSpawner()
|
||||
prefab_spawner.SetPrefabAssetPath(os.path.join("Prefabs", "PinkFlower.spawnable"))
|
||||
descriptor = hydra.get_component_property_value(vegetation_entity.components[2], 'Configuration|Embedded Assets|[0]')
|
||||
descriptor.spawner = prefab_spawner
|
||||
vegetation_entity.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor)
|
||||
|
||||
# Assign gradients to layer spawners.
|
||||
terrain_entity_1.get_set_test(2, "Configuration|Gradient Entities", [gradient_entity_1.id])
|
||||
terrain_entity_2.get_set_test(2, "Configuration|Gradient Entities", [gradient_entity_2.id])
|
||||
|
||||
# Move view so that the entities are visible.
|
||||
general.set_current_view_position(17.0, -66.0, 41.0)
|
||||
general.set_current_view_rotation(-15, 0, 0)
|
||||
|
||||
# Expected item counts under conditions to be tested.
|
||||
# By default, vegetation spawns at a density of 20 items per 16 meters,
|
||||
# so in a 20m square, there should be around 25 ^ 2 items depending on whether area edges are included.
|
||||
# In this case there are 26 ^ 2 items.
|
||||
expected_surface_tag_excluded_item_count = 338
|
||||
expected_no_exclusions_item_count = 676
|
||||
|
||||
# Wait for the vegetation to spawn
|
||||
helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_no_exclusions_item_count, 5.0)
|
||||
|
||||
# Check the spawn count is correct.
|
||||
item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
|
||||
Report.result(VegetationTests.unfiltered_vegetation_count_correct, item_count == expected_no_exclusions_item_count)
|
||||
|
||||
test_aabb = math.Aabb_CreateFromMinMax(math.Vector3(-10.0, -10.0, 0.0), math.Vector3(30.0, 10.0, box_height))
|
||||
|
||||
# Find the z positions of the items with the lowest and highest x values, this will avoid the overlap area where z values are blended between the surface heights.
|
||||
highest_z, lowest_z = FindHighestAndLowestZValuesInArea(test_aabb)
|
||||
|
||||
# Check that the z values are as expected.
|
||||
Report.result(VegetationTests.vegetation_on_gradient_1, sys_math.isclose(lowest_z, box_height * gradient_value_1, abs_tol=0.01))
|
||||
Report.result(VegetationTests.vegetation_on_gradient_2, sys_math.isclose(highest_z, box_height * gradient_value_2, abs_tol=0.01))
|
||||
|
||||
# Assign SurfaceTags to the SurfaceGradientLists
|
||||
terrain_entity_1.get_set_test(3, "Configuration|Gradient to Surface Mappings|[0]|Surface Tag", surface_data.SurfaceTag("test_tag2"))
|
||||
terrain_entity_2.get_set_test(3, "Configuration|Gradient to Surface Mappings|[0]|Surface Tag", surface_data.SurfaceTag("test_tag3"))
|
||||
|
||||
# Give the VegetationSurfaceFilter an exclusion list, set it to exclude test_tag2 which should remove all the lower items which are in terrain_entity_1.
|
||||
vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags", [surface_data.SurfaceTag()])
|
||||
vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags|[0]", surface_data.SurfaceTag("test_tag2"))
|
||||
|
||||
# Wait for the vegetation to respawn and check z values.
|
||||
helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_surface_tag_excluded_item_count, 5.0)
|
||||
|
||||
item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
|
||||
Report.result(VegetationTests.testTag2_excluded_vegetation_count_correct, item_count == expected_surface_tag_excluded_item_count)
|
||||
|
||||
highest_z, lowest_z = FindHighestAndLowestZValuesInArea(test_aabb)
|
||||
|
||||
Report.result(VegetationTests.testTag2_excluded_vegetation_z_correct, lowest_z > box_height * gradient_value_1)
|
||||
|
||||
# Clear the filter and ensure vegetation respawns.
|
||||
vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags|[0]", surface_data.SurfaceTag("invalid"))
|
||||
helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_no_exclusions_item_count, 5.0)
|
||||
|
||||
item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
|
||||
Report.result(VegetationTests.cleared_exclusion_vegetation_count_correct, item_count == expected_no_exclusions_item_count)
|
||||
|
||||
# Exclude test_tag3 to exclude the higher items in terrain_entity_2 and recheck.
|
||||
vegetation_entity.get_set_test(3, "Configuration|Exclusion|Surface Tags|[0]", surface_data.SurfaceTag("test_tag3"))
|
||||
|
||||
helper.wait_for_condition(lambda: vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id) == expected_surface_tag_excluded_item_count, 5.0)
|
||||
|
||||
item_count = vegetation.VegetationSpawnerRequestBus(bus.Event, "GetAreaProductCount", vegetation_entity.id)
|
||||
Report.result(VegetationTests.testTag3_excluded_vegetation_count_correct, item_count == expected_surface_tag_excluded_item_count)
|
||||
|
||||
highest_z, lowest_z = FindHighestAndLowestZValuesInArea(test_aabb)
|
||||
|
||||
Report.result(VegetationTests.testTag3_excluded_vegetation_z_correct, highest_z < box_height * gradient_value_2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(TerrainSystem_VegetationSpawnsOnTerrainSurfaces)
|
||||
@@ -72,7 +72,7 @@ def Terrain_SupportsPhysics():
|
||||
|
||||
# 2) Create 2 test entities, one parent at 512.0, 512.0, 50.0 and one child at the default position and add the required components
|
||||
entity1_components_to_add = ["Axis Aligned Box Shape", "Terrain Layer Spawner", "Terrain Height Gradient List", "Terrain Physics Heightfield Collider", "PhysX Heightfield Collider"]
|
||||
entity2_components_to_add = ["Vegetation Reference Shape", "Gradient Transform Modifier", "FastNoise Gradient"]
|
||||
entity2_components_to_add = ["Shape Reference", "Gradient Transform Modifier", "FastNoise Gradient"]
|
||||
ball_components_to_add = ["Sphere Shape", "PhysX Collider", "PhysX Rigid Body"]
|
||||
terrain_spawner_entity = hydra.Entity("TestEntity1")
|
||||
terrain_spawner_entity.create_entity(azmath.Vector3(512.0, 512.0, 50.0), entity1_components_to_add)
|
||||
|
||||
@@ -28,5 +28,11 @@ class TestAutomation(EditorTestSuite):
|
||||
class test_Terrain_SupportsPhysics(EditorSharedTest):
|
||||
from .EditorScripts import Terrain_SupportsPhysics as test_module
|
||||
|
||||
class test_TerrainHeightGradientList_AddRemoveGradientWorks(EditorSharedTest):
|
||||
from .EditorScripts import TerrainHeightGradientList_AddRemoveGradientWorks as test_module
|
||||
|
||||
class test_TerrainSystem_VegetationSpawnsOnTerrainSurfaces(EditorSharedTest):
|
||||
from .EditorScripts import TerrainSystem_VegetationSpawnsOnTerrainSurfaces as test_module
|
||||
|
||||
class test_TerrainMacroMaterialComponent_MacroMaterialActivates(EditorSharedTest):
|
||||
from .EditorScripts import TerrainMacroMaterialComponent_MacroMaterialActivates as test_module
|
||||
from .EditorScripts import TerrainMacroMaterialComponent_MacroMaterialActivates as test_module
|
||||
|
||||
+8
-5
@@ -183,23 +183,26 @@ def ap_missing_dependency_fixture(request, workspace, ap_setup_fixture) -> Any:
|
||||
:return: None
|
||||
"""
|
||||
logger.info(f"Searching output for expected dependencies for product {product}")
|
||||
sorted_expected = sorted(expected_dependencies)
|
||||
# Check dependencies found either in the log or console output
|
||||
for product_name, missing_deps in self.extract_missing_dependencies_from_output(log_output).items():
|
||||
if product in product_name:
|
||||
sorted_missing = sorted(missing_deps)
|
||||
# fmt:off
|
||||
assert sorted(missing_deps) == sorted(expected_dependencies), \
|
||||
assert sorted_expected == sorted_missing, \
|
||||
f"Missing dependencies for '{product_name}' did not match expected. Expected: " \
|
||||
f"{expected_dependencies}, Actual: {missing_deps}"
|
||||
f"{sorted_expected}, Actual: {sorted_missing}"
|
||||
# fmt:on
|
||||
|
||||
# Check dependencies found in Database
|
||||
for product_name, missing_deps in self.extract_missing_dependencies_from_database(product,
|
||||
platforms).items():
|
||||
if product.replace("\\", "/") in product_name:
|
||||
sorted_missing = sorted(missing_deps)
|
||||
# fmt:off
|
||||
assert sorted(expected_dependencies) == sorted(missing_deps), \
|
||||
f"Product '{product_name}' expected missing dependencies: {expected_dependencies}; " \
|
||||
f"actual missing dependencies {missing_deps}"
|
||||
assert sorted_expected == sorted_missing, \
|
||||
f"Product '{product_name}' expected missing dependencies: {sorted_expected}; " \
|
||||
f"actual missing dependencies {sorted_missing}"
|
||||
# fmt:on
|
||||
|
||||
def __getitem__(self, item: str) -> object:
|
||||
|
||||
@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
A fixture for Setting Up Asset Processor Batch workspace for tests in lmbr_test
|
||||
A fixture for Setting Up Asset Processor Batch workspace for tests
|
||||
"""
|
||||
|
||||
# Import builtin libraries
|
||||
|
||||
+5
-1
@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
A fixture for using the Asset Processor in lmbr_test, this will stop the asset processor after every test via
|
||||
A fixture for using the Asset Processor, this will stop the asset processor after every test via
|
||||
the teardown. Using the fixture at class level will stop the asset processor after the suite completes.
|
||||
Using the fixture at test level will stop asset processor after the test completes. Calling this fixture as a test argument will still run the teardown to stop the Asset Processor.
|
||||
"""
|
||||
@@ -15,6 +15,7 @@ import logging
|
||||
|
||||
# Import LyTestTools
|
||||
import ly_test_tools.o3de.asset_processor as asset_processor_commands
|
||||
import ly_test_tools.o3de.asset_processor_utils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -36,5 +37,8 @@ def asset_processor(request: pytest.fixture, workspace: pytest.fixture) -> asset
|
||||
ap.stop()
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
for n in ly_test_tools.o3de.asset_processor_utils.processList:
|
||||
assert not ly_test_tools.o3de.asset_processor_utils.check_ap_running(n), f"{n} process did not shutdown correctly."
|
||||
|
||||
|
||||
return ap
|
||||
|
||||
@@ -103,6 +103,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AZ::AssetBundlerBatch
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.BundleMode
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::AssetBundlerBatch
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.AssetBuilder
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py
|
||||
|
||||
+10
@@ -8,6 +8,8 @@ General Asset Processor Batch Tests
|
||||
"""
|
||||
|
||||
# Import builtin libraries
|
||||
from os import listdir
|
||||
|
||||
import pytest
|
||||
import logging
|
||||
import os
|
||||
@@ -724,3 +726,11 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
|
||||
|
||||
assert error_line_found, "The error could not be found in the newest run of the AP Batch log."
|
||||
|
||||
@pytest.mark.assetpipeline
|
||||
def test_AssetProcessor_Log_On_Failure(self, asset_processor, ap_setup_fixture, workspace):
|
||||
asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "test_AP_Logs")
|
||||
result, output = asset_processor.batch_process(expect_failure=True, capture_output=True)
|
||||
assert result == False, f'AssetProcessorBatch should have failed because there is a bad asset, output was {output}'
|
||||
|
||||
jobLogs = listdir(workspace.paths.ap_job_logs() + "/test_AP_Logs")
|
||||
assert not len(jobLogs) == 0, 'No job logs where output during failure.'
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c6b33c6137d6bd8c696f180c30a23089c95c1af398a630b4b13e080bec3254d
|
||||
size 18220
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
import azlmbr.bus
|
||||
import azlmbr.editor
|
||||
import azlmbr.legacy.general
|
||||
import sys
|
||||
|
||||
# Print out the passed in bundle_path, so the outer test can verify this was sent in correctly
|
||||
bundle_path = sys.argv[1]
|
||||
print('Bundle mode test running with path {}'.format(sys.argv[1]))
|
||||
|
||||
# Turn on bundle mode. This will trigger some printouts that the outer test logic will validate.
|
||||
azlmbr.legacy.general.set_cvar_integer("sys_report_files_not_found_in_paks", 1)
|
||||
azlmbr.legacy.general.run_console(f"loadbundles {bundle_path}")
|
||||
|
||||
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
pytest.importorskip('ly_test_tools')
|
||||
|
||||
import ly_test_tools.environment.file_system as fs
|
||||
import ly_test_tools.environment.waiter as waiter
|
||||
import ly_test_tools.log.log_monitor
|
||||
|
||||
from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
|
||||
from ..ap_fixtures.bundler_batch_setup_fixture import bundler_batch_setup_fixture as bundler_batch_helper
|
||||
from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
|
||||
@pytest.mark.parametrize('project', ['AutomatedTesting'])
|
||||
@pytest.mark.parametrize('level', ['auto_test'])
|
||||
class TestBundleMode(object):
|
||||
def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform,
|
||||
asset_processor, workspace, bundler_batch_helper):
|
||||
level_pak = os.path.join("levels", level, "level.pak")
|
||||
|
||||
bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
|
||||
bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
|
||||
bundle_result_path = os.path.join(bundles_folder,
|
||||
bundler_batch_helper.platform_file_name(
|
||||
"bundle.pak", workspace.asset_processor_platform))
|
||||
|
||||
# Create target 'Bundles' folder if it doesn't exist
|
||||
if not os.path.exists(bundles_folder):
|
||||
os.mkdir(bundles_folder)
|
||||
# Delete target bundle file if it already exists
|
||||
if os.path.exists(bundle_result_path):
|
||||
fs.delete([bundle_result_path], True, False)
|
||||
|
||||
# Make asset list file to use in the bundle
|
||||
bundler_batch_helper.call_assetLists(
|
||||
addSeed=level_pak,
|
||||
assetListFile=bundler_batch_helper["asset_info_file_request"],
|
||||
)
|
||||
|
||||
# Make bundle in <project_folder>/Bundles
|
||||
bundler_batch_helper.call_bundles(
|
||||
assetListFile=bundler_batch_helper["asset_info_file_result"],
|
||||
outputBundlePath=bundle_request_path,
|
||||
maxSize="2048",
|
||||
)
|
||||
|
||||
# Ensure the bundle was created
|
||||
assert os.path.exists(bundle_result_path), f"Bundle was not created at location: {bundle_result_path}"
|
||||
|
||||
# The editor flips the slash direction in some of the printouts
|
||||
bundle_result_path_editor_separator = bundle_result_path.replace('\\', '/')
|
||||
|
||||
expected_lines = [
|
||||
# A beginning of test printout can help debug where failures occur, if this line is missing
|
||||
# then the Editor didn't launch, didn't run the Python test, or didn't pass in the right parameter
|
||||
f'Bundle mode test running with path {bundles_folder}',
|
||||
# These printouts happen in response to the loadbundles call, and verify this bundle is actually loaded
|
||||
f"[CONSOLE] Executing console command 'loadbundles {bundles_folder}'",
|
||||
f'(BundlingSystem) - Loading bundles from {bundles_folder} of type .pak',
|
||||
f'(Archive) - Opening archive file {bundle_result_path_editor_separator}',
|
||||
]
|
||||
unexpected_lines = []
|
||||
|
||||
timeout = 180
|
||||
halt_on_unexpected = False
|
||||
test_directory = os.path.join(os.path.dirname(__file__))
|
||||
test_file = os.path.join(test_directory, 'bundle_mode_in_editor_tests.py')
|
||||
editor.args.extend(['-NullRenderer', '-rhi=Null', "--skipWelcomeScreenDialog",
|
||||
"--autotest_mode", "--runpythontest", test_file, "--runpythonargs", bundles_folder])
|
||||
|
||||
with editor.start(launch_ap=True):
|
||||
editor_log_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
|
||||
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editor_log_file)
|
||||
waiter.wait_for(
|
||||
lambda: editor.is_alive(),
|
||||
timeout,
|
||||
exc=("Log file '{}' was never opened by another process.".format(editor_log_file)),
|
||||
interval=1)
|
||||
log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout)
|
||||
|
||||
# Delete the bundle created and used in this test
|
||||
fs.delete([bundle_result_path], True, False)
|
||||
+43
-41
@@ -120,31 +120,29 @@ class TestsMissingDependencies_WindowsAndMac(object):
|
||||
|
||||
# Relative path to the txt file with missing dependencies
|
||||
expected_product = f"testassets\\validuuidsnotdependency.txt"
|
||||
self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Objects\\LumberTank")
|
||||
self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Objects\\Characters\\Jack")
|
||||
# Expected missing dependencies
|
||||
expected_dependencies = [
|
||||
# String Asset #
|
||||
('1CB10C43F3245B93A294C602ADEF95F9:[0', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'),
|
||||
# InvalidAssetIdNoReport.txt
|
||||
('E68A85B0-131D-5A82-B2D5-BC58EE4062AE', '{E68A85B0-131D-5A82-B2D5-BC58EE4062AE}:0'),
|
||||
# InvalidRelativePathsNoReport.txt
|
||||
('B3EF12DD306C520EB0A8A6B0D031A195', '{B3EF12DD-306C-520E-B0A8-A6B0D031A195}:0'),
|
||||
# SelfReferenceUUID.txt
|
||||
('33bcee02F3225688ABEE534F6058593F', '{33BCEE02-F322-5688-ABEE-534F6058593F}:0'),
|
||||
('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3e8'),
|
||||
('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3ea'),
|
||||
('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3eb'),
|
||||
('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3e8'),
|
||||
('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3ea'),
|
||||
('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3eb'),
|
||||
('6BDE282B49C957F7B0714B26579BCA9A', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'),
|
||||
('747D31D71E62553592226173C49CF97E', '{747D31D7-1E62-5535-9222-6173C49CF97E}:1'),
|
||||
('747D31D71E62553592226173C49CF97E', '{747D31D7-1E62-5535-9222-6173C49CF97E}:2'),
|
||||
('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3e8'),
|
||||
('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3ea'),
|
||||
('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3eb'),
|
||||
('B076CDDC-14DF-50F4-A5E9-7518ABB3E851', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'),
|
||||
('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3e8'),
|
||||
('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3ea'),
|
||||
('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3eb'),
|
||||
('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3ec'),
|
||||
('D92C4661C8985E19BD3597CB2318CFA6:[0', '{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0'),
|
||||
# SelfReferencePath.txt
|
||||
('DD587FBE-16C8-5B98-AE3C-A9F8750B2692', '{DD587FBE-16C8-5B98-AE3C-A9F8750B2692}:0'),
|
||||
# InvalidUUIDNoReport.txt
|
||||
('837412DF-D05F-576D-81AA-ACF360463749', '{837412DF-D05F-576D-81AA-ACF360463749}:0'),
|
||||
# MaxIteration31Deep.txt
|
||||
('3F642A0FDC825696A70A1DA5709744DF', '{3F642A0F-DC82-5696-A70A-1DA5709744DF}:0'),
|
||||
# OnlyMatchesCorrectLengthUUIDs.txt
|
||||
('2545AD8B-1B9B-5F93-859D-D8DC1DC2B480', '{2545AD8B-1B9B-5F93-859D-D8DC1DC2B480}:0'),
|
||||
# WildcardScanTest1.txt
|
||||
('1CB10C43F3245B93A294C602ADEF95F9:[0', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'),
|
||||
# RelativeProductPathsNotDependencies.txt
|
||||
('B772953CA08A5D209491530E87D11504:[0', '{B772953C-A08A-5D20-9491-530E87D11504}:0'),
|
||||
# WildcardScanTest2.txt
|
||||
('D92C4661C8985E19BD3597CB2318CFA6', '{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0'),
|
||||
]
|
||||
self.do_missing_dependency_test(expected_product, expected_dependencies,
|
||||
"%ValidUUIDsNotDependency.txt")
|
||||
@@ -187,8 +185,11 @@ class TestsMissingDependencies_WindowsAndMac(object):
|
||||
# Expected missing dependencies
|
||||
expected_dependencies = [
|
||||
# String Asset #
|
||||
('2ef92b8D044E5C278E2BB1AC0374A4E7:1003', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3eb'),
|
||||
# _dev_Red.tif
|
||||
('2ef92b8D044E5C278E2BB1AC0374A4E7:1000', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3e8'),
|
||||
# _dev_Purple.tif
|
||||
('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
|
||||
# _dev_White.tif
|
||||
('D83B36F1-61A6-5001-B191-4D0CE282E236}-1002', '{D83B36F1-61A6-5001-B191-4D0CE282E236}:3ea'),
|
||||
]
|
||||
|
||||
@@ -237,11 +238,10 @@ class TestsMissingDependencies_WindowsAndMac(object):
|
||||
expected_dependencies = [
|
||||
# String Asset #
|
||||
('TestAssets\\WildcardScanTest1.txt', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'),
|
||||
('libs/particles/milestone2PARTICLES.XML', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'),
|
||||
('TESTASSETS/ReportONEmISSINGdEPENDENCY.tXT', '{BE5E2373-245E-59E4-B4C6-7370EEAA2EFD}:0'),
|
||||
('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3e8'),
|
||||
('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
|
||||
('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3eb'),
|
||||
('project.json', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'),
|
||||
('TestAssets/InvalidAssetIdNoReport.txt', '{E68A85B0-131D-5A82-B2D5-BC58EE4062AE}:0'),
|
||||
('TestAssets/RelativeProductPathsNotDependencies.txt', '{B772953C-A08A-5D20-9491-530E87D11504}:0'),
|
||||
]
|
||||
|
||||
@@ -282,29 +282,31 @@ class TestsMissingDependencies_WindowsAndMac(object):
|
||||
2. Set the expected missing dependencies
|
||||
3. Execute test
|
||||
"""
|
||||
|
||||
self._asset_processor.add_source_folder_assets(f"Gems\\LyShineExamples\\Assets\\UI\\Fonts\\LyShineExamples")
|
||||
self._asset_processor.add_scan_folder(f"Gems\\LyShineExamples\\Assets")
|
||||
# Relative path to the txt file with missing dependencies as product paths
|
||||
expected_product = f"testassets\\relativeproductpathsnotdependencies.txt"
|
||||
expected_dependencies = [
|
||||
# String Asset #
|
||||
('materials/floor_tile.mtl', '{0EFF5E4A-F544-5D87-8696-6DDFA62D6063}:0'),
|
||||
('materials/am_grass1.mtl', '{1151F14D-38A6-5579-888A-BE3139882E68}:0'),
|
||||
('2ef92b8D044E5C278E2BB1AC0374A4E7:1002', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3ea'),
|
||||
('textures/milestone2/ama_grey_02.tif.streamingimage', '{3EE80AAD-EB9C-56BD-9E9C-65410578998C}:3e8'),
|
||||
('ui/milestone2menu.uicanvas', '{445D9AF3-6CA5-5281-82A9-5C570BCD1DB8}:0'),
|
||||
('libs/particles/milestone2particles.xml', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'),
|
||||
('textures/_dev_yellow_light.tif.1002.imagemipchain', '{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:3ea'),
|
||||
('textures\\\\_dev_tan.tif.streamingimage', '{8F2BCEF5-C8CE-5B80-8103-8C1D694D012C}:3e8'),
|
||||
('materials/am_rockground.mtl', '{A1DA3D05-A020-5BB5-A608-C4812B7BD733}:0'),
|
||||
('textures/_dev_purple.tif.streamingimage', '{A2482826-053D-5634-A27B-084B1326AAE5}:3e8'),
|
||||
('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
|
||||
('project.json', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'),
|
||||
('CEAA362B4E505BCEB827CB92EF40A50E', '{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:1'),
|
||||
('CEAA362B4E505BCEB827CB92EF40A50E', '{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:2'),
|
||||
('textures\\_dev_stucco.tif.streamingimage', '{70114D85-D712-5AEB-A816-8FE3A37087AF}:3e8'),
|
||||
('textures\\\\_dev_tan.tif.streamingimage', '{8F2BCEF5-C8CE-5B80-8103-8C1D694D012C}:3e8'),
|
||||
('TEXTURES/_DEV_WHITE.tif.streamingimage', '{D83B36F1-61A6-5001-B191-4D0CE282E236}:3e8'),
|
||||
('textures/_dev_yellow_light.tif.1002.imagemipchain', '{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:3ea'),
|
||||
('textures/_dev_woodland.tif.1002.imagemipchain', '{F3DD193C-5845-569C-A974-AA338B30CF86}:3ea'),
|
||||
('textures/_dev_woodland.tif.streamingimage', '{F3DD193C-5845-569C-A974-AA338B30CF86}:3e8'),
|
||||
('textures/_dev_yellow_light.tif.streamingimage', '{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:3e8'),
|
||||
('textures/_dev_yellow_med.tif.1002.imagemipchain', '{BB4DFF57-52BD-525B-9628-68232E31802C}:3ea'),
|
||||
('textures/lights/flare01.tif.streamingimage', '{D8E49CC4-C743-5F31-A1EC-4AA89163B8F5}:3e8'),
|
||||
# SelfReferenceUUID.txt
|
||||
('33BCEE02-F322-5688-ABEE-534F6058593F', '{33BCEE02-F322-5688-ABEE-534F6058593F}:0'),
|
||||
('textures/test_texture_sequence/test_texture_sequence000.png.streamingimage', '{6CC90BEE-0A9F-57A8-9013-7C1D643C0E8E}:3e8'),
|
||||
# _dev_red.tif.streamingimage
|
||||
('2ef92b8D044E5C278E2BB1AC0374A4E7:1002', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3ea'),
|
||||
# SelfReferenceAssetID.txt
|
||||
('785A05D2-483E-5B43-A2B9-92ACDAE6E938', '{785A05D2-483E-5B43-A2B9-92ACDAE6E938}:0'),
|
||||
('textures/test_texture_sequence/test_texture_sequence001.png.streamingimage', '{8A8A37DD-01B9-5D70-92E4-925E2C0FE826}:3e8'),
|
||||
# _dev_purple.tif.1002.imagemipchain
|
||||
('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'),
|
||||
('textures/_dev_purple_glass.tif.1002.imagemipchain', '{2FCDD831-77D1-5BE1-A4C8-CA47E4F89F19}:3ea'),
|
||||
]
|
||||
|
||||
self.do_missing_dependency_test(expected_product, expected_dependencies,
|
||||
|
||||
@@ -8,7 +8,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
import os
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
import pytest
|
||||
import time
|
||||
|
||||
@@ -128,7 +128,8 @@ class TestAutomationBase:
|
||||
errors.append(TestRunError("FAILED TEST", error_str))
|
||||
if return_code and return_code != TestAutomationBase.TEST_FAIL_RETCODE: # Crashed
|
||||
crash_info = "-- No crash log available --"
|
||||
crash_log = os.path.join(workspace.paths.project_log(), 'error.log')
|
||||
crash_log = workspace.paths.crash_log()
|
||||
|
||||
try:
|
||||
waiter.wait_for(lambda: os.path.exists(crash_log), timeout=TestAutomationBase.WAIT_FOR_CRASH_LOG)
|
||||
except AssertionError:
|
||||
|
||||
@@ -7,60 +7,6 @@
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorTests_Main
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
PYTEST_MARKS "not REQUIRES_gpu"
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Editor
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorTests_Main_GPU
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
TEST_REQUIRES gpu
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
PYTEST_MARKS "REQUIRES_gpu"
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Editor
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorTests_Periodic
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Editor
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorTests_Sandbox
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Editor
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorTests_Main_Optimized
|
||||
|
||||
@@ -49,7 +49,6 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
|
||||
from .EditorScripts import AssetPicker_UI_UX as test_module
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
|
||||
@@ -11,24 +11,10 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
## DynVeg ##
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationTests_Main
|
||||
NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized
|
||||
TEST_SERIAL
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic.py
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -37,7 +23,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized
|
||||
TEST_SERIAL
|
||||
@@ -52,20 +37,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized
|
||||
TEST_SERIAL
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Main_Optimized.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
AutomatedTesting.GameLauncher
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
## LandscapeCanvas ##
|
||||
|
||||
ly_add_pytest(
|
||||
|
||||
+2
-2
@@ -72,9 +72,9 @@ def DynamicSliceInstanceSpawner_Embedded_E2E():
|
||||
# 1) Create a new, temporary level
|
||||
lvl_name = "tmp_level"
|
||||
helper.init_idle()
|
||||
level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False)
|
||||
level_created = helper.create_level(lvl_name)
|
||||
general.idle_wait(1.0)
|
||||
Report.critical_result(Tests.level_created, level_created == 0)
|
||||
Report.critical_result(Tests.level_created, level_created)
|
||||
general.set_current_view_position(512.0, 480.0, 38.0)
|
||||
|
||||
# 2) Create a new entity with required vegetation area components and Script Canvas component for launcher test
|
||||
|
||||
+2
-2
@@ -73,9 +73,9 @@ def DynamicSliceInstanceSpawner_External_E2E():
|
||||
# 1) Create a new, temporary level
|
||||
lvl_name = "tmp_level"
|
||||
helper.init_idle()
|
||||
level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False)
|
||||
level_created = helper.create_level(lvl_name)
|
||||
general.idle_wait(1.0)
|
||||
Report.critical_result(Tests.level_created, level_created == 0)
|
||||
Report.critical_result(Tests.level_created, level_created)
|
||||
general.set_current_view_position(512.0, 480.0, 38.0)
|
||||
|
||||
# 2) Create a new entity with required vegetation area components and switch the Vegetation Asset List Source
|
||||
|
||||
+2
-2
@@ -76,9 +76,9 @@ def LayerBlender_E2E_Editor():
|
||||
# 1) Create a new, temporary level
|
||||
lvl_name = "tmp_level"
|
||||
helper.init_idle()
|
||||
level_created = general.create_level_no_prompt(lvl_name, 1024, 1, 4096, False)
|
||||
level_created = helper.create_level(lvl_name)
|
||||
general.idle_wait(1.0)
|
||||
Report.critical_result(Tests.level_created, level_created == 0)
|
||||
Report.critical_result(Tests.level_created, level_created)
|
||||
|
||||
general.set_current_view_position(500.49, 498.69, 46.66)
|
||||
general.set_current_view_rotation(-42.05, 0.00, -36.33)
|
||||
|
||||
+2
-2
@@ -78,7 +78,7 @@ def LayerSpawner_InheritBehaviorFlag():
|
||||
# Create Vegetation area and assign a valid asset
|
||||
veg_1 = hydra.Entity("veg_1")
|
||||
veg_1.create_entity(
|
||||
position, ["Vegetation Layer Spawner", "Vegetation Reference Shape", "Vegetation Asset List"]
|
||||
position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
|
||||
)
|
||||
set_dynamic_slice_asset(veg_1, 2, os.path.join("Slices", "PinkFlower.dynamicslice"))
|
||||
veg_1.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
|
||||
@@ -86,7 +86,7 @@ def LayerSpawner_InheritBehaviorFlag():
|
||||
# Create second vegetation area and assign a valid asset
|
||||
veg_2 = hydra.Entity("veg_2")
|
||||
veg_2.create_entity(
|
||||
position, ["Vegetation Layer Spawner", "Vegetation Reference Shape", "Vegetation Asset List"]
|
||||
position, ["Vegetation Layer Spawner", "Shape Reference", "Vegetation Asset List"]
|
||||
)
|
||||
set_dynamic_slice_asset(veg_2, 2, os.path.join("Slices", "PurpleFlower.dynamicslice"))
|
||||
veg_2.get_set_test(1, "Configuration|Shape Entity Id", blender_entity.id)
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
def LayerSpawner_InstancesPlantInAllSupportedShapes():
|
||||
"""
|
||||
Summary:
|
||||
The level is loaded and vegetation area is created. Then the Vegetation Reference Shape
|
||||
The level is loaded and vegetation area is created. Then the Shape Reference
|
||||
component of vegetation area is pinned with entities of different shape components to check
|
||||
if the vegetation plants in different shaped areas.
|
||||
|
||||
@@ -67,7 +67,7 @@ def LayerSpawner_InstancesPlantInAllSupportedShapes():
|
||||
10.0, 10.0, 10.0,
|
||||
asset_path)
|
||||
vegetation.remove_component("Box Shape")
|
||||
vegetation.add_component("Vegetation Reference Shape")
|
||||
vegetation.add_component("Shape Reference")
|
||||
|
||||
# Create surface for planting on
|
||||
dynveg.create_surface_entity("Surface Entity", entity_position, 60.0, 60.0, 1.0)
|
||||
|
||||
@@ -12,13 +12,23 @@ import ly_test_tools.environment.file_system as file_system
|
||||
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.")
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
enable_prefab_system = False
|
||||
|
||||
# Helpers for test asset cleanup
|
||||
def cleanup_test_level(self, workspace):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
|
||||
True, True)
|
||||
|
||||
def cleanup_test_slices(self, workspace):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
|
||||
"TestSlice_1.slice")], True, True)
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
|
||||
"TestSlice_2.slice")], True, True)
|
||||
|
||||
class test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(EditorParallelTest):
|
||||
from .EditorScripts import DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks as test_module
|
||||
@@ -38,10 +48,7 @@ class TestAutomation(EditorTestSuite):
|
||||
class test_SpawnerSlices_SliceCreationAndVisibilityToggleWorks(EditorSingleTest):
|
||||
# Custom teardown to remove slice asset created during test
|
||||
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
|
||||
"TestSlice_1.slice")], True, True)
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
|
||||
"TestSlice_2.slice")], True, True)
|
||||
TestAutomation.cleanup_test_slices(self, workspace)
|
||||
from .EditorScripts import SpawnerSlices_SliceCreationAndVisibilityToggleWorks as test_module
|
||||
|
||||
class test_AssetListCombiner_CombinedDescriptorsExpressInConfiguredArea(EditorParallelTest):
|
||||
@@ -152,23 +159,29 @@ class TestAutomation(EditorTestSuite):
|
||||
class test_DynamicSliceInstanceSpawner_Embedded_E2E_Editor(EditorSingleTest):
|
||||
from .EditorScripts import DynamicSliceInstanceSpawner_Embedded_E2E as test_module
|
||||
|
||||
# Custom teardown to remove test level created during test
|
||||
# Custom setup/teardown to remove test level created during test
|
||||
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
TestAutomation.cleanup_test_level(self, workspace)
|
||||
|
||||
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
|
||||
True, True)
|
||||
TestAutomation.cleanup_test_level(self, workspace)
|
||||
|
||||
class test_DynamicSliceInstanceSpawner_External_E2E_Editor(EditorSingleTest):
|
||||
from .EditorScripts import DynamicSliceInstanceSpawner_External_E2E as test_module
|
||||
|
||||
# Custom teardown to remove test level created during test
|
||||
# Custom setup/teardown to remove test level created during test
|
||||
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
TestAutomation.cleanup_test_level(self, workspace)
|
||||
|
||||
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
|
||||
True, True)
|
||||
|
||||
TestAutomation.cleanup_test_level(self, workspace)
|
||||
|
||||
class test_LayerBlender_E2E_Editor(EditorSingleTest):
|
||||
from .EditorScripts import LayerBlender_E2E_Editor as test_module
|
||||
|
||||
# Custom teardown to remove test level created during test
|
||||
# Custom setup/teardown to remove test level created during test
|
||||
def setup(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
TestAutomation.cleanup_test_level(self, workspace)
|
||||
|
||||
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "Levels", "tmp_level")],
|
||||
True, True)
|
||||
TestAutomation.cleanup_test_level(self, workspace)
|
||||
|
||||
+2
-2
@@ -96,7 +96,7 @@ def AreaNodes_DependentComponentsAdded():
|
||||
'SpawnerAreaNode': [
|
||||
'Vegetation Layer Spawner',
|
||||
'Vegetation Asset List',
|
||||
'Vegetation Reference Shape'
|
||||
'Shape Reference'
|
||||
],
|
||||
'MeshBlockerAreaNode': [
|
||||
'Vegetation Layer Blocker (Mesh)',
|
||||
@@ -104,7 +104,7 @@ def AreaNodes_DependentComponentsAdded():
|
||||
],
|
||||
'BlockerAreaNode': [
|
||||
'Vegetation Layer Blocker',
|
||||
'Vegetation Reference Shape'
|
||||
'Shape Reference'
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ def Edit_DisabledNodeDuplication():
|
||||
nodes = {
|
||||
'SpawnerAreaNode': 'Vegetation Asset List',
|
||||
'MeshBlockerAreaNode': 'Mesh',
|
||||
'BlockerAreaNode': 'Vegetation Reference Shape',
|
||||
'BlockerAreaNode': 'Shape Reference',
|
||||
'FastNoiseGradientNode': 'Gradient Transform Modifier',
|
||||
'ImageGradientNode': 'Gradient Transform Modifier',
|
||||
'PerlinNoiseGradientNode': 'Gradient Transform Modifier',
|
||||
|
||||
+2
-2
@@ -104,7 +104,7 @@ def GradientNodes_DependentComponentsAdded():
|
||||
# we will be checking for
|
||||
commonComponents = [
|
||||
'Gradient Transform Modifier',
|
||||
'Vegetation Reference Shape'
|
||||
'Shape Reference'
|
||||
]
|
||||
componentNames = []
|
||||
for name in gradients:
|
||||
@@ -114,7 +114,7 @@ def GradientNodes_DependentComponentsAdded():
|
||||
|
||||
# Create nodes for the gradients that have additional required dependencies and check if
|
||||
# the Entity created by adding the node has the appropriate Component and required
|
||||
# Gradient Transform Modifier and Vegetation Reference Shape components added automatically to it
|
||||
# Gradient Transform Modifier and Shape Reference components added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7e169277bca473325281d5fe043cffc9196bd3ef46f6bffbea6e0b5e3b7194a1
|
||||
size 62700
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"$type": "ScriptProcessorRule",
|
||||
"scriptFilename": "Editor/Scripts/auto_lod.py"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,24 +2,24 @@ These tests are mostly done with files that have a different extension between s
|
||||
The source scan is done first, and will catch files in the source path.
|
||||
Product path searching is resolved using "endsWith" logic.
|
||||
textures/_dev_purple.tif.streamingimage
|
||||
Back slashes, and project name in the path
|
||||
pc/textures/_dev_stucco.tif.streamingimage
|
||||
Back slashes
|
||||
textures\_dev_stucco.tif.streamingimage
|
||||
Double back slashes
|
||||
textures\\_dev_tan.tif.streamingimage
|
||||
Casing doesn't match
|
||||
TEXTURES/_DEV_WHITE.tif.streamingimage
|
||||
Some files have multiple extensions, this verifies that won't trip up the scanner.
|
||||
textures/_dev_yellow_light.tif.1002.imagemipchain
|
||||
Path inline textures/milestone2/ama_grey_02.tif.streamingimage test
|
||||
Path inline textures/_dev_woodland.tif.1002.imagemipchain test
|
||||
Path after=textures/_dev_woodland.tif.streamingimage equal sign
|
||||
|
||||
Multiple paths on one line
|
||||
Multiple materials/am_grass1.mtl paths materials/am_rockground.mtl on one line
|
||||
Path before a UUID
|
||||
Path materials/floor_tile.mtl before B92667DC-9F5B-5D72-A29D-99219DD9B691 a UUID
|
||||
Path before an asset ID
|
||||
Path ui/milestone2menu.uicanvas before an 2ef92b8D044E5C278E2BB1AC0374A4E7:1002 asset ID
|
||||
Path after a UUID
|
||||
Path after CEAA362B4E505BCEB827CB92EF40A50E a project.json UUID
|
||||
Path after an asset ID
|
||||
Path after {A2482826-053D-5634-A27B-084B1326AAE5}:[1002] an libs/particles/milestone2particles.xml asset ID
|
||||
Multiple textures/_dev_yellow_light.tif.streamingimage paths textures/_dev_yellow_med.tif.1002.imagemipchain on one line
|
||||
Path before a UUID for SelfReferenceUUID text file
|
||||
Path textures/lights/flare01.tif.streamingimage before 33BCEE02-F322-5688-ABEE-534F6058593F a UUID
|
||||
Path before an asset ID for _dev_red image
|
||||
Path textures/test_texture_sequence/test_texture_sequence000.png.streamingimage before an 2ef92b8D044E5C278E2BB1AC0374A4E7:1002 asset ID
|
||||
Path after a UUID for SelfReferenceAssetID text file
|
||||
Path after 785A05D2-483E-5B43-A2B9-92ACDAE6E938 a textures/test_texture_sequence/test_texture_sequence001.png.streamingimage UUID
|
||||
Path after an asset ID for _dev_purple image file
|
||||
Path after {A2482826-053D-5634-A27B-084B1326AAE5}:[1002] an textures/_dev_purple_glass.tif.1002.imagemipchain asset ID
|
||||
|
||||
@@ -3,6 +3,6 @@ TestAssets/RelativeProductPathsNotDependencies.txt
|
||||
Back slashes
|
||||
TestAssets\WildcardScanTest1.txt
|
||||
Casing doesn't match
|
||||
libs/particles/milestone2PARTICLES.XML
|
||||
Path inline project.json test
|
||||
TESTASSETS/ReportONEmISSINGdEPENDENCY.tXT
|
||||
Path inline TestAssets/InvalidAssetIdNoReport.txt test
|
||||
Path after=textures/_dev_Purple.tif equal sign
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
File extensions are separated from file names, so the missing dependency scanner doesn't find when scanning, and only finds the asset IDs in this file.
|
||||
|
||||
/textures /_dev_Purple . tif, the product ID is for one of the mips.
|
||||
{A2482826-053D-5634-A27B-084B1326AAE5}:[1002]
|
||||
_dev_Red . tif, another mip, different formatting.
|
||||
2ef92b8D044E5C278E2BB1AC0374A4E7:1003
|
||||
2ef92b8D044E5C278E2BB1AC0374A4E7:1000
|
||||
_dev_White.tif, {D83B36F1-61A6-5001-B191-4D0CE282E236}-1002 asset ID inline.
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
Paths are broken up to avoid having them show up as relative path results.
|
||||
All references are to other text files in this folder, extensions are omitted to make sure only UUID scanning finds these references.
|
||||
|
||||
This is the UUID for Materials / Default / AM_UV_v1_1K_source . png
|
||||
C67BEA9F-09FF-59AA-A7F0-A52B8F987508
|
||||
This is the UUID for libs / particles / milestone2particles . xml. This tests UUIDs without separators.
|
||||
6BDE282B49C957F7B0714B26579BCA9A
|
||||
This is the UUID for SelfReferenceUUID.txt. This tests UUIDs with mixed casing.
|
||||
This is the UUID for InvalidAssetIdNoReport
|
||||
E68A85B0-131D-5A82-B2D5-BC58EE4062AE
|
||||
This is the UUID for InvalidRelativePathsNoReport. This tests UUIDs without separators.
|
||||
B3EF12DD306C520EB0A8A6B0D031A195
|
||||
This is the UUID for SelfReferenceUUID. This tests UUIDs with mixed casing.
|
||||
33bcee02F3225688ABEE534F6058593F
|
||||
This is a UUID mid-line B076CDDC-14DF-50F4-A5E9-7518ABB3E851, for project . json
|
||||
This is a UUID mid-line DD587FBE-16C8-5B98-AE3C-A9F8750B2692, for SelfReferencePath
|
||||
|
||||
Two UUIDs on the same line
|
||||
Two UUIDs 345E5C660D6254FF8D0F7C8EE66A2249 mixed on A26C73D1837E5AE59E68F916FA7C3699 the same line
|
||||
InvalidUUIDNoReport and MaxIteration31Deep
|
||||
Two UUIDs 837412DF-D05F-576D-81AA-ACF360463749 mixed on 3F642A0FDC825696A70A1DA5709744DF the same line
|
||||
|
||||
Test UUIDs and Asset IDs mixed on the same line. Relative paths are handled in the relative path tests.
|
||||
UUID: slices / MuzzleFlash . slice, AssetID: TestsAssets / WildcardScanTest1 . txt
|
||||
This 747D31D71E62553592226173C49CF97E uuid is on the line with 1CB10C43F3245B93A294C602ADEF95F9:[0] a valid asset ID
|
||||
UUID: Objects / Lumbertank_turret . cgf, AssetID: TestsAssets / WildcardScanTest2 . txt
|
||||
This D92C4661C8985E19BD3597CB2318CFA6:[0] uuid is on the line with 37108522F50459499CD6C8D47A960CF1 a valid asset ID
|
||||
OnlyMatchesCorrectLengthUUIDs and WildcardScanTest1
|
||||
This 2545AD8B-1B9B-5F93-859D-D8DC1DC2B480 uuid is on the line with 1CB10C43F3245B93A294C602ADEF95F9:[0] a valid asset ID
|
||||
RelativeProductPathsNotDependencies and WildcardScanTest2
|
||||
This B772953CA08A5D209491530E87D11504:[0] uuid is on the line with D92C4661C8985E19BD3597CB2318CFA6 a valid asset ID
|
||||
|
||||
@@ -14,66 +14,6 @@
|
||||
#include "Include/IBaseLibraryManager.h"
|
||||
#include <Util/PathUtil.h>
|
||||
#include <IFileUtil.h>
|
||||
#include "Undo/IUndoObject.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Undo functionality for libraries.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CUndoBaseLibrary
|
||||
: public IUndoObject
|
||||
{
|
||||
public:
|
||||
CUndoBaseLibrary(CBaseLibrary* pLib, const QString& description, const QString& selectedItem = QString())
|
||||
: m_pLib(pLib)
|
||||
, m_description(description)
|
||||
, m_redo(nullptr)
|
||||
, m_selectedItem(selectedItem)
|
||||
{
|
||||
assert(m_pLib);
|
||||
|
||||
m_undo = GetIEditor()->GetSystem()->CreateXmlNode("Undo");
|
||||
m_pLib->Serialize(m_undo, false);
|
||||
}
|
||||
|
||||
QString GetEditorObjectName() override
|
||||
{
|
||||
return m_selectedItem;
|
||||
}
|
||||
|
||||
protected:
|
||||
int GetSize() override { return sizeof(CUndoBaseLibrary); }
|
||||
QString GetDescription() override { return m_description; };
|
||||
|
||||
void Undo(bool bUndo) override
|
||||
{
|
||||
if (bUndo)
|
||||
{
|
||||
m_redo = GetIEditor()->GetSystem()->CreateXmlNode("Redo");
|
||||
m_pLib->Serialize(m_redo, false);
|
||||
}
|
||||
m_pLib->Serialize(m_undo, true);
|
||||
m_pLib->SetModified();
|
||||
GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
|
||||
}
|
||||
|
||||
void Redo() override
|
||||
{
|
||||
m_pLib->Serialize(m_redo, true);
|
||||
m_pLib->SetModified();
|
||||
GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_description;
|
||||
QString m_selectedItem;
|
||||
_smart_ptr<CBaseLibrary> m_pLib;
|
||||
XmlNodeRef m_undo;
|
||||
XmlNodeRef m_redo;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBaseLibrary implementation.
|
||||
|
||||
@@ -29,7 +29,6 @@ public:
|
||||
assert(libMgr);
|
||||
|
||||
m_itemPath = libItem->GetFullName();
|
||||
m_description = "Lib item changed: " + m_itemPath;
|
||||
|
||||
//serialize the lib item to undo
|
||||
m_undoCtx.node = GetIEditor()->GetSystem()->CreateXmlNode("Undo");
|
||||
@@ -45,13 +44,8 @@ public:
|
||||
m_size = sizeof(CUndoBaseLibraryItem);
|
||||
m_size += static_cast<int>(xmlStr.GetAllocatedMemory());
|
||||
m_size += m_itemPath.length();
|
||||
m_size += m_description.length();
|
||||
}
|
||||
|
||||
QString GetEditorObjectName() override
|
||||
{
|
||||
return m_itemPath;
|
||||
}
|
||||
|
||||
protected:
|
||||
int GetSize() override
|
||||
@@ -59,11 +53,6 @@ protected:
|
||||
return m_size;
|
||||
}
|
||||
|
||||
QString GetDescription() override
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void Undo(bool bUndo) override
|
||||
{
|
||||
//find the libItem
|
||||
@@ -111,7 +100,6 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_description;
|
||||
QString m_itemPath;
|
||||
IDataBaseItem::SerializeContext m_undoCtx; //saved before operation
|
||||
IDataBaseItem::SerializeContext m_redoCtx; //saved after operation so used for redo
|
||||
|
||||
@@ -17,120 +17,6 @@
|
||||
#include "ErrorReport.h"
|
||||
#include "Undo/IUndoObject.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Undo functionality for Managers, including add library, remove library, and rename library -- Vera, Confetti
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CUndoBaseLibraryManager
|
||||
: public IUndoObject
|
||||
{
|
||||
public:
|
||||
CUndoBaseLibraryManager(CBaseLibraryManager* pMngr, const QString& description, const QString& modifiedManager = nullptr)
|
||||
: m_pMngr(pMngr)
|
||||
, m_description(description)
|
||||
, m_editorObject(modifiedManager)
|
||||
{
|
||||
assert(m_pMngr);
|
||||
SerializeTo(m_undos);
|
||||
}
|
||||
|
||||
QString GetEditorObjectName() override
|
||||
{
|
||||
return m_editorObject;
|
||||
}
|
||||
|
||||
protected:
|
||||
int GetSize() override { return sizeof(CUndoBaseLibraryManager); }
|
||||
QString GetDescription() override { return m_description; };
|
||||
|
||||
void Undo(bool bUndo) override
|
||||
{
|
||||
if (bUndo)
|
||||
{
|
||||
SerializeTo(m_redos);
|
||||
}
|
||||
m_pMngr->ClearAll();
|
||||
UnserializeFrom(m_undos);
|
||||
GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
|
||||
}
|
||||
|
||||
void Redo() override
|
||||
{
|
||||
m_pMngr->ClearAll();
|
||||
UnserializeFrom(m_redos);
|
||||
GetIEditor()->Notify(eNotify_OnDataBaseUpdate);
|
||||
}
|
||||
|
||||
private:
|
||||
struct LibUndoNode
|
||||
: public _i_reference_target_t
|
||||
{
|
||||
LibUndoNode()
|
||||
{
|
||||
node = nullptr;
|
||||
fileName = "";
|
||||
}
|
||||
XmlNodeRef node;
|
||||
QString fileName;
|
||||
};
|
||||
|
||||
static const char* const LIBRARY_TAG;
|
||||
static const char* const LEVEL_LIBRARY_TAG;
|
||||
|
||||
void SerializeTo(std::vector<_smart_ptr<LibUndoNode> >& undos) // Save Library Undo
|
||||
{
|
||||
undos.clear();
|
||||
for (int i = 0; i < m_pMngr->GetLibraryCount(); i++)
|
||||
{
|
||||
IDataBaseLibrary* library = m_pMngr->GetLibrary(i);
|
||||
|
||||
const char* tag = library->IsLevelLibrary() ? LEVEL_LIBRARY_TAG : LIBRARY_TAG;
|
||||
XmlNodeRef node = GetIEditor()->GetSystem()->CreateXmlNode(tag);
|
||||
QString file = library->GetFilename().isEmpty() ? library->GetFilename() : library->GetName();
|
||||
library->Serialize(node, false);
|
||||
if (node && !file.isEmpty())
|
||||
{
|
||||
_smart_ptr<LibUndoNode> undo = new LibUndoNode();
|
||||
undo->fileName = file;
|
||||
undo->node = node;
|
||||
undos.push_back(undo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnserializeFrom(std::vector<_smart_ptr<LibUndoNode> >& undos) // Load Library Undo
|
||||
{
|
||||
for (int i = 0; i < undos.size(); i++)
|
||||
{
|
||||
_smart_ptr<LibUndoNode> undo = undos[i];
|
||||
if (undo->node && !undo->fileName.isEmpty())
|
||||
{
|
||||
//AddLibrary adds a .xml to the end of the library path, this will remove the extra for compatibility
|
||||
undo->fileName.replace(m_pMngr->GetLibsPath().toLower(), "");
|
||||
undo->fileName.replace(".xml", "");
|
||||
|
||||
const bool isLevelLibrary = (strcmp(undo->node->getTag(), LEVEL_LIBRARY_TAG) == 0);
|
||||
|
||||
IDataBaseLibrary* library = m_pMngr->AddLibrary(undo->fileName, isLevelLibrary);
|
||||
library->Serialize(undo->node, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString m_description;
|
||||
QString m_editorObject;
|
||||
CBaseLibraryManager* m_pMngr;
|
||||
std::vector<_smart_ptr<LibUndoNode> > m_undos;
|
||||
std::vector<_smart_ptr<LibUndoNode> > m_redos;
|
||||
};
|
||||
|
||||
const char* const CUndoBaseLibraryManager::LIBRARY_TAG = "UndoLibrary";
|
||||
const char* const CUndoBaseLibraryManager::LEVEL_LIBRARY_TAG = "UndoLevelLibrary";
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CBaseLibraryManager implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -82,7 +82,6 @@ protected:
|
||||
}
|
||||
|
||||
int GetSize() override { return sizeof(*this); }
|
||||
QString GetDescription() override { return "UndoSplineCtrlEx"; };
|
||||
|
||||
void Undo(bool bUndo) override
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <QScopedValueRollback>
|
||||
#include <QClipboard>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
// Aws Native SDK
|
||||
@@ -4016,7 +4017,7 @@ void CCryEditApp::OnError(AzFramework::AssetSystem::AssetSystemErrors error)
|
||||
break;
|
||||
}
|
||||
|
||||
CryMessageBox(errorMessage.c_str(), "Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
|
||||
QMessageBox::critical(nullptr,"Error",errorMessage.c_str());
|
||||
}
|
||||
|
||||
void CCryEditApp::OnOpenProceduralMaterialEditor()
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#include "GameExporter.h"
|
||||
#include "MainWindow.h"
|
||||
#include "LevelFileDialog.h"
|
||||
#include "StatObjBus.h"
|
||||
#include "Undo/Undo.h"
|
||||
|
||||
#include <Atom/RPI.Public/ViewportContext.h>
|
||||
@@ -246,9 +245,6 @@ void CCryEditDoc::DeleteContents()
|
||||
|
||||
EBUS_EVENT(AzToolsFramework::EditorEntityContextRequestBus, ResetEditorContext);
|
||||
|
||||
// [LY-90904] move this to the EditorVegetationManager component
|
||||
InstanceStatObjEventBus::Broadcast(&InstanceStatObjEventBus::Events::ReleaseData);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Clear all undo info.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -308,8 +304,6 @@ void CCryEditDoc::Save(TDocMultiArchive& arrXmlAr)
|
||||
|
||||
// Fog settings ///////////////////////////////////////////////////////
|
||||
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
|
||||
|
||||
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
|
||||
}
|
||||
}
|
||||
AfterSave();
|
||||
@@ -455,12 +449,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isPrefabEnabled)
|
||||
{
|
||||
// Name Selection groups
|
||||
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
|
||||
}
|
||||
|
||||
{
|
||||
CAutoLogTime logtime("Post Load");
|
||||
|
||||
@@ -595,16 +583,6 @@ void CCryEditDoc::SerializeFogSettings(CXmlArchive& xmlAr)
|
||||
}
|
||||
}
|
||||
|
||||
void CCryEditDoc::SerializeNameSelection(CXmlArchive& xmlAr)
|
||||
{
|
||||
IObjectManager* pObjManager = GetIEditor()->GetObjectManager();
|
||||
|
||||
if (pObjManager)
|
||||
{
|
||||
pObjManager->SerializeNameSelection(xmlAr.root, xmlAr.bLoading);
|
||||
}
|
||||
}
|
||||
|
||||
void CCryEditDoc::SetModifiedModules(EModifiedModule eModifiedModule, bool boSet)
|
||||
{
|
||||
if (!boSet)
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <IEditor.h>
|
||||
#endif
|
||||
|
||||
class CClouds;
|
||||
struct LightingSettings;
|
||||
struct IVariable;
|
||||
struct ICVar;
|
||||
@@ -124,7 +123,6 @@ public: // Create from serialization only
|
||||
const char* GetTemporaryLevelName() const;
|
||||
void DeleteTemporaryLevel();
|
||||
|
||||
CClouds* GetClouds() { return m_pClouds; }
|
||||
void SetWaterColor(const QColor& col) { m_waterColor = col; }
|
||||
QColor GetWaterColor() const { return m_waterColor; }
|
||||
XmlNodeRef& GetFogTemplate() { return m_fogTemplate; }
|
||||
@@ -163,7 +161,6 @@ protected:
|
||||
bool LoadEntitiesFromSlice(const QString& sliceFile);
|
||||
void SerializeFogSettings(CXmlArchive& xmlAr);
|
||||
virtual void SerializeViewSettings(CXmlArchive& xmlAr);
|
||||
void SerializeNameSelection(CXmlArchive& xmlAr);
|
||||
void LogLoadTime(int time) const;
|
||||
|
||||
struct TSaveDocContext
|
||||
@@ -195,7 +192,6 @@ protected:
|
||||
QColor m_waterColor = QColor(0, 0, 255);
|
||||
XmlNodeRef m_fogTemplate;
|
||||
XmlNodeRef m_environmentTemplate;
|
||||
CClouds* m_pClouds;
|
||||
std::list<IDocListener*> m_listeners;
|
||||
bool m_bDocumentReady = false;
|
||||
ICVar* doc_validate_surface_types = nullptr;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include "EditorPreferencesPageViewportManipulator.h"
|
||||
|
||||
#include <AzToolsFramework/Viewport/ViewportSettings.h>
|
||||
|
||||
// Editor
|
||||
#include "EditorViewportSettings.h"
|
||||
#include "Settings.h"
|
||||
@@ -19,7 +21,17 @@ void CEditorPreferencesPage_ViewportManipulator::Reflect(AZ::SerializeContext& s
|
||||
serialize.Class<Manipulators>()
|
||||
->Version(1)
|
||||
->Field("LineBoundWidth", &Manipulators::m_manipulatorLineBoundWidth)
|
||||
->Field("CircleBoundWidth", &Manipulators::m_manipulatorCircleBoundWidth);
|
||||
->Field("CircleBoundWidth", &Manipulators::m_manipulatorCircleBoundWidth)
|
||||
->Field("LinearManipulatorAxisLength", &Manipulators::m_linearManipulatorAxisLength)
|
||||
->Field("PlanarManipulatorAxisLength", &Manipulators::m_planarManipulatorAxisLength)
|
||||
->Field("SurfaceManipulatorRadius", &Manipulators::m_surfaceManipulatorRadius)
|
||||
->Field("SurfaceManipulatorOpacity", &Manipulators::m_surfaceManipulatorOpacity)
|
||||
->Field("LinearManipulatorConeLength", &Manipulators::m_linearManipulatorConeLength)
|
||||
->Field("LinearManipulatorConeRadius", &Manipulators::m_linearManipulatorConeRadius)
|
||||
->Field("ScaleManipulatorBoxHalfExtent", &Manipulators::m_scaleManipulatorBoxHalfExtent)
|
||||
->Field("RotationManipulatorRadius", &Manipulators::m_rotationManipulatorRadius)
|
||||
->Field("ManipulatorViewBaseScale", &Manipulators::m_manipulatorViewBaseScale)
|
||||
->Field("FlipManipulatorAxesTowardsView", &Manipulators::m_flipManipulatorAxesTowardsView);
|
||||
|
||||
serialize.Class<CEditorPreferencesPage_ViewportManipulator>()->Version(2)->Field(
|
||||
"Manipulators", &CEditorPreferencesPage_ViewportManipulator::m_manipulators);
|
||||
@@ -36,7 +48,55 @@ void CEditorPreferencesPage_ViewportManipulator::Reflect(AZ::SerializeContext& s
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_manipulatorCircleBoundWidth, "Circle Bound Width",
|
||||
"Manipulator Circle Bound Width")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.001f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 2.0f);
|
||||
->Attribute(AZ::Edit::Attributes::Max, 2.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorAxisLength, "Linear Manipulator Axis Length",
|
||||
"Length of default Linear Manipulator (for Translation and Scale Manipulators)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.1f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 5.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_planarManipulatorAxisLength, "Planar Manipulator Axis Length",
|
||||
"Length of default Planar Manipulator (for Translation Manipulators)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.1f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 5.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_surfaceManipulatorRadius, "Surface Manipulator Radius",
|
||||
"Radius of default Surface Manipulator (for Translation Manipulators)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_surfaceManipulatorOpacity, "Surface Manipulator Opacity",
|
||||
"Opacity of default Surface Manipulator (for Translation Manipulators)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.01f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorConeLength, "Linear Manipulator Cone Length",
|
||||
"Length of cone for default Linear Manipulator (for Translation Manipulators)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_linearManipulatorConeRadius, "Linear Manipulator Cone Radius",
|
||||
"Radius of cone for default Linear Manipulator (for Translation Manipulators)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 0.5f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_scaleManipulatorBoxHalfExtent, "Scale Manipulator Box Half Extent",
|
||||
"Half extent of box for default Scale Manipulator")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.05f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_rotationManipulatorRadius, "Rotation Manipulator Radius",
|
||||
"Radius of default Angular Manipulators (for Rotation Manipulators)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.5f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 5.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::SpinBox, &Manipulators::m_manipulatorViewBaseScale, "Manipulator View Base Scale",
|
||||
"The base scale to apply to all Manipulator Views (default is 1.0)")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.5f)
|
||||
->Attribute(AZ::Edit::Attributes::Max, 2.0f)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::CheckBox, &Manipulators::m_flipManipulatorAxesTowardsView, "Flip Manipulator Axes Towards View",
|
||||
"Determines whether Planar and Linear Manipulators should switch to face the view (camera) in the Editor");
|
||||
|
||||
editContext
|
||||
->Class<CEditorPreferencesPage_ViewportManipulator>("Manipulator Viewport Preferences", "Manipulator Viewport Preferences")
|
||||
@@ -82,10 +142,32 @@ void CEditorPreferencesPage_ViewportManipulator::OnApply()
|
||||
{
|
||||
SandboxEditor::SetManipulatorLineBoundWidth(m_manipulators.m_manipulatorLineBoundWidth);
|
||||
SandboxEditor::SetManipulatorCircleBoundWidth(m_manipulators.m_manipulatorCircleBoundWidth);
|
||||
|
||||
AzToolsFramework::SetLinearManipulatorAxisLength(m_manipulators.m_linearManipulatorAxisLength);
|
||||
AzToolsFramework::SetPlanarManipulatorAxisLength(m_manipulators.m_planarManipulatorAxisLength);
|
||||
AzToolsFramework::SetSurfaceManipulatorRadius(m_manipulators.m_surfaceManipulatorRadius);
|
||||
AzToolsFramework::SetSurfaceManipulatorOpacity(m_manipulators.m_surfaceManipulatorOpacity);
|
||||
AzToolsFramework::SetLinearManipulatorConeLength(m_manipulators.m_linearManipulatorConeLength);
|
||||
AzToolsFramework::SetLinearManipulatorConeRadius(m_manipulators.m_linearManipulatorConeRadius);
|
||||
AzToolsFramework::SetScaleManipulatorBoxHalfExtent(m_manipulators.m_scaleManipulatorBoxHalfExtent);
|
||||
AzToolsFramework::SetRotationManipulatorRadius(m_manipulators.m_rotationManipulatorRadius);
|
||||
AzToolsFramework::SetFlipManipulatorAxesTowardsView(m_manipulators.m_flipManipulatorAxesTowardsView);
|
||||
AzToolsFramework::SetManipulatorViewBaseScale(m_manipulators.m_manipulatorViewBaseScale);
|
||||
}
|
||||
|
||||
void CEditorPreferencesPage_ViewportManipulator::InitializeSettings()
|
||||
{
|
||||
m_manipulators.m_manipulatorLineBoundWidth = SandboxEditor::ManipulatorLineBoundWidth();
|
||||
m_manipulators.m_manipulatorCircleBoundWidth = SandboxEditor::ManipulatorCircleBoundWidth();
|
||||
|
||||
m_manipulators.m_linearManipulatorAxisLength = AzToolsFramework::LinearManipulatorAxisLength();
|
||||
m_manipulators.m_planarManipulatorAxisLength = AzToolsFramework::PlanarManipulatorAxisLength();
|
||||
m_manipulators.m_surfaceManipulatorRadius = AzToolsFramework::SurfaceManipulatorRadius();
|
||||
m_manipulators.m_surfaceManipulatorOpacity = AzToolsFramework::SurfaceManipulatorOpacity();
|
||||
m_manipulators.m_linearManipulatorConeLength = AzToolsFramework::LinearManipulatorConeLength();
|
||||
m_manipulators.m_linearManipulatorConeRadius = AzToolsFramework::LinearManipulatorConeRadius();
|
||||
m_manipulators.m_scaleManipulatorBoxHalfExtent = AzToolsFramework::ScaleManipulatorBoxHalfExtent();
|
||||
m_manipulators.m_rotationManipulatorRadius = AzToolsFramework::RotationManipulatorRadius();
|
||||
m_manipulators.m_flipManipulatorAxesTowardsView = AzToolsFramework::FlipManipulatorAxesTowardsView();
|
||||
m_manipulators.m_manipulatorViewBaseScale = AzToolsFramework::ManipulatorViewBaseScale();
|
||||
}
|
||||
|
||||
@@ -41,6 +41,16 @@ private:
|
||||
|
||||
float m_manipulatorLineBoundWidth = 0.0f;
|
||||
float m_manipulatorCircleBoundWidth = 0.0f;
|
||||
float m_linearManipulatorAxisLength = 0.0f;
|
||||
float m_planarManipulatorAxisLength = 0.0f;
|
||||
float m_surfaceManipulatorRadius = 0.0f;
|
||||
float m_surfaceManipulatorOpacity = 0.0f;
|
||||
float m_linearManipulatorConeLength = 0.0f;
|
||||
float m_linearManipulatorConeRadius = 0.0f;
|
||||
float m_scaleManipulatorBoxHalfExtent = 0.0f;
|
||||
float m_rotationManipulatorRadius = 0.0f;
|
||||
float m_manipulatorViewBaseScale = 0.0f;
|
||||
bool m_flipManipulatorAxesTowardsView = false;
|
||||
};
|
||||
|
||||
Manipulators m_manipulators;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportSettings.h>
|
||||
|
||||
namespace SandboxEditor
|
||||
{
|
||||
@@ -57,31 +58,6 @@ namespace SandboxEditor
|
||||
constexpr AZStd::string_view CameraDefaultStartingPositionY = "/Amazon/Preferences/Editor/Camera/DefaultStartingPosition/y";
|
||||
constexpr AZStd::string_view CameraDefaultStartingPositionZ = "/Amazon/Preferences/Editor/Camera/DefaultStartingPosition/z";
|
||||
|
||||
template<typename T>
|
||||
void SetRegistry(const AZStd::string_view setting, T&& value)
|
||||
{
|
||||
if (auto* registry = AZ::SettingsRegistry::Get())
|
||||
{
|
||||
registry->Set(setting, AZStd::forward<T>(value));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
AZStd::remove_cvref_t<T> GetRegistry(const AZStd::string_view setting, T&& defaultValue)
|
||||
{
|
||||
AZStd::remove_cvref_t<T> value = AZStd::forward<T>(defaultValue);
|
||||
if (const auto* registry = AZ::SettingsRegistry::Get())
|
||||
{
|
||||
T potentialValue;
|
||||
if (registry->Get(potentialValue, setting))
|
||||
{
|
||||
value = AZStd::move(potentialValue);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
struct EditorViewportSettingsCallbacksImpl : public EditorViewportSettingsCallbacks
|
||||
{
|
||||
EditorViewportSettingsCallbacksImpl()
|
||||
@@ -118,399 +94,409 @@ namespace SandboxEditor
|
||||
AZ::Vector3 CameraDefaultEditorPosition()
|
||||
{
|
||||
return AZ::Vector3(
|
||||
aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionX, 0.0)),
|
||||
aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionY, -10.0)),
|
||||
aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionZ, 4.0)));
|
||||
aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionX, 0.0)),
|
||||
aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionY, -10.0)),
|
||||
aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultStartingPositionZ, 4.0)));
|
||||
}
|
||||
|
||||
void SetCameraDefaultEditorPosition(const AZ::Vector3& defaultCameraPosition)
|
||||
{
|
||||
SetRegistry(CameraDefaultStartingPositionX, defaultCameraPosition.GetX());
|
||||
SetRegistry(CameraDefaultStartingPositionY, defaultCameraPosition.GetY());
|
||||
SetRegistry(CameraDefaultStartingPositionZ, defaultCameraPosition.GetZ());
|
||||
AzToolsFramework::SetRegistry(CameraDefaultStartingPositionX, defaultCameraPosition.GetX());
|
||||
AzToolsFramework::SetRegistry(CameraDefaultStartingPositionY, defaultCameraPosition.GetY());
|
||||
AzToolsFramework::SetRegistry(CameraDefaultStartingPositionZ, defaultCameraPosition.GetZ());
|
||||
}
|
||||
|
||||
AZ::u64 MaxItemsShownInAssetBrowserSearch()
|
||||
{
|
||||
return GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast<AZ::u64>(50));
|
||||
return AzToolsFramework::GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast<AZ::u64>(50));
|
||||
}
|
||||
|
||||
void SetMaxItemsShownInAssetBrowserSearch(const AZ::u64 numberOfItemsShown)
|
||||
{
|
||||
SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
|
||||
AzToolsFramework::SetRegistry(AssetBrowserMaxItemsShownInSearchSetting, numberOfItemsShown);
|
||||
}
|
||||
|
||||
bool GridSnappingEnabled()
|
||||
{
|
||||
return GetRegistry(GridSnappingSetting, false);
|
||||
return AzToolsFramework::GetRegistry(GridSnappingSetting, false);
|
||||
}
|
||||
|
||||
void SetGridSnapping(const bool enabled)
|
||||
{
|
||||
SetRegistry(GridSnappingSetting, enabled);
|
||||
AzToolsFramework::SetRegistry(GridSnappingSetting, enabled);
|
||||
}
|
||||
|
||||
float GridSnappingSize()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(GridSizeSetting, 0.1));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(GridSizeSetting, 0.1));
|
||||
}
|
||||
|
||||
void SetGridSnappingSize(const float size)
|
||||
{
|
||||
SetRegistry(GridSizeSetting, size);
|
||||
AzToolsFramework::SetRegistry(GridSizeSetting, size);
|
||||
}
|
||||
|
||||
bool AngleSnappingEnabled()
|
||||
{
|
||||
return GetRegistry(AngleSnappingSetting, false);
|
||||
return AzToolsFramework::GetRegistry(AngleSnappingSetting, false);
|
||||
}
|
||||
|
||||
void SetAngleSnapping(const bool enabled)
|
||||
{
|
||||
SetRegistry(AngleSnappingSetting, enabled);
|
||||
AzToolsFramework::SetRegistry(AngleSnappingSetting, enabled);
|
||||
}
|
||||
|
||||
float AngleSnappingSize()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(AngleSizeSetting, 5.0));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(AngleSizeSetting, 5.0));
|
||||
}
|
||||
|
||||
void SetAngleSnappingSize(const float size)
|
||||
{
|
||||
SetRegistry(AngleSizeSetting, size);
|
||||
AzToolsFramework::SetRegistry(AngleSizeSetting, size);
|
||||
}
|
||||
|
||||
bool ShowingGrid()
|
||||
{
|
||||
return GetRegistry(ShowGridSetting, false);
|
||||
return AzToolsFramework::GetRegistry(ShowGridSetting, false);
|
||||
}
|
||||
|
||||
void SetShowingGrid(const bool showing)
|
||||
{
|
||||
SetRegistry(ShowGridSetting, showing);
|
||||
AzToolsFramework::SetRegistry(ShowGridSetting, showing);
|
||||
}
|
||||
|
||||
bool StickySelectEnabled()
|
||||
{
|
||||
return GetRegistry(StickySelectSetting, false);
|
||||
return AzToolsFramework::GetRegistry(StickySelectSetting, false);
|
||||
}
|
||||
|
||||
void SetStickySelectEnabled(const bool enabled)
|
||||
{
|
||||
SetRegistry(StickySelectSetting, enabled);
|
||||
AzToolsFramework::SetRegistry(StickySelectSetting, enabled);
|
||||
}
|
||||
|
||||
float ManipulatorLineBoundWidth()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(ManipulatorLineBoundWidthSetting, 0.1));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(ManipulatorLineBoundWidthSetting, 0.1));
|
||||
}
|
||||
|
||||
void SetManipulatorLineBoundWidth(const float lineBoundWidth)
|
||||
{
|
||||
SetRegistry(ManipulatorLineBoundWidthSetting, lineBoundWidth);
|
||||
AzToolsFramework::SetRegistry(ManipulatorLineBoundWidthSetting, lineBoundWidth);
|
||||
}
|
||||
|
||||
float ManipulatorCircleBoundWidth()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(ManipulatorCircleBoundWidthSetting, 0.1));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(ManipulatorCircleBoundWidthSetting, 0.1));
|
||||
}
|
||||
|
||||
void SetManipulatorCircleBoundWidth(const float circleBoundWidth)
|
||||
{
|
||||
SetRegistry(ManipulatorCircleBoundWidthSetting, circleBoundWidth);
|
||||
AzToolsFramework::SetRegistry(ManipulatorCircleBoundWidthSetting, circleBoundWidth);
|
||||
}
|
||||
|
||||
float CameraTranslateSpeed()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraTranslateSpeedSetting, 10.0));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraTranslateSpeedSetting, 10.0));
|
||||
}
|
||||
|
||||
void SetCameraTranslateSpeed(const float speed)
|
||||
{
|
||||
SetRegistry(CameraTranslateSpeedSetting, speed);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateSpeedSetting, speed);
|
||||
}
|
||||
|
||||
float CameraBoostMultiplier()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraBoostMultiplierSetting, 3.0));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraBoostMultiplierSetting, 3.0));
|
||||
}
|
||||
|
||||
void SetCameraBoostMultiplier(const float multiplier)
|
||||
{
|
||||
SetRegistry(CameraBoostMultiplierSetting, multiplier);
|
||||
AzToolsFramework::SetRegistry(CameraBoostMultiplierSetting, multiplier);
|
||||
}
|
||||
|
||||
float CameraRotateSpeed()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraRotateSpeedSetting, 0.005));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraRotateSpeedSetting, 0.005));
|
||||
}
|
||||
|
||||
void SetCameraRotateSpeed(const float speed)
|
||||
{
|
||||
SetRegistry(CameraRotateSpeedSetting, speed);
|
||||
AzToolsFramework::SetRegistry(CameraRotateSpeedSetting, speed);
|
||||
}
|
||||
|
||||
float CameraScrollSpeed()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraScrollSpeedSetting, 0.02));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraScrollSpeedSetting, 0.02));
|
||||
}
|
||||
|
||||
void SetCameraScrollSpeed(const float speed)
|
||||
{
|
||||
SetRegistry(CameraScrollSpeedSetting, speed);
|
||||
AzToolsFramework::SetRegistry(CameraScrollSpeedSetting, speed);
|
||||
}
|
||||
|
||||
float CameraDollyMotionSpeed()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraDollyMotionSpeedSetting, 0.01));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDollyMotionSpeedSetting, 0.01));
|
||||
}
|
||||
|
||||
void SetCameraDollyMotionSpeed(const float speed)
|
||||
{
|
||||
SetRegistry(CameraDollyMotionSpeedSetting, speed);
|
||||
AzToolsFramework::SetRegistry(CameraDollyMotionSpeedSetting, speed);
|
||||
}
|
||||
|
||||
bool CameraOrbitYawRotationInverted()
|
||||
{
|
||||
return GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
|
||||
return AzToolsFramework::GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
|
||||
}
|
||||
|
||||
void SetCameraOrbitYawRotationInverted(const bool inverted)
|
||||
{
|
||||
SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
|
||||
AzToolsFramework::SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
|
||||
}
|
||||
|
||||
bool CameraPanInvertedX()
|
||||
{
|
||||
return GetRegistry(CameraPanInvertedXSetting, true);
|
||||
return AzToolsFramework::GetRegistry(CameraPanInvertedXSetting, true);
|
||||
}
|
||||
|
||||
void SetCameraPanInvertedX(const bool inverted)
|
||||
{
|
||||
SetRegistry(CameraPanInvertedXSetting, inverted);
|
||||
AzToolsFramework::SetRegistry(CameraPanInvertedXSetting, inverted);
|
||||
}
|
||||
|
||||
bool CameraPanInvertedY()
|
||||
{
|
||||
return GetRegistry(CameraPanInvertedYSetting, true);
|
||||
return AzToolsFramework::GetRegistry(CameraPanInvertedYSetting, true);
|
||||
}
|
||||
|
||||
void SetCameraPanInvertedY(const bool inverted)
|
||||
{
|
||||
SetRegistry(CameraPanInvertedYSetting, inverted);
|
||||
AzToolsFramework::SetRegistry(CameraPanInvertedYSetting, inverted);
|
||||
}
|
||||
|
||||
float CameraPanSpeed()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraPanSpeedSetting, 0.01));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraPanSpeedSetting, 0.01));
|
||||
}
|
||||
|
||||
void SetCameraPanSpeed(float speed)
|
||||
{
|
||||
SetRegistry(CameraPanSpeedSetting, speed);
|
||||
AzToolsFramework::SetRegistry(CameraPanSpeedSetting, speed);
|
||||
}
|
||||
|
||||
float CameraRotateSmoothness()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraRotateSmoothnessSetting, 5.0));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraRotateSmoothnessSetting, 5.0));
|
||||
}
|
||||
|
||||
void SetCameraRotateSmoothness(const float smoothness)
|
||||
{
|
||||
SetRegistry(CameraRotateSmoothnessSetting, smoothness);
|
||||
AzToolsFramework::SetRegistry(CameraRotateSmoothnessSetting, smoothness);
|
||||
}
|
||||
|
||||
float CameraTranslateSmoothness()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraTranslateSmoothnessSetting, 5.0));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraTranslateSmoothnessSetting, 5.0));
|
||||
}
|
||||
|
||||
void SetCameraTranslateSmoothness(const float smoothness)
|
||||
{
|
||||
SetRegistry(CameraTranslateSmoothnessSetting, smoothness);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateSmoothnessSetting, smoothness);
|
||||
}
|
||||
|
||||
bool CameraRotateSmoothingEnabled()
|
||||
{
|
||||
return GetRegistry(CameraRotateSmoothingSetting, true);
|
||||
return AzToolsFramework::GetRegistry(CameraRotateSmoothingSetting, true);
|
||||
}
|
||||
|
||||
void SetCameraRotateSmoothingEnabled(const bool enabled)
|
||||
{
|
||||
SetRegistry(CameraRotateSmoothingSetting, enabled);
|
||||
AzToolsFramework::SetRegistry(CameraRotateSmoothingSetting, enabled);
|
||||
}
|
||||
|
||||
bool CameraTranslateSmoothingEnabled()
|
||||
{
|
||||
return GetRegistry(CameraTranslateSmoothingSetting, true);
|
||||
return AzToolsFramework::GetRegistry(CameraTranslateSmoothingSetting, true);
|
||||
}
|
||||
|
||||
void SetCameraTranslateSmoothingEnabled(const bool enabled)
|
||||
{
|
||||
SetRegistry(CameraTranslateSmoothingSetting, enabled);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateSmoothingSetting, enabled);
|
||||
}
|
||||
|
||||
bool CameraCaptureCursorForLook()
|
||||
{
|
||||
return GetRegistry(CameraCaptureCursorLookSetting, true);
|
||||
return AzToolsFramework::GetRegistry(CameraCaptureCursorLookSetting, true);
|
||||
}
|
||||
|
||||
void SetCameraCaptureCursorForLook(const bool capture)
|
||||
{
|
||||
SetRegistry(CameraCaptureCursorLookSetting, capture);
|
||||
AzToolsFramework::SetRegistry(CameraCaptureCursorLookSetting, capture);
|
||||
}
|
||||
|
||||
float CameraDefaultOrbitDistance()
|
||||
{
|
||||
return aznumeric_cast<float>(GetRegistry(CameraDefaultOrbitDistanceSetting, 20.0));
|
||||
return aznumeric_cast<float>(AzToolsFramework::GetRegistry(CameraDefaultOrbitDistanceSetting, 20.0));
|
||||
}
|
||||
|
||||
void SetCameraDefaultOrbitDistance(const float distance)
|
||||
{
|
||||
SetRegistry(CameraDefaultOrbitDistanceSetting, distance);
|
||||
AzToolsFramework::SetRegistry(CameraDefaultOrbitDistanceSetting, distance);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraTranslateForwardChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(
|
||||
GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str());
|
||||
AzToolsFramework::GetRegistry(CameraTranslateForwardIdSetting, AZStd::string("keyboard_key_alphanumeric_W")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraTranslateForwardChannelId(AZStd::string_view cameraTranslateForwardId)
|
||||
{
|
||||
SetRegistry(CameraTranslateForwardIdSetting, cameraTranslateForwardId);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateForwardIdSetting, cameraTranslateForwardId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraTranslateBackwardChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(
|
||||
GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str());
|
||||
AzToolsFramework::GetRegistry(CameraTranslateBackwardIdSetting, AZStd::string("keyboard_key_alphanumeric_S")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraTranslateBackwardChannelId(AZStd::string_view cameraTranslateBackwardId)
|
||||
{
|
||||
SetRegistry(CameraTranslateBackwardIdSetting, cameraTranslateBackwardId);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateBackwardIdSetting, cameraTranslateBackwardId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraTranslateLeftChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraTranslateLeftIdSetting, AZStd::string("keyboard_key_alphanumeric_A")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraTranslateLeftChannelId(AZStd::string_view cameraTranslateLeftId)
|
||||
{
|
||||
SetRegistry(CameraTranslateLeftIdSetting, cameraTranslateLeftId);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateLeftIdSetting, cameraTranslateLeftId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraTranslateRightChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(
|
||||
GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str());
|
||||
AzToolsFramework::GetRegistry(CameraTranslateRightIdSetting, AZStd::string("keyboard_key_alphanumeric_D")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraTranslateRightChannelId(AZStd::string_view cameraTranslateRightId)
|
||||
{
|
||||
SetRegistry(CameraTranslateRightIdSetting, cameraTranslateRightId);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateRightIdSetting, cameraTranslateRightId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraTranslateUpChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraTranslateUpIdSetting, AZStd::string("keyboard_key_alphanumeric_E")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraTranslateUpChannelId(AZStd::string_view cameraTranslateUpId)
|
||||
{
|
||||
SetRegistry(CameraTranslateUpIdSetting, cameraTranslateUpId);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateUpIdSetting, cameraTranslateUpId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraTranslateDownChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraTranslateDownIdSetting, AZStd::string("keyboard_key_alphanumeric_Q")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraTranslateDownChannelId(AZStd::string_view cameraTranslateDownId)
|
||||
{
|
||||
SetRegistry(CameraTranslateDownIdSetting, cameraTranslateDownId);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateDownIdSetting, cameraTranslateDownId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraTranslateBoostChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(
|
||||
GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str());
|
||||
AzToolsFramework::GetRegistry(CameraTranslateBoostIdSetting, AZStd::string("keyboard_key_modifier_shift_l")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraTranslateBoostChannelId(AZStd::string_view cameraTranslateBoostId)
|
||||
{
|
||||
SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
|
||||
AzToolsFramework::SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitChannelId(AZStd::string_view cameraOrbitId)
|
||||
{
|
||||
SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
|
||||
AzToolsFramework::SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraFreeLookChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraFreeLookIdSetting, AZStd::string("mouse_button_right")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraFreeLookIdSetting, AZStd::string("mouse_button_right")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraFreeLookChannelId(AZStd::string_view cameraFreeLookId)
|
||||
{
|
||||
SetRegistry(CameraFreeLookIdSetting, cameraFreeLookId);
|
||||
AzToolsFramework::SetRegistry(CameraFreeLookIdSetting, cameraFreeLookId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraFreePanChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraFreePanChannelId(AZStd::string_view cameraFreePanId)
|
||||
{
|
||||
SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
|
||||
AzToolsFramework::SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitLookChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId)
|
||||
{
|
||||
SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
|
||||
AzToolsFramework::SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitDollyChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId)
|
||||
{
|
||||
SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
|
||||
AzToolsFramework::SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitPanChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId)
|
||||
{
|
||||
SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
|
||||
AzToolsFramework::SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraFocusChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraFocusIdSetting, AZStd::string("keyboard_key_alphanumeric_X")).c_str());
|
||||
return AzFramework::InputChannelId(
|
||||
AzToolsFramework::GetRegistry(CameraFocusIdSetting, AZStd::string("keyboard_key_alphanumeric_X")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraFocusChannelId(AZStd::string_view cameraFocusId)
|
||||
{
|
||||
SetRegistry(CameraFocusIdSetting, cameraFocusId);
|
||||
AzToolsFramework::SetRegistry(CameraFocusIdSetting, cameraFocusId);
|
||||
}
|
||||
} // namespace SandboxEditor
|
||||
|
||||
@@ -97,9 +97,6 @@
|
||||
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
|
||||
#include <IEntityRenderState.h>
|
||||
#include <IStatObj.h>
|
||||
|
||||
AZ_CVAR(
|
||||
bool, ed_visibility_logTiming, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Output the timing of the new IVisibilitySystem query");
|
||||
|
||||
@@ -475,7 +472,7 @@ void EditorViewportWidget::Update()
|
||||
{
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
m_entityVisibilityQuery.UpdateVisibility(GetCameraState());
|
||||
m_entityVisibilityQuery.UpdateVisibility(m_renderViewport->GetCameraState());
|
||||
|
||||
if (ed_visibility_logTiming)
|
||||
{
|
||||
@@ -717,7 +714,7 @@ void EditorViewportWidget::RenderAll()
|
||||
|
||||
m_debugDisplay->DepthTestOff();
|
||||
m_manipulatorManager->DrawManipulators(
|
||||
*m_debugDisplay, GetCameraState(),
|
||||
*m_debugDisplay, m_renderViewport->GetCameraState(),
|
||||
BuildMouseInteractionInternal(
|
||||
AztfVi::MouseButtons(AztfVi::TranslateMouseButtons(QGuiApplication::mouseButtons())), keyboardModifiers,
|
||||
BuildMousePick(WidgetToViewport(mapFromGlobal(QCursor::pos())))));
|
||||
@@ -881,31 +878,11 @@ void EditorViewportWidget::OnMenuSelectCurrentCamera()
|
||||
}
|
||||
}
|
||||
|
||||
AzFramework::CameraState EditorViewportWidget::GetCameraState()
|
||||
{
|
||||
return m_renderViewport->GetCameraState();
|
||||
}
|
||||
|
||||
AZ::Vector3 EditorViewportWidget::PickTerrain(const AzFramework::ScreenPoint& point)
|
||||
{
|
||||
return LYVec3ToAZVec3(ViewToWorld(AzToolsFramework::ViewportInteraction::QPointFromScreenPoint(point), nullptr, true));
|
||||
}
|
||||
|
||||
float EditorViewportWidget::TerrainHeight(const AZ::Vector2& position)
|
||||
{
|
||||
return GetIEditor()->GetTerrainElevation(position.GetX(), position.GetY());
|
||||
}
|
||||
|
||||
void EditorViewportWidget::FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntitiesOut)
|
||||
{
|
||||
visibleEntitiesOut.assign(m_entityVisibilityQuery.Begin(), m_entityVisibilityQuery.End());
|
||||
}
|
||||
|
||||
AzFramework::ScreenPoint EditorViewportWidget::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
|
||||
{
|
||||
return m_renderViewport->ViewportWorldToScreen(worldPosition);
|
||||
}
|
||||
|
||||
QWidget* EditorViewportWidget::GetWidgetForViewportContextMenu()
|
||||
{
|
||||
return this;
|
||||
@@ -2135,7 +2112,7 @@ bool EditorViewportWidget::GetActiveCameraState(AzFramework::CameraState& camera
|
||||
{
|
||||
if (m_pPrimaryViewport == this)
|
||||
{
|
||||
cameraState = GetCameraState();
|
||||
cameraState = m_renderViewport->GetCameraState();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -205,8 +205,6 @@ private:
|
||||
void* GetSystemCursorConstraintWindow() const override;
|
||||
|
||||
// AzToolsFramework::MainEditorViewportInteractionRequestBus overrides ...
|
||||
AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) override;
|
||||
float TerrainHeight(const AZ::Vector2& position) override;
|
||||
bool ShowingWorldSpace() override;
|
||||
QWidget* GetWidgetForViewportContextMenu() override;
|
||||
|
||||
@@ -293,9 +291,6 @@ private:
|
||||
// This switches the active camera to the next one in the list of (default, all custom cams).
|
||||
void CycleCamera();
|
||||
|
||||
AzFramework::CameraState GetCameraState();
|
||||
AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition);
|
||||
|
||||
QPoint WidgetToViewport(const QPoint& point) const;
|
||||
QPoint ViewportToWidget(const QPoint& point) const;
|
||||
QSize WidgetToViewport(const QSize& size) const;
|
||||
|
||||
@@ -35,20 +35,8 @@
|
||||
#include "Resource.h"
|
||||
#include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h"
|
||||
|
||||
#include <IEntityRenderState.h>
|
||||
#include <IStatObj.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
inline Export::Vector3D Vec3ToVector3D(const Vec3& vec)
|
||||
{
|
||||
Export::Vector3D ret;
|
||||
ret.x = vec.x;
|
||||
ret.y = vec.y;
|
||||
ret.z = vec.z;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const float kTangentDelta = 0.01f;
|
||||
const float kAspectRatio = 1.777778f;
|
||||
const int kReserveCount = 7; // x,y,z,rot_x,rot_y,rot_z,fov
|
||||
@@ -106,22 +94,22 @@ void Export::CData::Clear()
|
||||
// CExportManager
|
||||
CExportManager::CExportManager()
|
||||
: m_isPrecaching(false)
|
||||
, m_pBaseObj(nullptr)
|
||||
, m_FBXBakedExportFPS(0.0f)
|
||||
, m_fScale(100.0f)
|
||||
, m_bAnimationExport(false)
|
||||
, m_pBaseObj(nullptr)
|
||||
, // this scale is used by CryEngine RC
|
||||
m_bAnimationExport(false)
|
||||
m_FBXBakedExportFPS(0.0f)
|
||||
, m_bExportLocalCoords(false)
|
||||
, m_bExportOnlyPrimaryCamera(false)
|
||||
, m_numberOfExportFrames(0)
|
||||
, m_pivotEntityObject(nullptr)
|
||||
, m_bBakedKeysSequenceExport(true)
|
||||
, m_animTimeExportPrimarySequenceCurrentTime(0.0f)
|
||||
, m_animKeyTimeExport(true)
|
||||
, m_soundKeyTimeExport(true)
|
||||
, m_bExportOnlyPrimaryCamera(false)
|
||||
{
|
||||
RegisterExporter(new COBJExporter());
|
||||
RegisterExporter(new COCMExporter());
|
||||
CExportManager::RegisterExporter(new COBJExporter());
|
||||
CExportManager::RegisterExporter(new COCMExporter());
|
||||
}
|
||||
|
||||
|
||||
@@ -313,203 +301,6 @@ void CExportManager::AddEntityAnimationData(AZ::EntityId entityId)
|
||||
ProcessEntityAnimationTrack(entityId, pObj, AnimParamType::Rotation);
|
||||
}
|
||||
|
||||
|
||||
void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh, Matrix34A* pTm)
|
||||
{
|
||||
if (m_isPrecaching || !pObj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pObj->m_MeshHash = reinterpret_cast<size_t>(pIndMesh);
|
||||
IIndexedMesh::SMeshDescription meshDesc;
|
||||
pIndMesh->GetMeshDescription(meshDesc);
|
||||
|
||||
// if we have subset of meshes we need to duplicate vertices,
|
||||
// keep transformation of submesh,
|
||||
// and store new offset for indices
|
||||
int newOffsetIndex = pObj->GetVertexCount();
|
||||
|
||||
if (meshDesc.m_nVertCount)
|
||||
{
|
||||
pObj->m_vertices.reserve(meshDesc.m_nVertCount + newOffsetIndex);
|
||||
pObj->m_normals.reserve(meshDesc.m_nVertCount + newOffsetIndex);
|
||||
}
|
||||
|
||||
for (int v = 0; v < meshDesc.m_nVertCount; ++v)
|
||||
{
|
||||
Vec3 n = meshDesc.m_pNorms[v].GetN();
|
||||
Vec3 tmp = (meshDesc.m_pVerts ? meshDesc.m_pVerts[v] : meshDesc.m_pVertsF16[v].ToVec3());
|
||||
if (pTm)
|
||||
{
|
||||
tmp = pTm->TransformPoint(tmp);
|
||||
}
|
||||
|
||||
pObj->m_vertices.push_back(Vec3ToVector3D(tmp * m_fScale));
|
||||
pObj->m_normals.push_back(Vec3ToVector3D(n));
|
||||
}
|
||||
|
||||
if (meshDesc.m_nCoorCount)
|
||||
{
|
||||
pObj->m_texCoords.reserve(meshDesc.m_nCoorCount + newOffsetIndex);
|
||||
}
|
||||
|
||||
for (int v = 0; v < meshDesc.m_nCoorCount; ++v)
|
||||
{
|
||||
Vec2 uv = meshDesc.m_pTexCoord[v].GetUV();
|
||||
uv.y = 1.0f - uv.y;
|
||||
pObj->m_texCoords.push_back({uv.x,uv.y});
|
||||
}
|
||||
|
||||
if (pIndMesh->GetSubSetCount() && !(pIndMesh->GetSubSetCount() == 1 && pIndMesh->GetSubSet(0).nNumIndices == 0))
|
||||
{
|
||||
for (int i = 0; i < pIndMesh->GetSubSetCount(); ++i)
|
||||
{
|
||||
Export::CMesh* pMesh = new Export::CMesh();
|
||||
|
||||
const SMeshSubset& sms = pIndMesh->GetSubSet(i);
|
||||
const vtx_idx* pIndices = &meshDesc.m_pIndices[sms.nFirstIndexId];
|
||||
int nTris = sms.nNumIndices / 3;
|
||||
pMesh->m_faces.reserve(nTris);
|
||||
for (int f = 0; f < nTris; ++f)
|
||||
{
|
||||
Export::Face face;
|
||||
face.idx[0] = *(pIndices++) + newOffsetIndex;
|
||||
face.idx[1] = *(pIndices++) + newOffsetIndex;
|
||||
face.idx[2] = *(pIndices++) + newOffsetIndex;
|
||||
pMesh->m_faces.push_back(face);
|
||||
}
|
||||
|
||||
pObj->m_meshes.push_back(pMesh);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Export::CMesh* pMesh = new Export::CMesh();
|
||||
if (meshDesc.m_nFaceCount == 0 && meshDesc.m_nIndexCount != 0 && meshDesc.m_pIndices != nullptr)
|
||||
{
|
||||
const vtx_idx* pIndices = &meshDesc.m_pIndices[0];
|
||||
int nTris = meshDesc.m_nIndexCount / 3;
|
||||
pMesh->m_faces.reserve(nTris);
|
||||
for (int f = 0; f < nTris; ++f)
|
||||
{
|
||||
Export::Face face;
|
||||
face.idx[0] = *(pIndices++) + newOffsetIndex;
|
||||
face.idx[1] = *(pIndices++) + newOffsetIndex;
|
||||
face.idx[2] = *(pIndices++) + newOffsetIndex;
|
||||
pMesh->m_faces.push_back(face);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pMesh->m_faces.reserve(meshDesc.m_nFaceCount);
|
||||
for (int f = 0; f < meshDesc.m_nFaceCount; ++f)
|
||||
{
|
||||
Export::Face face;
|
||||
face.idx[0] = meshDesc.m_pFaces[f].v[0];
|
||||
face.idx[1] = meshDesc.m_pFaces[f].v[1];
|
||||
face.idx[2] = meshDesc.m_pFaces[f].v[2];
|
||||
pMesh->m_faces.push_back(face);
|
||||
}
|
||||
}
|
||||
|
||||
pObj->m_meshes.push_back(pMesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CExportManager::AddStatObj(Export::CObject* pObj, IStatObj* pStatObj, Matrix34A* pTm)
|
||||
{
|
||||
IIndexedMesh* pIndMesh = nullptr;
|
||||
|
||||
if (pStatObj->GetSubObjectCount())
|
||||
{
|
||||
for (int i = 0; i < pStatObj->GetSubObjectCount(); i++)
|
||||
{
|
||||
IStatObj::SSubObject* pSubObj = pStatObj->GetSubObject(i);
|
||||
if (pSubObj && pSubObj->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj)
|
||||
{
|
||||
pIndMesh = nullptr;
|
||||
if (m_isOccluder)
|
||||
{
|
||||
if (pSubObj->pStatObj->GetLodObject(2))
|
||||
{
|
||||
pIndMesh = pSubObj->pStatObj->GetLodObject(2)->GetIndexedMesh(true);
|
||||
}
|
||||
if (!pIndMesh && pSubObj->pStatObj->GetLodObject(1))
|
||||
{
|
||||
pIndMesh = pSubObj->pStatObj->GetLodObject(1)->GetIndexedMesh(true);
|
||||
}
|
||||
}
|
||||
if (!pIndMesh)
|
||||
{
|
||||
pIndMesh = pSubObj->pStatObj->GetIndexedMesh(true);
|
||||
}
|
||||
if (pIndMesh)
|
||||
{
|
||||
AddMesh(pObj, pIndMesh, pTm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pIndMesh)
|
||||
{
|
||||
if (m_isOccluder)
|
||||
{
|
||||
if (pStatObj->GetLodObject(2))
|
||||
{
|
||||
pIndMesh = pStatObj->GetLodObject(2)->GetIndexedMesh(true);
|
||||
}
|
||||
if (!pIndMesh && pStatObj->GetLodObject(1))
|
||||
{
|
||||
pIndMesh = pStatObj->GetLodObject(1)->GetIndexedMesh(true);
|
||||
}
|
||||
}
|
||||
if (!pIndMesh)
|
||||
{
|
||||
pIndMesh = pStatObj->GetIndexedMesh(true);
|
||||
}
|
||||
if (pIndMesh)
|
||||
{
|
||||
AddMesh(pObj, pIndMesh, pTm);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CExportManager::AddMeshes(Export::CObject* pObj)
|
||||
{
|
||||
if (m_pBaseObj->GetType() == OBJTYPE_AZENTITY)
|
||||
{
|
||||
CEntityObject* pEntityObject = (CEntityObject*)m_pBaseObj;
|
||||
IRenderNode* pEngineNode = pEntityObject->GetEngineNode();
|
||||
|
||||
if (pEngineNode)
|
||||
{
|
||||
if (!m_isPrecaching)
|
||||
{
|
||||
for (int i = 0; i < pEngineNode->GetSlotCount(); ++i)
|
||||
{
|
||||
Matrix34A tm;
|
||||
IStatObj* pStatObj = pEngineNode->GetEntityStatObj(i, 0, &tm);
|
||||
if (pStatObj)
|
||||
{
|
||||
Matrix34A objTM = m_pBaseObj->GetWorldTM();
|
||||
objTM.Invert();
|
||||
tm = objTM * tm;
|
||||
AddStatObj(pObj, pStatObj, &tm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CExportManager::AddObject(CBaseObject* pBaseObj)
|
||||
{
|
||||
if (m_isOccluder)
|
||||
@@ -531,7 +322,6 @@ bool CExportManager::AddObject(CBaseObject* pBaseObj)
|
||||
|
||||
if (m_isPrecaching)
|
||||
{
|
||||
AddMeshes(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -542,7 +332,6 @@ bool CExportManager::AddObject(CBaseObject* pBaseObj)
|
||||
|
||||
m_objectMap[pBaseObj] = int(m_data.m_objects.size() - 1);
|
||||
|
||||
AddMeshes(pObj);
|
||||
m_pBaseObj = nullptr;
|
||||
|
||||
return true;
|
||||
@@ -1227,15 +1016,6 @@ bool CExportManager::ImportFromFile(const char* filename)
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool CExportManager::ExportSingleStatObj(IStatObj* pStatObj, const char* filename)
|
||||
{
|
||||
Export::CObject* pObj = new Export::CObject(Path::GetFileName(filename).toUtf8().data());
|
||||
AddStatObj(pObj, pStatObj);
|
||||
m_data.m_objects.push_back(pObj);
|
||||
ExportToFile(filename, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CExportManager::SaveNodeKeysTimeToXML()
|
||||
{
|
||||
CTrackViewSequence* pSequence = GetIEditor()->GetAnimation()->GetSequence();
|
||||
|
||||
@@ -139,18 +139,11 @@ public:
|
||||
bool ImportFromFile(const char* filename);
|
||||
const Export::CData& GetData() const {return m_data; };
|
||||
|
||||
//! Exports the stat obj to the obj file specified
|
||||
//! returns true if succeeded, otherwise false
|
||||
bool ExportSingleStatObj(IStatObj* pStatObj, const char* filename) override;
|
||||
|
||||
void SetBakedKeysSequenceExport(bool bBaked){m_bBakedKeysSequenceExport = bBaked; };
|
||||
|
||||
void SaveNodeKeysTimeToXML();
|
||||
|
||||
private:
|
||||
void AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh, Matrix34A* pTm = nullptr);
|
||||
bool AddStatObj(Export::CObject* pObj, IStatObj* pStatObj, Matrix34A* pTm = nullptr);
|
||||
bool AddMeshes(Export::CObject* pObj);
|
||||
bool AddObject(CBaseObject* pBaseObj);
|
||||
void SolveHierarchy();
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
// CryCommon
|
||||
#include <CryCommon/INavigationSystem.h>
|
||||
#include <CryCommon/LyShine/ILyShine.h>
|
||||
#include <CryCommon/MainThreadRenderRequestBus.h>
|
||||
|
||||
// Editor
|
||||
@@ -157,20 +156,20 @@ struct SSystemUserCallback
|
||||
}
|
||||
}
|
||||
|
||||
int ShowMessage(const char* text, const char* caption, unsigned int uType) override
|
||||
void ShowMessage(const char* text, const char* caption, unsigned int uType) override
|
||||
{
|
||||
if (CCryEditApp::instance()->IsInAutotestMode())
|
||||
{
|
||||
return IDOK;
|
||||
return;
|
||||
}
|
||||
|
||||
const UINT kMessageBoxButtonMask = 0x000f;
|
||||
if (!GetIEditor()->IsInGameMode() && (uType == 0 || uType == MB_OK || !(uType & kMessageBoxButtonMask)))
|
||||
{
|
||||
static_cast<CEditorImpl*>(GetIEditor())->AddErrorMessage(text, caption);
|
||||
return IDOK;
|
||||
return;
|
||||
}
|
||||
return CryMessageBox(text, caption, uType);
|
||||
CryMessageBox(text, caption, uType);
|
||||
}
|
||||
|
||||
void OnSplashScreenDone()
|
||||
@@ -595,13 +594,6 @@ void CGameEngine::SwitchToInEditor()
|
||||
// Enable accelerators.
|
||||
GetIEditor()->EnableAcceleratos(true);
|
||||
|
||||
|
||||
// reset UI system
|
||||
if (gEnv->pLyShine)
|
||||
{
|
||||
gEnv->pLyShine->Reset();
|
||||
}
|
||||
|
||||
// [Anton] - order changed, see comments for CGameEngine::SetSimulationMode
|
||||
//! Send event to switch out of game.
|
||||
GetIEditor()->GetObjectManager()->SendEvent(EVENT_OUTOFGAME);
|
||||
|
||||
@@ -8,17 +8,11 @@
|
||||
|
||||
|
||||
// Description : The game engine for editor
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_GAMEENGINE_H
|
||||
#define CRYINCLUDE_EDITOR_GAMEENGINE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include "LogFile.h"
|
||||
#include "CryListenerSet.h"
|
||||
#include "Util/ModalWindowDismisser.h"
|
||||
#endif
|
||||
|
||||
@@ -159,5 +153,3 @@ private:
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_GAMEENGINE_H
|
||||
|
||||
@@ -146,13 +146,11 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
|
||||
exportSuccessful = false;
|
||||
}
|
||||
|
||||
if (exportSuccessful)
|
||||
if (exportSuccessful && m_bAutoExportMode)
|
||||
{
|
||||
if (m_bAutoExportMode)
|
||||
{
|
||||
// Remove read-only flags.
|
||||
CrySetFileAttributes(m_levelPak.m_sPath.toUtf8().data(), FILE_ATTRIBUTE_NORMAL);
|
||||
}
|
||||
// Remove read-only flags.
|
||||
auto perms = QFile::permissions(m_levelPak.m_sPath) | QFile::Permission::WriteOwner;
|
||||
QFile::setPermissions(m_levelPak.m_sPath, perms);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -508,8 +508,6 @@ struct IEditor
|
||||
virtual CBaseObject* NewObject(const char* typeName, const char* fileName = "", const char* name = "", float x = 0.0f, float y = 0.0f, float z = 0.0f, bool modifyDoc = true) = 0;
|
||||
//! Delete object
|
||||
virtual void DeleteObject(CBaseObject* obj) = 0;
|
||||
//! Clone object
|
||||
virtual CBaseObject* CloneObject(CBaseObject* obj) = 0;
|
||||
//! Get current selection group
|
||||
virtual CSelectionGroup* GetSelection() = 0;
|
||||
virtual CBaseObject* GetSelectedObject() = 0;
|
||||
|
||||
@@ -397,11 +397,6 @@ void CEditorImpl::Update()
|
||||
// Make sure this is not called recursively
|
||||
m_bUpdates = false;
|
||||
|
||||
//@FIXME: Restore this latter.
|
||||
//if (GetGameEngine() && GetGameEngine()->IsLevelLoaded())
|
||||
{
|
||||
m_pObjectManager->Update();
|
||||
}
|
||||
if (IsInPreviewMode())
|
||||
{
|
||||
SetModifiedFlag(false);
|
||||
@@ -687,13 +682,6 @@ void CEditorImpl::DeleteObject(CBaseObject* obj)
|
||||
GetObjectManager()->DeleteObject(obj);
|
||||
}
|
||||
|
||||
CBaseObject* CEditorImpl::CloneObject(CBaseObject* obj)
|
||||
{
|
||||
SetModifiedFlag();
|
||||
GetIEditor()->SetModifiedModule(eModifiedBrushes);
|
||||
return GetObjectManager()->CloneObject(obj);
|
||||
}
|
||||
|
||||
CBaseObject* CEditorImpl::GetSelectedObject()
|
||||
{
|
||||
if (m_pObjectManager->GetSelection()->GetCount() != 1)
|
||||
|
||||
@@ -141,7 +141,6 @@ public:
|
||||
const SGizmoParameters& GetGlobalGizmoParameters() override;
|
||||
CBaseObject* NewObject(const char* typeName, const char* fileName = "", const char* name = "", float x = 0.0f, float y = 0.0f, float z = 0.0f, bool modifyDoc = true) override;
|
||||
void DeleteObject(CBaseObject* obj) override;
|
||||
CBaseObject* CloneObject(CBaseObject* obj) override;
|
||||
IObjectManager* GetObjectManager() override;
|
||||
// This will return a null pointer if CrySystem is not loaded before
|
||||
// Global Sandbox Settings are loaded from the registry before CrySystem
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include "Util/Image.h"
|
||||
#include "Util/ImageUtil.h"
|
||||
|
||||
#include <IStatObj.h>
|
||||
|
||||
#define HELPER_MATERIAL "Objects/Helper"
|
||||
|
||||
namespace
|
||||
@@ -38,7 +36,6 @@ namespace
|
||||
CIconManager::CIconManager()
|
||||
{
|
||||
ZeroStruct(m_icons);
|
||||
ZeroStruct(m_objects);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -61,13 +58,7 @@ void CIconManager::Done()
|
||||
void CIconManager::Reset()
|
||||
{
|
||||
// Do not unload objects. but clears them.
|
||||
int i;
|
||||
for (i = 0; i < sizeof(m_objects) / sizeof(m_objects[0]); i++)
|
||||
{
|
||||
delete m_objects[i];
|
||||
m_objects[i] = nullptr;
|
||||
}
|
||||
for (i = 0; i < eIcon_COUNT; i++)
|
||||
for (int i = 0; i < eIcon_COUNT; i++)
|
||||
{
|
||||
m_icons[i] = 0;
|
||||
}
|
||||
@@ -110,12 +101,6 @@ int CIconManager::GetIconTexture(EIcon icon)
|
||||
return m_icons[icon];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IStatObj* CIconManager::GetObject(EStatObject)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
QImage* CIconManager::GetIconBitmap(const char* filename, bool& bHaveAlpha, uint32 effects /*=0*/)
|
||||
{
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
|
||||
|
||||
// Description : Manages Textures used by Icon.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_ICONMANAGER_H
|
||||
#define CRYINCLUDE_EDITOR_ICONMANAGER_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Include/IIconManager.h" // for IIconManager
|
||||
@@ -31,7 +26,7 @@ class CIconManager
|
||||
public:
|
||||
// Construction
|
||||
CIconManager();
|
||||
~CIconManager();
|
||||
~CIconManager() override;
|
||||
|
||||
void Init();
|
||||
void Done();
|
||||
@@ -41,8 +36,6 @@ public:
|
||||
|
||||
// Operations
|
||||
virtual int GetIconTexture(EIcon icon);
|
||||
|
||||
virtual IStatObj* GetObject(EStatObject object);
|
||||
virtual int GetIconTexture(const char* iconName);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -61,7 +54,6 @@ public:
|
||||
private:
|
||||
StdMap<QString, int> m_textures;
|
||||
|
||||
IStatObj* m_objects[eStatObject_COUNT];
|
||||
int m_icons[eIcon_COUNT];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -70,5 +62,3 @@ private:
|
||||
typedef std::map<QString, QImage*> IconsMap;
|
||||
IconsMap m_iconBitmapsMap;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_ICONMANAGER_H
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IDISPLAYVIEWPORT_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IDISPLAYVIEWPORT_H
|
||||
#pragma once
|
||||
|
||||
struct DisplayContext;
|
||||
@@ -22,7 +19,6 @@ struct IDisplayViewport
|
||||
{
|
||||
virtual void Update() = 0;
|
||||
virtual float GetScreenScaleFactor(const Vec3& position) const = 0;
|
||||
virtual bool HitTestLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& hitpoint, int pixelRadius, float* pToCameraDistance = 0) const = 0;
|
||||
|
||||
/**
|
||||
* Gets the distance of the point on screen to the line defined by the two points, converted to screenspace.
|
||||
@@ -48,12 +44,9 @@ struct IDisplayViewport
|
||||
virtual Vec3 WorldToView3D(const Vec3& worldPoint, int flags = 0) const = 0;
|
||||
virtual Vec3 ViewToWorld(const QPoint& vp, bool* collideWithTerrain = nullptr, bool onlyTerrain = false, bool bSkipVegetation = false, bool bTestRenderMesh = false, bool* collideWithObject = nullptr) const = 0;
|
||||
virtual void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const = 0;
|
||||
virtual float GetGridStep() const = 0;
|
||||
virtual void setRay(QPoint& vp, Vec3& raySrc, Vec3& rayDir) = 0;
|
||||
virtual void setHitcontext(QPoint& vp, Vec3& raySrc, Vec3& rayDir) = 0;
|
||||
|
||||
virtual float GetAspectRatio() const = 0;
|
||||
virtual const ::Plane* GetConstructionPlane() const = 0;
|
||||
|
||||
virtual bool IsBoundsVisible(const AABB& box) const = 0;
|
||||
|
||||
@@ -62,5 +55,3 @@ struct IDisplayViewport
|
||||
|
||||
virtual CViewport *asCViewport() { return nullptr; }
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IDISPLAYVIEWPORT_H
|
||||
|
||||
@@ -8,14 +8,9 @@
|
||||
|
||||
|
||||
// Description : Export geometry interfaces
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IEXPORTMANAGER_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IEXPORTMANAGER_H
|
||||
#pragma once
|
||||
|
||||
#define EXP_NAMESIZE 32
|
||||
struct IStatObj;
|
||||
enum class AnimParamType;
|
||||
|
||||
namespace Export
|
||||
@@ -178,18 +173,10 @@ struct IExporter
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// IExportManager: interface to export manager
|
||||
struct IExportManager
|
||||
{
|
||||
//! Register exporter
|
||||
//! return true if succeed, otherwise false
|
||||
virtual bool RegisterExporter(IExporter* pExporter) = 0;
|
||||
|
||||
virtual bool ExportSingleStatObj(IStatObj* pStatObj, const char* filename) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IEXPORTMANAGER_H
|
||||
|
||||
@@ -6,12 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IICONMANAGER_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IICONMANAGER_H
|
||||
#pragma once
|
||||
|
||||
struct IStatObj;
|
||||
struct IMaterial;
|
||||
class CBitmap;
|
||||
|
||||
@@ -56,12 +52,9 @@ enum EIconEffect
|
||||
struct IIconManager
|
||||
{
|
||||
virtual ~IIconManager() = default;
|
||||
virtual IStatObj* GetObject(EStatObject object) = 0;
|
||||
virtual int GetIconTexture(EIcon icon) = 0;
|
||||
virtual int GetIconTexture(const char* iconName) = 0;
|
||||
virtual QImage* GetIconBitmap(const char* filename, bool& haveAlpha, uint32 effects = 0) = 0;
|
||||
// Register an Icon for the specific command
|
||||
virtual void RegisterCommandIcon([[maybe_unused]] const char* filename, [[maybe_unused]] int nCommandId) {}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IICONMANAGER_H
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IOBJECTMANAGER_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IOBJECTMANAGER_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
@@ -29,32 +25,15 @@ class CObjectArchive;
|
||||
class CViewport;
|
||||
struct HitContext;
|
||||
enum class ImageRotationDegrees;
|
||||
struct IStatObj;
|
||||
class CBaseObject;
|
||||
class XmlNodeRef;
|
||||
|
||||
#include "ObjectEvent.h"
|
||||
|
||||
enum SerializeFlags
|
||||
{
|
||||
SERIALIZE_ALL = 0,
|
||||
SERIALIZE_ONLY_SHARED = 1,
|
||||
SERIALIZE_ONLY_NOTSHARED = 2,
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef std::vector<CBaseObject*> CBaseObjectsArray;
|
||||
typedef std::pair< bool(CALLBACK*)(CBaseObject const&, void*), void* > BaseObjectFilterFunctor;
|
||||
|
||||
struct IObjectSelectCallback
|
||||
{
|
||||
//! Called when object is selected.
|
||||
//! Return true if selection should proceed, or false to abort object selection.
|
||||
virtual bool OnSelectObject(CBaseObject* obj) = 0;
|
||||
//! Return true if object can be selected.
|
||||
virtual bool CanSelectObject(CBaseObject* obj) = 0;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Interface to access editor objects scene graph.
|
||||
@@ -78,10 +57,6 @@ public:
|
||||
virtual void DeleteObject(CBaseObject* obj) = 0;
|
||||
virtual void DeleteSelection(CSelectionGroup* pSelection) = 0;
|
||||
virtual void DeleteAllObjects() = 0;
|
||||
virtual CBaseObject* CloneObject(CBaseObject* obj) = 0;
|
||||
|
||||
virtual void BeginEditParams(CBaseObject* obj, int flags) = 0;
|
||||
virtual void EndEditParams(int flags = 0) = 0;
|
||||
|
||||
//! Get number of objects manager by ObjectManager (not contain sub objects of groups).
|
||||
virtual int GetObjectCount() const = 0;
|
||||
@@ -90,27 +65,9 @@ public:
|
||||
//! @param layer if 0 get objects for all layers, or layer to get objects from.
|
||||
virtual void GetObjects(CBaseObjectsArray& objects) const = 0;
|
||||
|
||||
//! Get array of objects that pass the filter.
|
||||
//! @param filter The filter functor, return true if you want to get the certain obj, return false if want to skip it.
|
||||
virtual void GetObjects(CBaseObjectsArray& objects, BaseObjectFilterFunctor const& filter) const = 0;
|
||||
|
||||
//! Display objects on specified display context.
|
||||
virtual void Display(DisplayContext& dc) = 0;
|
||||
|
||||
//! Called when selecting without selection helpers - this is needed since
|
||||
//! the visible object cache is normally not updated when not displaying helpers.
|
||||
virtual void ForceUpdateVisibleObjectCache(DisplayContext& dc) = 0;
|
||||
|
||||
//! Check intersection with objects.
|
||||
//! Find intersection with nearest to ray origin object hit by ray.
|
||||
//! If distance tollerance is specified certain relaxation applied on collision test.
|
||||
//! @return true if hit any object, and fills hitInfo structure.
|
||||
virtual bool HitTest(HitContext& hitInfo) = 0;
|
||||
|
||||
//! Check intersection with an object.
|
||||
//! @return true if hit, and fills hitInfo structure.
|
||||
virtual bool HitTestObject(CBaseObject* obj, HitContext& hc) = 0;
|
||||
|
||||
//! Gets a radius to be used for hit tests on the axis helpers, like the transform gizmo.
|
||||
//! @return the axis helper hit radius.
|
||||
virtual int GetAxisHelperHitRadius() const = 0;
|
||||
@@ -137,59 +94,18 @@ public:
|
||||
//! Find objects which intersect with a given AABB.
|
||||
virtual void FindObjectsInAABB(const AABB& aabb, std::vector<CBaseObject*>& result) const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Operations on objects.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Makes object visible or invisible.
|
||||
virtual void HideObject(CBaseObject* obj, bool hide) = 0;
|
||||
//! Shows the last hidden object based on hidden ID
|
||||
virtual void ShowLastHiddenObject() = 0;
|
||||
//! Freeze object, making it unselectable.
|
||||
virtual void FreezeObject(CBaseObject* obj, bool freeze) = 0;
|
||||
//! Unhide all hidden objects.
|
||||
virtual void UnhideAll() = 0;
|
||||
//! Unfreeze all frozen objects.
|
||||
virtual void UnfreezeAll() = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Object Selection.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual bool SelectObject(CBaseObject* obj, bool bUseMask = true) = 0;
|
||||
virtual void UnselectObject(CBaseObject* obj) = 0;
|
||||
|
||||
//! Select objects within specified distance from given position.
|
||||
//! Return number of selected objects.
|
||||
virtual int SelectObjects(const AABB& box, bool bUnselect = false) = 0;
|
||||
|
||||
virtual void SelectEntities(std::set<CEntityObject*>& s) = 0;
|
||||
|
||||
virtual int MoveObjects(const AABB& box, const Vec3& offset, ImageRotationDegrees rotation, bool bIsCopy = false) = 0;
|
||||
|
||||
//! Selects/Unselects all objects within 2d rectangle in given viewport.
|
||||
virtual void SelectObjectsInRect(CViewport* view, const QRect& rect, bool bSelect) = 0;
|
||||
virtual void FindObjectsInRect(CViewport* view, const QRect& rect, std::vector<GUID>& guids) = 0;
|
||||
|
||||
//! Clear default selection set.
|
||||
//! @Return number of objects removed from selection.
|
||||
virtual int ClearSelection() = 0;
|
||||
|
||||
//! Deselect all current selected objects and selects object that were unselected.
|
||||
//! @Return number of selected objects.
|
||||
virtual int InvertSelection() = 0;
|
||||
|
||||
//! Get current selection.
|
||||
virtual CSelectionGroup* GetSelection() const = 0;
|
||||
//! Get named selection.
|
||||
virtual CSelectionGroup* GetSelection(const QString& name) const = 0;
|
||||
// Get selection group names
|
||||
virtual void GetNameSelectionStrings(QStringList& names) = 0;
|
||||
//! Change name of current selection group.
|
||||
//! And store it in list.
|
||||
virtual void NameSelection(const QString& name) = 0;
|
||||
//! Set one of name selections as current selection.
|
||||
virtual void SetSelection(const QString& name) = 0;
|
||||
//! Removes one of named selections.
|
||||
virtual void RemoveSelection(const QString& name) = 0;
|
||||
|
||||
//! Delete all objects in current selection group.
|
||||
virtual void DeleteSelection() = 0;
|
||||
@@ -198,54 +114,11 @@ public:
|
||||
virtual QString GenerateUniqueObjectName(const QString& typeName) = 0;
|
||||
//! Register object name in object manager, needed for generating uniq names.
|
||||
virtual void RegisterObjectName(const QString& name) = 0;
|
||||
//! Enable/Disable generating of unique object names (Enabled by default).
|
||||
//! Return previous value.
|
||||
virtual bool EnableUniqObjectNames(bool bEnable) = 0;
|
||||
|
||||
//! Find object class by name.
|
||||
virtual CObjectClassDesc* FindClass(const QString& className) = 0;
|
||||
virtual void GetClassCategories(QStringList& categories) = 0;
|
||||
virtual void GetClassCategoryToolClassNamePairs(std::vector< std::pair<QString, QString> >& categoryToolClassNamePairs) = 0;
|
||||
virtual void GetClassTypes(const QString& category, QStringList& types) = 0;
|
||||
|
||||
//! Export objects to xml.
|
||||
//! When onlyShared is true ony objects with shared flags exported, overwise only not shared object exported.
|
||||
virtual void Export(const QString& levelPath, XmlNodeRef& rootNode, bool onlyShared) = 0;
|
||||
//! Export only entities to xml.
|
||||
virtual void ExportEntities(XmlNodeRef& rootNode) = 0;
|
||||
|
||||
//! Serialize Objects in manager to specified XML Node.
|
||||
//! @param flags Can be one of SerializeFlags.
|
||||
virtual void Serialize(XmlNodeRef& rootNode, bool bLoading, int flags = SERIALIZE_ALL) = 0;
|
||||
virtual void SerializeNameSelection(XmlNodeRef& rootNode, bool bLoading) = 0;
|
||||
|
||||
//! Load objects from object archive.
|
||||
//! @param bSelect if set newly loaded object will be selected.
|
||||
virtual void LoadObjects(CObjectArchive& ar, bool bSelect) = 0;
|
||||
|
||||
virtual void ChangeObjectId(REFGUID oldId, REFGUID newId) = 0;
|
||||
virtual bool IsDuplicateObjectName(const QString& newName) const = 0;
|
||||
virtual void ShowDuplicationMsgWarning(CBaseObject* obj, const QString& newName, bool bShowMsgBox) const = 0;
|
||||
virtual void ChangeObjectName(CBaseObject* obj, const QString& newName) = 0;
|
||||
|
||||
//! while loading PreFabs we need to force this IDs
|
||||
//! to force always the same IDs, on each load.
|
||||
//! needed for RAM-maps assignments
|
||||
virtual uint32 ForceID() const = 0;
|
||||
virtual void ForceID(uint32 FID) = 0;
|
||||
|
||||
//! Convert object of one type to object of another type.
|
||||
//! Original object is deleted.
|
||||
virtual bool ConvertToType(CBaseObject* pObject, const QString& typeName) = 0;
|
||||
|
||||
//! Set new selection callback.
|
||||
//! @return previous selection callback.
|
||||
virtual IObjectSelectCallback* SetSelectCallback(IObjectSelectCallback* callback) = 0;
|
||||
|
||||
// Enables/Disables creating of game objects.
|
||||
virtual void SetCreateGameObject(bool enable) = 0;
|
||||
//! Return true if objects loaded from xml should immidiatly create game objects associated with them.
|
||||
virtual bool IsCreateGameObjects() const = 0;
|
||||
|
||||
virtual IGizmoManager* GetGizmoManager() = 0;
|
||||
|
||||
@@ -253,34 +126,9 @@ public:
|
||||
//! Invalidate visibily settings of objects.
|
||||
virtual void InvalidateVisibleList() = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ObjectManager notification Callbacks.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void AddObjectEventListener(EventListener* listener) = 0;
|
||||
virtual void RemoveObjectEventListener(EventListener* listener) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Used to indicate starting and ending of objects loading.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void StartObjectsLoading(int numObjects) = 0;
|
||||
virtual void EndObjectsLoading() = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Gathers all resources used by all objects.
|
||||
virtual void GatherUsedResources(CUsedResources& resources) = 0;
|
||||
|
||||
virtual bool IsLightClass(CBaseObject* pObject) = 0;
|
||||
|
||||
virtual void FindAndRenameProperty2(const char* property2Name, const QString& oldValue, const QString& newValue) = 0;
|
||||
virtual void FindAndRenameProperty2If(const char* property2Name, const QString& oldValue, const QString& newValue, const char* otherProperty2Name, const QString& otherValue) = 0;
|
||||
|
||||
virtual bool IsReloading() const = 0;
|
||||
|
||||
// Set bSkipUpdate to true if you want to skip update objects on the idle loop.
|
||||
virtual void SetSkipUpdate(bool bSkipUpdate) = 0;
|
||||
|
||||
virtual void SetExportingLevel(bool bExporting) = 0;
|
||||
virtual bool IsExportingLevelInprogress() const = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IOBJECTMANAGER_H
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
//! Standart objects types.
|
||||
enum ObjectType
|
||||
{
|
||||
OBJTYPE_DUMMY = 1 << 20,
|
||||
OBJTYPE_AZENTITY = 1 << 21,
|
||||
};
|
||||
|
||||
|
||||
@@ -63,16 +63,6 @@ namespace ObjectManagerPythonBindingsUnitTests
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("get_selection_center") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("get_selection_aabb") != behaviorContext->m_methods.end());
|
||||
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("hide_object") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("is_object_hidden") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("unhide_object") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("hide_all_objects") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("unhide_all_objects") != behaviorContext->m_methods.end());
|
||||
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("freeze_object") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("is_object_frozen") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("unfreeze_object") != behaviorContext->m_methods.end());
|
||||
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("delete_object") != behaviorContext->m_methods.end());
|
||||
EXPECT_TRUE(behaviorContext->m_methods.find("delete_selected") != behaviorContext->m_methods.end());
|
||||
|
||||
|
||||
@@ -576,7 +576,6 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
||||
}
|
||||
// Close all edit panels.
|
||||
GetIEditor()->ClearSelection();
|
||||
GetIEditor()->GetObjectManager()->EndEditParams();
|
||||
|
||||
// force clean up of all deferred deletes, so that we don't have any issues with windows from plugins not being deleted yet
|
||||
qApp->sendPostedEvents(nullptr, QEvent::DeferredDelete);
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include "ViewManager.h"
|
||||
#include "IEditorImpl.h"
|
||||
#include "GameEngine.h"
|
||||
#include <IEntityRenderState.h>
|
||||
#include <IStatObj.h>
|
||||
// To use the Andrew's algorithm in order to make convex hull from the points, this header is needed.
|
||||
#include "Util/GeometryUtil.h"
|
||||
|
||||
@@ -53,18 +51,16 @@ class CUndoBaseObject
|
||||
: public IUndoObject
|
||||
{
|
||||
public:
|
||||
CUndoBaseObject(CBaseObject* pObj, const char* undoDescription);
|
||||
CUndoBaseObject(CBaseObject* pObj);
|
||||
|
||||
protected:
|
||||
int GetSize() override { return sizeof(*this); }
|
||||
QString GetDescription() override { return m_undoDescription; };
|
||||
QString GetObjectName() override;
|
||||
|
||||
void Undo(bool bUndo) override;
|
||||
void Redo() override;
|
||||
|
||||
protected:
|
||||
QString m_undoDescription;
|
||||
GUID m_guid;
|
||||
XmlNodeRef m_undo;
|
||||
XmlNodeRef m_redo;
|
||||
@@ -77,11 +73,10 @@ class CUndoBaseObjectMinimal
|
||||
: public IUndoObject
|
||||
{
|
||||
public:
|
||||
CUndoBaseObjectMinimal(CBaseObject* obj, const char* undoDescription, int flags);
|
||||
CUndoBaseObjectMinimal(CBaseObject* obj, int flags);
|
||||
|
||||
protected:
|
||||
int GetSize() override { return sizeof(*this); }
|
||||
QString GetDescription() override { return m_undoDescription; };
|
||||
QString GetObjectName() override;
|
||||
|
||||
void Undo(bool bUndo) override;
|
||||
@@ -101,7 +96,6 @@ private:
|
||||
void SetTransformsFromState(CBaseObject* pObject, const StateStruct& state, bool bUndo);
|
||||
|
||||
GUID m_guid;
|
||||
QString m_undoDescription;
|
||||
StateStruct m_undoState;
|
||||
StateStruct m_redoState;
|
||||
};
|
||||
@@ -167,7 +161,6 @@ private:
|
||||
}
|
||||
|
||||
int GetSize() override { return sizeof(CUndoAttachBaseObject); }
|
||||
QString GetDescription() override { return "Attachment Changed"; }
|
||||
|
||||
GUID m_attachedObjectGUID;
|
||||
GUID m_parentObjectGUID;
|
||||
@@ -176,11 +169,10 @@ private:
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CUndoBaseObject::CUndoBaseObject(CBaseObject* obj, const char* undoDescription)
|
||||
CUndoBaseObject::CUndoBaseObject(CBaseObject* obj)
|
||||
{
|
||||
// Stores the current state of this object.
|
||||
assert(obj != 0);
|
||||
m_undoDescription = undoDescription;
|
||||
m_guid = obj->GetId();
|
||||
|
||||
m_redo = nullptr;
|
||||
@@ -254,11 +246,10 @@ void CUndoBaseObject::Redo()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CUndoBaseObjectMinimal::CUndoBaseObjectMinimal(CBaseObject* pObj, const char* undoDescription, [[maybe_unused]] int flags)
|
||||
CUndoBaseObjectMinimal::CUndoBaseObjectMinimal(CBaseObject* pObj, [[maybe_unused]] int flags)
|
||||
{
|
||||
// Stores the current state of this object.
|
||||
assert(pObj != nullptr);
|
||||
m_undoDescription = undoDescription;
|
||||
m_guid = pObj->GetId();
|
||||
|
||||
ZeroStruct(m_redoState);
|
||||
@@ -287,7 +278,7 @@ QString CUndoBaseObjectMinimal::GetObjectName()
|
||||
void CUndoBaseObjectMinimal::Undo(bool bUndo)
|
||||
{
|
||||
CBaseObject* pObject = GetIEditor()->GetObjectManager()->FindObject(m_guid);
|
||||
if (!pObject || pObject->GetType() == OBJTYPE_DUMMY)
|
||||
if (!pObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -316,7 +307,7 @@ void CUndoBaseObjectMinimal::Undo(bool bUndo)
|
||||
void CUndoBaseObjectMinimal::Redo()
|
||||
{
|
||||
CBaseObject* pObject = GetIEditor()->GetObjectManager()->FindObject(m_guid);
|
||||
if (!pObject || pObject->GetType() == OBJTYPE_DUMMY)
|
||||
if (!pObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -382,7 +373,6 @@ CBaseObject::CBaseObject()
|
||||
, m_rotate(IDENTITY)
|
||||
, m_scale(1, 1, 1)
|
||||
, m_guid(GUID_NULL)
|
||||
, m_floorNumber(-1)
|
||||
, m_flags(0)
|
||||
, m_nTextureIcon(0)
|
||||
, m_color(QColor(255, 255, 255))
|
||||
@@ -398,11 +388,9 @@ CBaseObject::CBaseObject()
|
||||
, m_bMatrixInWorldSpace(false)
|
||||
, m_bMatrixValid(false)
|
||||
, m_bWorldBoxValid(false)
|
||||
, m_nMaterialLayersMask(0)
|
||||
, m_nMinSpec(0)
|
||||
, m_vDrawIconPos(0, 0, 0)
|
||||
, m_nIconFlags(0)
|
||||
, m_hideOrder(CBaseObject::s_invalidHiddenID)
|
||||
{
|
||||
m_worldBounds.min.Set(0, 0, 0);
|
||||
m_worldBounds.max.Set(0, 0, 0);
|
||||
@@ -431,7 +419,6 @@ bool CBaseObject::Init([[maybe_unused]] IEditor* ie, CBaseObject* prev, [[maybe_
|
||||
SetLocalTM(prev->GetPos(), prev->GetRotation(), prev->GetScale());
|
||||
SetArea(prev->GetArea());
|
||||
SetColor(prev->GetColor());
|
||||
m_nMaterialLayersMask = prev->m_nMaterialLayersMask;
|
||||
SetMinSpec(prev->GetMinSpec(), false);
|
||||
|
||||
// Copy all basic variables.
|
||||
@@ -488,7 +475,7 @@ void CBaseObject::SetName(const QString& name)
|
||||
return;
|
||||
}
|
||||
|
||||
StoreUndo("Name");
|
||||
StoreUndo();
|
||||
|
||||
// Notification is expensive and not required if this is during construction.
|
||||
bool notify = (!m_name.isEmpty());
|
||||
@@ -500,7 +487,6 @@ void CBaseObject::SetName(const QString& name)
|
||||
if (notify)
|
||||
{
|
||||
NotifyListeners(ON_RENAME);
|
||||
static_cast<CObjectManager*>(GetIEditor()->GetObjectManager())->NotifyObjectListeners(this, ON_RENAME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,47 +515,6 @@ const QString& CBaseObject::GetName() const
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
QString CBaseObject::GetWarningsText() const
|
||||
{
|
||||
QString warnings;
|
||||
|
||||
if (gSettings.viewports.bShowScaleWarnings)
|
||||
{
|
||||
const EScaleWarningLevel scaleWarningLevel = GetScaleWarningLevel();
|
||||
if (scaleWarningLevel == eScaleWarningLevel_Rescaled)
|
||||
{
|
||||
warnings += "\\n Warning: Object Scale is not 100%.";
|
||||
}
|
||||
else if (scaleWarningLevel == eScaleWarningLevel_RescaledNonUniform)
|
||||
{
|
||||
warnings += "\\n Warning: Object has non-uniform scale.";
|
||||
}
|
||||
}
|
||||
|
||||
if (gSettings.viewports.bShowRotationWarnings)
|
||||
{
|
||||
const ERotationWarningLevel rotationWarningLevel = GetRotationWarningLevel();
|
||||
|
||||
if (rotationWarningLevel == eRotationWarningLevel_Rotated)
|
||||
{
|
||||
warnings += "\\n Warning: Object is rotated.";
|
||||
}
|
||||
else if (rotationWarningLevel == eRotationWarningLevel_RotatedNonRectangular)
|
||||
{
|
||||
warnings += "\\n Warning: Object is rotated non-orthogonally.";
|
||||
}
|
||||
}
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::IsSameClass(CBaseObject* obj)
|
||||
{
|
||||
return GetClassDesc() == obj->GetClassDesc();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::SetPos(const Vec3& pos, int flags)
|
||||
{
|
||||
@@ -615,7 +560,7 @@ bool CBaseObject::SetPos(const Vec3& pos, int flags)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!bPositionDelegated && (flags & eObjectUpdateFlags_RestoreUndo) == 0 && (flags & eObjectUpdateFlags_Animated) == 0)
|
||||
{
|
||||
StoreUndo("Position", true, flags);
|
||||
StoreUndo(true, flags);
|
||||
}
|
||||
|
||||
if (!bPositionDelegated)
|
||||
@@ -659,7 +604,7 @@ bool CBaseObject::SetRotation(const Quat& rotate, int flags)
|
||||
|
||||
if (!bRotationDelegated && (flags & eObjectUpdateFlags_RestoreUndo) == 0 && (flags & eObjectUpdateFlags_Animated) == 0)
|
||||
{
|
||||
StoreUndo("Rotate", true, flags);
|
||||
StoreUndo(true, flags);
|
||||
}
|
||||
|
||||
if (!bRotationDelegated)
|
||||
@@ -704,7 +649,7 @@ bool CBaseObject::SetScale(const Vec3& scale, int flags)
|
||||
|
||||
if (!bScaleDelegated && (flags & eObjectUpdateFlags_RestoreUndo) == 0 && (flags & eObjectUpdateFlags_Animated) == 0)
|
||||
{
|
||||
StoreUndo("Scale", true, flags);
|
||||
StoreUndo(true, flags);
|
||||
}
|
||||
|
||||
if (!bScaleDelegated)
|
||||
@@ -763,7 +708,7 @@ void CBaseObject::ChangeColor(const QColor& color)
|
||||
return;
|
||||
}
|
||||
|
||||
StoreUndo("Color", true);
|
||||
StoreUndo(true);
|
||||
|
||||
SetColor(color);
|
||||
SetModified(false);
|
||||
@@ -783,7 +728,7 @@ void CBaseObject::SetArea(float area)
|
||||
return;
|
||||
}
|
||||
|
||||
StoreUndo("Area", true);
|
||||
StoreUndo(true);
|
||||
|
||||
m_flattenArea = area;
|
||||
SetModified(false);
|
||||
@@ -1183,47 +1128,6 @@ bool CBaseObject::CanBeDrawn(const DisplayContext& dc, bool& outDisplaySelection
|
||||
return bResult;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CBaseObject::MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Editor);
|
||||
|
||||
if (event == eMouseMove || event == eMouseLDown)
|
||||
{
|
||||
Vec3 pos;
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld(point, &hitTerrain);
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x, pos.y) + 1.0f;
|
||||
}
|
||||
pos = view->SnapToGrid(pos);
|
||||
}
|
||||
SetPos(pos);
|
||||
|
||||
if (event == eMouseLDown)
|
||||
{
|
||||
return MOUSECREATE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (event == eMouseWheel)
|
||||
{
|
||||
float angle = 1;
|
||||
Quat rot = GetRotation();
|
||||
rot.SetRotationXYZ(Ang3(0.f, 0.f, rot.GetRotZ() + DEG2RAD(flags > 0 ? angle * (-1) : angle)));
|
||||
SetRotation(rot);
|
||||
}
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::OnEvent(ObjectEvent event)
|
||||
{
|
||||
@@ -1237,18 +1141,13 @@ void CBaseObject::OnEvent(ObjectEvent event)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::SetShared([[maybe_unused]] bool bShared)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::SetHidden(bool bHidden, uint64 hiddenID, bool bAnimated)
|
||||
void CBaseObject::SetHidden(bool bHidden, bool bAnimated)
|
||||
{
|
||||
if (CheckFlags(OBJFLAG_HIDDEN) != bHidden)
|
||||
{
|
||||
if (!bAnimated)
|
||||
{
|
||||
StoreUndo("Hide Object");
|
||||
StoreUndo();
|
||||
}
|
||||
|
||||
if (bHidden)
|
||||
@@ -1260,7 +1159,6 @@ void CBaseObject::SetHidden(bool bHidden, uint64 hiddenID, bool bAnimated)
|
||||
ClearFlags(OBJFLAG_HIDDEN);
|
||||
}
|
||||
|
||||
m_hideOrder = hiddenID;
|
||||
UpdateVisibility(!IsHidden());
|
||||
}
|
||||
}
|
||||
@@ -1270,7 +1168,7 @@ void CBaseObject::SetFrozen(bool bFrozen)
|
||||
{
|
||||
if (CheckFlags(OBJFLAG_FROZEN) != bFrozen)
|
||||
{
|
||||
StoreUndo("Freeze Object");
|
||||
StoreUndo();
|
||||
if (bFrozen)
|
||||
{
|
||||
SetFlags(OBJFLAG_FROZEN);
|
||||
@@ -1356,14 +1254,6 @@ void CBaseObject::Serialize(CObjectArchive& ar)
|
||||
if (ar.bLoading)
|
||||
{
|
||||
// Loading.
|
||||
if (ar.ShouldResetInternalMembers())
|
||||
{
|
||||
m_flags = 0;
|
||||
m_flattenArea = 0.0f;
|
||||
m_nMinSpec = 0;
|
||||
m_scale.Set(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
int oldFlags = m_flags;
|
||||
|
||||
@@ -1403,7 +1293,6 @@ void CBaseObject::Serialize(CObjectArchive& ar)
|
||||
xmlNode->getAttr("LookAt", lookatId);
|
||||
xmlNode->getAttr("Material", mtlName);
|
||||
xmlNode->getAttr("MinSpec", nMinSpec);
|
||||
xmlNode->getAttr("FloorNumber", m_floorNumber);
|
||||
|
||||
if (nMinSpec <= CONFIG_VERYHIGH_SPEC) // Ignore invalid values.
|
||||
{
|
||||
@@ -1467,18 +1356,6 @@ void CBaseObject::Serialize(CObjectArchive& ar)
|
||||
SetModified(false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (ar.bUndo)
|
||||
{
|
||||
// If we are selected update UI Panel.
|
||||
xmlNode->getAttr("HideOrder", m_hideOrder);
|
||||
}
|
||||
|
||||
// We reseted the min spec and deserialized it so set it internally
|
||||
if (ar.ShouldResetInternalMembers())
|
||||
{
|
||||
SetMinSpec(m_nMinSpec);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1490,7 +1367,6 @@ void CBaseObject::Serialize(CObjectArchive& ar)
|
||||
xmlNode->setAttr("Id", m_guid);
|
||||
|
||||
xmlNode->setAttr("Name", GetName().toUtf8().data());
|
||||
xmlNode->setAttr("HideOrder", m_hideOrder);
|
||||
|
||||
if (m_parent)
|
||||
{
|
||||
@@ -1507,8 +1383,6 @@ void CBaseObject::Serialize(CObjectArchive& ar)
|
||||
xmlNode->setAttr("Pos", GetPos());
|
||||
}
|
||||
|
||||
xmlNode->setAttr("FloorNumber", m_floorNumber);
|
||||
|
||||
xmlNode->setAttr("Rotate", m_rotate);
|
||||
|
||||
if (!IsEquivalent(GetScale(), Vec3(1, 1, 1), 0))
|
||||
@@ -1601,13 +1475,8 @@ CBaseObject* CBaseObject::FindObject(REFGUID id) const
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::StoreUndo(const char* UndoDescription, bool minimal, int flags)
|
||||
void CBaseObject::StoreUndo(bool minimal, int flags)
|
||||
{
|
||||
if (m_objType == OBJTYPE_DUMMY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't use Sandbox undo for AZ entities, except for the move & scale tools, which rely on it.
|
||||
const bool isGizmoTool = 0 != (flags & (eObjectUpdateFlags_MoveTool | eObjectUpdateFlags_ScaleTool | eObjectUpdateFlags_UserInput));
|
||||
if (!isGizmoTool && 0 != (m_flags & OBJFLAG_DONT_SAVE))
|
||||
@@ -1619,28 +1488,18 @@ void CBaseObject::StoreUndo(const char* UndoDescription, bool minimal, int flags
|
||||
{
|
||||
if (minimal)
|
||||
{
|
||||
CUndo::Record(new CUndoBaseObjectMinimal(this, UndoDescription, flags));
|
||||
CUndo::Record(new CUndoBaseObjectMinimal(this, flags));
|
||||
}
|
||||
else
|
||||
{
|
||||
CUndo::Record(new CUndoBaseObject(this, UndoDescription));
|
||||
CUndo::Record(new CUndoBaseObject(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::IsCreateGameObjects() const
|
||||
{
|
||||
return GetObjectManager()->IsCreateGameObjects();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
QString CBaseObject::GetTypeName() const
|
||||
{
|
||||
if (m_objType == OBJTYPE_DUMMY)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QString className = m_classDesc->ClassName();
|
||||
QString subClassName = strstr(className.toUtf8().data(), "::");
|
||||
if (subClassName.isEmpty())
|
||||
@@ -1901,85 +1760,6 @@ bool CBaseObject::HitTestRect(HitContext& hc)
|
||||
return bHit;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::HitHelperTest(HitContext& hc)
|
||||
{
|
||||
return HitHelperAtTest(hc, GetWorldPos());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::HitHelperAtTest(HitContext& hc, const Vec3& pos)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Editor);
|
||||
|
||||
bool bResult = false;
|
||||
|
||||
if (m_nTextureIcon && (gSettings.viewports.bShowIcons || gSettings.viewports.bShowSizeBasedIcons) && !hc.bUseSelectionHelpers)
|
||||
{
|
||||
int iconSizeX = OBJECT_TEXTURE_ICON_SIZEX;
|
||||
int iconSizeY = OBJECT_TEXTURE_ICON_SIZEY;
|
||||
|
||||
if (gSettings.viewports.bDistanceScaleIcons)
|
||||
{
|
||||
float fScreenScale = hc.view->GetScreenScaleFactor(pos);
|
||||
|
||||
iconSizeX = static_cast<int>(static_cast<float>(iconSizeX) * OBJECT_TEXTURE_ICON_SCALE / fScreenScale);
|
||||
iconSizeY = static_cast<int>(static_cast<float>(iconSizeY) * OBJECT_TEXTURE_ICON_SCALE / fScreenScale);
|
||||
}
|
||||
|
||||
// Hit Test icon of this object.
|
||||
Vec3 testPos = pos;
|
||||
int y0 = -(iconSizeY / 2);
|
||||
int y1 = +(iconSizeY / 2);
|
||||
if (CheckFlags(OBJFLAG_SHOW_ICONONTOP))
|
||||
{
|
||||
Vec3 objectPos = GetWorldPos();
|
||||
|
||||
AABB box;
|
||||
GetBoundBox(box);
|
||||
testPos.z = (pos.z - objectPos.z) + box.max.z;
|
||||
y0 = -(iconSizeY);
|
||||
y1 = 0;
|
||||
}
|
||||
QPoint pnt = hc.view->WorldToView(testPos);
|
||||
|
||||
if (hc.point2d.x() >= pnt.x() - (iconSizeX / 2) && hc.point2d.x() <= pnt.x() + (iconSizeX / 2) &&
|
||||
hc.point2d.y() >= pnt.y() + y0 && hc.point2d.y() <= pnt.y() + y1)
|
||||
{
|
||||
hc.dist = hc.raySrc.GetDistance(testPos) - 0.2f;
|
||||
hc.iconHit = true;
|
||||
bResult = true;
|
||||
}
|
||||
}
|
||||
else if (hc.bUseSelectionHelpers)
|
||||
{
|
||||
// Check potentially children first
|
||||
bResult = HitHelperTestForChildObjects(hc);
|
||||
|
||||
// If no hit check this object
|
||||
if (!bResult)
|
||||
{
|
||||
// Hit test helper.
|
||||
Vec3 w = pos - hc.raySrc;
|
||||
w = hc.rayDir.Cross(w);
|
||||
float d = w.GetLengthSquared();
|
||||
|
||||
static const float screenScaleToRadiusFactor = 0.008f;
|
||||
const float radius = hc.view->GetScreenScaleFactor(pos) * screenScaleToRadiusFactor;
|
||||
const float pickDistance = hc.raySrc.GetDistance(pos);
|
||||
if (d < radius * radius + hc.distanceTolerance && hc.dist >= pickDistance)
|
||||
{
|
||||
hc.dist = pickDistance;
|
||||
hc.object = this;
|
||||
bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CBaseObject::GetChild(size_t const i) const
|
||||
{
|
||||
@@ -1987,47 +1767,6 @@ CBaseObject* CBaseObject::GetChild(size_t const i) const
|
||||
return m_childs[i];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::IsChildOf(CBaseObject* node)
|
||||
{
|
||||
CBaseObject* p = m_parent;
|
||||
while (p && p != node)
|
||||
{
|
||||
p = p->m_parent;
|
||||
}
|
||||
if (p == node)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::CloneChildren(CBaseObject* pFromObject)
|
||||
{
|
||||
if (pFromObject == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0, nChildCount(pFromObject->GetChildCount()); i < nChildCount; ++i)
|
||||
{
|
||||
CBaseObject* pFromChildObject = pFromObject->GetChild(i);
|
||||
|
||||
CBaseObject* pChildClone = GetObjectManager()->CloneObject(pFromChildObject);
|
||||
if (pChildClone == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pChildClone->CloneChildren(pFromChildObject);
|
||||
AddMember(pChildClone, false);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::AttachChild(CBaseObject* child, bool bKeepPos)
|
||||
{
|
||||
@@ -2044,7 +1783,6 @@ void CBaseObject::AttachChild(CBaseObject* child, bool bKeepPos)
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<CObjectManager*>(GetObjectManager())->NotifyObjectListeners(child, ON_PREATTACHED);
|
||||
child->NotifyListeners(bKeepPos ? ON_PREATTACHEDKEEPXFORM : ON_PREATTACHED);
|
||||
|
||||
pTransformDelegate = m_pTransformDelegate;
|
||||
@@ -2089,7 +1827,6 @@ void CBaseObject::AttachChild(CBaseObject* child, bool bKeepPos)
|
||||
m_pTransformDelegate = pTransformDelegate;
|
||||
child->m_pTransformDelegate = pChildTransformDelegate;
|
||||
|
||||
static_cast<CObjectManager*>(GetObjectManager())->NotifyObjectListeners(child, ON_ATTACHED);
|
||||
child->NotifyListeners(ON_ATTACHED);
|
||||
|
||||
NotifyListeners(ON_CHILDATTACHED);
|
||||
@@ -2127,7 +1864,6 @@ void CBaseObject::DetachThis(bool bKeepPos)
|
||||
|
||||
{
|
||||
CScopedSuspendUndo suspendUndo;
|
||||
static_cast<CObjectManager*>(GetObjectManager())->NotifyObjectListeners(this, ON_PREDETACHED);
|
||||
NotifyListeners(bKeepPos ? ON_PREDETACHEDKEEPXFORM : ON_PREDETACHED);
|
||||
|
||||
pTransformDelegate = m_pTransformDelegate;
|
||||
@@ -2158,7 +1894,6 @@ void CBaseObject::DetachThis(bool bKeepPos)
|
||||
|
||||
SetTransformDelegate(pTransformDelegate);
|
||||
|
||||
static_cast<CObjectManager*>(GetObjectManager())->NotifyObjectListeners(this, ON_DETACHED);
|
||||
NotifyListeners(ON_DETACHED);
|
||||
}
|
||||
}
|
||||
@@ -2262,12 +1997,6 @@ Matrix34 CBaseObject::GetParentAttachPointWorldTM() const
|
||||
return Matrix34(IDENTITY);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::IsParentAttachmentValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::InvalidateTM([[maybe_unused]] int flags)
|
||||
{
|
||||
@@ -2418,7 +2147,7 @@ void CBaseObject::SetLookAt(CBaseObject* target)
|
||||
return;
|
||||
}
|
||||
|
||||
StoreUndo("Change LookAt");
|
||||
StoreUndo();
|
||||
|
||||
if (m_lookat)
|
||||
{
|
||||
@@ -2543,63 +2272,6 @@ void CBaseObject::Validate(IErrorReport* report)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Ang3 CBaseObject::GetWorldAngles() const
|
||||
{
|
||||
if (m_scale == Vec3(1, 1, 1))
|
||||
{
|
||||
Quat q = Quat(GetWorldTM());
|
||||
Ang3 angles = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(q)));
|
||||
return angles;
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix34 tm = GetWorldTM();
|
||||
tm.OrthonormalizeFast();
|
||||
Quat q = Quat(tm);
|
||||
Ang3 angles = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(q)));
|
||||
return angles;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::PostClone(CBaseObject* pFromObject, CObjectCloneContext& ctx)
|
||||
{
|
||||
CBaseObject* pFromParent = pFromObject->GetParent();
|
||||
if (pFromParent)
|
||||
{
|
||||
SetFloorNumber(pFromObject->GetFloorNumber());
|
||||
|
||||
CBaseObject* pFromParentInContext = ctx.FindClone(pFromParent);
|
||||
if (pFromParentInContext)
|
||||
{
|
||||
pFromParentInContext->AddMember(this, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
pFromParent->AddMember(this, false);
|
||||
}
|
||||
}
|
||||
if (pFromObject->ShouldCloneChildren())
|
||||
{
|
||||
for (int i = 0; i < pFromObject->GetChildCount(); i++)
|
||||
{
|
||||
CBaseObject* pChildObject = pFromObject->GetChild(i);
|
||||
CBaseObject* pClonedChild = GetObjectManager()->CloneObject(pChildObject);
|
||||
ctx.AddClone(pChildObject, pClonedChild);
|
||||
}
|
||||
for (int i = 0; i < pFromObject->GetChildCount(); i++)
|
||||
{
|
||||
CBaseObject* pChildObject = pFromObject->GetChild(i);
|
||||
CBaseObject* pClonedChild = ctx.FindClone(pChildObject);
|
||||
if (pClonedChild)
|
||||
{
|
||||
pClonedChild->PostClone(pChildObject, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::GatherUsedResources(CUsedResources& resources)
|
||||
{
|
||||
@@ -2635,79 +2307,6 @@ void CBaseObject::SetMinSpec(uint32 nSpec, bool bSetChildren)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::OnPropertyChanged(IVariable*)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::OnMultiSelPropertyChanged(IVariable*)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::OnMenuShowInAssetBrowser()
|
||||
{
|
||||
if (!IsSelected())
|
||||
{
|
||||
CUndo undo("Select Object");
|
||||
GetIEditor()->GetObjectManager()->ClearSelection();
|
||||
GetIEditor()->SelectObject(this);
|
||||
}
|
||||
|
||||
GetIEditor()->ExecuteCommand("asset_browser.show_viewport_selection");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBaseObject::OnContextMenu(QMenu* menu)
|
||||
{
|
||||
if (!menu->isEmpty())
|
||||
{
|
||||
menu->addSeparator();
|
||||
}
|
||||
CUsedResources resources;
|
||||
GatherUsedResources(resources);
|
||||
|
||||
static_cast<CEditorImpl*>(GetIEditor())->OnObjectContextMenuOpened(menu, this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CBaseObject::IntersectRayMesh(const Vec3& raySrc, const Vec3& rayDir, SRayHitInfo& outHitInfo) const
|
||||
{
|
||||
const float fRenderMeshTestDistance = 0.2f;
|
||||
IRenderNode* pRenderNode = GetEngineNode();
|
||||
if (!pRenderNode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Matrix34 worldTM;
|
||||
IStatObj* pStatObj = pRenderNode->GetEntityStatObj(0, 0, &worldTM);
|
||||
if (!pStatObj)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// transform decal into object space
|
||||
Matrix34 worldTM_Inverted = worldTM.GetInverted();
|
||||
Matrix33 worldRot(worldTM_Inverted);
|
||||
worldRot.Transpose();
|
||||
// put hit direction into the object space
|
||||
Vec3 vRayDir = rayDir.GetNormalized() * worldRot;
|
||||
// put hit position into the object space
|
||||
Vec3 vHitPos = worldTM_Inverted.TransformPoint(raySrc);
|
||||
Vec3 vLineP1 = vHitPos - vRayDir * fRenderMeshTestDistance;
|
||||
|
||||
memset(&outHitInfo, 0, sizeof(outHitInfo));
|
||||
outHitInfo.inReferencePoint = vHitPos;
|
||||
outHitInfo.inRay.origin = vLineP1;
|
||||
outHitInfo.inRay.direction = vRayDir;
|
||||
outHitInfo.bInFirstHit = false;
|
||||
outHitInfo.bUseCache = false;
|
||||
|
||||
return pStatObj->RayIntersection(outHitInfo, nullptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
EScaleWarningLevel CBaseObject::GetScaleWarningLevel() const
|
||||
{
|
||||
|
||||
@@ -35,8 +35,6 @@ struct SSubObjSelectionModifyContext;
|
||||
struct SRayHitInfo;
|
||||
class CPopupMenuItem;
|
||||
class QMenu;
|
||||
struct IRenderNode;
|
||||
struct IStatObj;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef _smart_ptr<CBaseObject> CBaseObjectPtr;
|
||||
@@ -119,15 +117,6 @@ enum ObjectFlags
|
||||
|
||||
#define ERF_GET_WRITABLE(flags) (flags)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! This flags passed to CBaseObject::BeginEditParams method.
|
||||
enum ObjectEditFlags
|
||||
{
|
||||
OBJECT_CREATE = 0x001,
|
||||
OBJECT_EDIT = 0x002,
|
||||
OBJECT_COLLAPSE_OBJECTPANEL = 0x004
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Return values from CBaseObject::MouseCreateCallback method.
|
||||
enum MouseCreateResult
|
||||
@@ -137,19 +126,6 @@ enum MouseCreateResult
|
||||
MOUSECREATE_OK, //!< Accept this object.
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Interface to the object create with the mouse callback.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct IMouseCreateCallback
|
||||
{
|
||||
virtual void Release() = 0;
|
||||
virtual MouseCreateResult OnMouseEvent(CViewport* view, EMouseEvent event, QPoint& point, int flags) = 0;
|
||||
// Some process of creation need to be able to be displayed such as creation for custom solid.
|
||||
virtual void Display([[maybe_unused]] DisplayContext& dc){}
|
||||
// Called after accepting an object to see if new object creation mode should be continued.
|
||||
virtual bool ContinueCreation() = 0;
|
||||
};
|
||||
|
||||
// Flags used for object interaction
|
||||
enum EObjectUpdateFlags
|
||||
{
|
||||
@@ -261,22 +237,11 @@ public:
|
||||
|
||||
/** Check if both object are of same class.
|
||||
*/
|
||||
virtual bool IsSameClass(CBaseObject* obj);
|
||||
virtual void SetDefaultType() { m_objType = OBJTYPE_DUMMY; };
|
||||
virtual ObjectType GetType() const
|
||||
{
|
||||
if (m_objType == OBJTYPE_DUMMY)
|
||||
{
|
||||
return m_objType;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_classDesc->GetObjectType();
|
||||
}
|
||||
return m_classDesc->GetObjectType();
|
||||
};
|
||||
// const char* GetTypeName() const { return m_classDesc->ClassName(); };
|
||||
QString GetTypeName() const;
|
||||
virtual QString GetTypeDescription() const { return m_classDesc->ClassName(); };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Flags.
|
||||
@@ -289,8 +254,6 @@ public:
|
||||
// Hidden ID
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static const uint64 s_invalidHiddenID = 0;
|
||||
uint64 GetHideOrder() const { return m_hideOrder; }
|
||||
void SetHideOrder(uint64 newID) { m_hideOrder = newID; }
|
||||
|
||||
//! Returns true if object hidden.
|
||||
bool IsHidden() const;
|
||||
@@ -307,26 +270,19 @@ public:
|
||||
virtual bool IsSelectable() const;
|
||||
|
||||
// Return texture icon.
|
||||
bool HaveTextureIcon() const { return m_nTextureIcon != 0; };
|
||||
int GetTextureIcon() const { return m_nTextureIcon; }
|
||||
void SetTextureIcon(int nTexIcon) { m_nTextureIcon = nTexIcon; }
|
||||
|
||||
//! Set shared between missions flag.
|
||||
virtual void SetShared(bool bShared);
|
||||
//! Set object hidden status.
|
||||
virtual void SetHidden(bool bHidden, uint64 hiddenId = CBaseObject::s_invalidHiddenID, bool bAnimated = false);
|
||||
virtual void SetHidden(bool bHidden, bool bAnimated = false);
|
||||
//! Set object frozen status.
|
||||
virtual void SetFrozen(bool bFrozen);
|
||||
//! Set object selected status.
|
||||
virtual void SetSelected(bool bSelect);
|
||||
//! Return associated 3DEngine render node
|
||||
virtual IRenderNode* GetEngineNode() const { return nullptr; };
|
||||
//! Set object highlighted (Note: not selected)
|
||||
virtual void SetHighlight(bool bHighlight);
|
||||
//! Check if object is highlighted.
|
||||
bool IsHighlighted() const { return CheckFlags(OBJFLAG_HIGHLIGHT); }
|
||||
//! Check if object can have measurement axises.
|
||||
virtual bool HasMeasurementAxis() const { return true; }
|
||||
//! Check if the object is isolated when the editor is in Isolation Mode
|
||||
virtual bool IsIsolated() const { return false; }
|
||||
|
||||
@@ -345,8 +301,6 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Get name of object.
|
||||
const QString& GetName() const;
|
||||
virtual QString GetComment() const { return QString(); }
|
||||
virtual QString GetWarningsText() const;
|
||||
|
||||
//! Change name of object.
|
||||
virtual void SetName(const QString& name);
|
||||
@@ -376,10 +330,6 @@ public:
|
||||
//! Get object scale.
|
||||
const Vec3 GetScale() const;
|
||||
|
||||
virtual bool StartScaling() { return false; }
|
||||
virtual bool GetUntransformedScale([[maybe_unused]] Vec3& scale) const { return false; }
|
||||
virtual bool TransformScale([[maybe_unused]] const Vec3& scale) { return false; }
|
||||
|
||||
//! Set flatten area.
|
||||
void SetArea(float area);
|
||||
float GetArea() const { return m_flattenArea; };
|
||||
@@ -397,8 +347,6 @@ public:
|
||||
// CHILDS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Return true if node have childs.
|
||||
bool HaveChilds() const { return !m_childs.empty(); }
|
||||
//! Return true if have attached childs.
|
||||
size_t GetChildCount() const { return m_childs.size(); }
|
||||
|
||||
@@ -406,10 +354,6 @@ public:
|
||||
CBaseObject* GetChild(size_t const i) const;
|
||||
//! Return parent node if exist.
|
||||
CBaseObject* GetParent() const { return m_parent; };
|
||||
//! Scans hierarchy up to determine if we child of specified node.
|
||||
virtual bool IsChildOf(CBaseObject* node);
|
||||
//! Clone Children
|
||||
void CloneChildren(CBaseObject* pFromObject);
|
||||
//! Attach new child node.
|
||||
//! @param bKeepPos if true Child node will keep its world space position.
|
||||
virtual void AttachChild(CBaseObject* child, bool bKeepPos = true);
|
||||
@@ -422,8 +366,6 @@ public:
|
||||
virtual void DetachAll(bool bKeepPos = true);
|
||||
// Detach this node from parent.
|
||||
virtual void DetachThis(bool bKeepPos = true);
|
||||
// Returns the link parent.
|
||||
virtual CBaseObject* GetLinkParent() const { return GetParent(); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MATRIX
|
||||
@@ -437,15 +379,11 @@ public:
|
||||
// Gets matrix of parent attachment point
|
||||
virtual Matrix34 GetParentAttachPointWorldTM() const;
|
||||
|
||||
// Checks if the attachment point is valid
|
||||
virtual bool IsParentAttachmentValid() const;
|
||||
|
||||
//! Set position in world space.
|
||||
virtual void SetWorldPos(const Vec3& pos, int flags = 0);
|
||||
|
||||
//! Get position in world space.
|
||||
Vec3 GetWorldPos() const { return GetWorldTM().GetTranslation(); };
|
||||
Ang3 GetWorldAngles() const;
|
||||
|
||||
//! Set xform of object given in world space.
|
||||
virtual void SetWorldTM(const Matrix34& tm, int flags = 0);
|
||||
@@ -460,12 +398,6 @@ public:
|
||||
// Interface to be implemented in plugins.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Called when object is being created (use GetMouseCreateCallback for more advanced mouse creation callback).
|
||||
virtual int MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags);
|
||||
// Return pointer to the callback object used when creating object by the mouse.
|
||||
// If this function return nullptr MouseCreateCallback method will be used instead.
|
||||
virtual IMouseCreateCallback* GetMouseCreateCallback() { return nullptr; };
|
||||
|
||||
//! Draw object to specified viewport.
|
||||
virtual void Display([[maybe_unused]] DisplayContext& disp) {}
|
||||
|
||||
@@ -477,10 +409,6 @@ public:
|
||||
//! Return true if was hit.
|
||||
virtual bool HitTestRect(HitContext& hc);
|
||||
|
||||
//! Perform intersection testing of this object based on its icon helper.
|
||||
//! Return true if was hit.
|
||||
virtual bool HitHelperTest(HitContext& hc);
|
||||
|
||||
//! Get bounding box of object in world coordinate space.
|
||||
virtual void GetBoundBox(AABB& box);
|
||||
|
||||
@@ -500,8 +428,6 @@ public:
|
||||
//! @param bUndo true if loading or saving data for Undo/Redo purposes.
|
||||
virtual void Serialize(CObjectArchive& ar);
|
||||
|
||||
//// Pre load called before serialize after all objects where completly loaded.
|
||||
//virtual void PreLoad( CObjectArchive &ar ) {};
|
||||
// Post load called after all objects where completely loaded.
|
||||
virtual void PostLoad([[maybe_unused]] CObjectArchive& ar) {};
|
||||
|
||||
@@ -513,9 +439,6 @@ public:
|
||||
//! Override in derived classes, to handle specific events.
|
||||
virtual void OnEvent(ObjectEvent event);
|
||||
|
||||
//! Generate dynamic context menu for the object
|
||||
virtual void OnContextMenu(QMenu* menu);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// LookAt Target.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -523,13 +446,11 @@ public:
|
||||
CBaseObject* GetLookAt() const { return m_lookat; };
|
||||
//! Returns true if this object is a look-at target.
|
||||
bool IsLookAtTarget() const;
|
||||
CBaseObject* GetLookAtSource() const { return m_lookatSource; };
|
||||
|
||||
|
||||
IObjectManager* GetObjectManager() const;
|
||||
|
||||
//! Store undo information for this object.
|
||||
void StoreUndo(const char* undoDescription, bool minimal = false, int flags = 0);
|
||||
void StoreUndo(bool minimal = false, int flags = 0);
|
||||
|
||||
//! Add event listener callback.
|
||||
void AddEventListener(EventListener* listener);
|
||||
@@ -548,52 +469,21 @@ public:
|
||||
//! Check if specified object is very similar to this one.
|
||||
virtual bool IsSimilarObject(CBaseObject* pObject);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Material Layers Mask.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetMaterialLayersMask(uint32 nLayersMask) { m_nMaterialLayersMask = nLayersMask; }
|
||||
uint32 GetMaterialLayersMask() const { return m_nMaterialLayersMask; };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Object minimal usage spec (All/Low/Medium/High)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
uint32 GetMinSpec() const { return m_nMinSpec; }
|
||||
virtual void SetMinSpec(uint32 nSpec, bool bSetChildren = true);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SubObj selection.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Return true if object support selecting of this sub object element type.
|
||||
virtual bool StartSubObjSelection([[maybe_unused]] int elemType) { return false; };
|
||||
virtual void EndSubObjectSelection() {};
|
||||
virtual void ModifySubObjSelection([[maybe_unused]] SSubObjSelectionModifyContext& modCtx) {};
|
||||
virtual void AcceptSubObjectModify() {};
|
||||
|
||||
//! In This function variables of the object must be initialized.
|
||||
virtual void InitVariables() {};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Procedural Floor Management.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int GetFloorNumber() const { return m_floorNumber; };
|
||||
void SetFloorNumber(int floorNumber) { m_floorNumber = floorNumber; };
|
||||
|
||||
virtual void OnPropertyChanged(IVariable*);
|
||||
virtual void OnMultiSelPropertyChanged(IVariable*);
|
||||
|
||||
//! Draw a reddish highlight indicating its budget usage.
|
||||
virtual void DrawBudgetUsage(DisplayContext& dc, const QColor& color);
|
||||
|
||||
bool IntersectRayMesh(const Vec3& raySrc, const Vec3& rayDir, SRayHitInfo& outHitInfo) const;
|
||||
|
||||
virtual void EditTags([[maybe_unused]] bool alwaysTag) {}
|
||||
virtual bool SupportsEditTags() const { return false; }
|
||||
|
||||
bool CanBeHightlighted() const;
|
||||
bool IsSkipSelectionHelper() const;
|
||||
|
||||
virtual IStatObj* GetIStatObj() { return nullptr; }
|
||||
|
||||
// Invalidates cached transformation matrix.
|
||||
// nWhyFlags - Flags that indicate the reason for matrix invalidation.
|
||||
virtual void InvalidateTM(int nWhyFlags);
|
||||
@@ -612,26 +502,14 @@ protected:
|
||||
//! Optional file parameter specify initial object or script for this object.
|
||||
virtual bool Init(IEditor* ie, CBaseObject* prev, const QString& file);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Must be called after cloning the object on clone of object.
|
||||
//! This will make sure object references are cloned correctly.
|
||||
virtual void PostClone(CBaseObject* pFromObject, CObjectCloneContext& ctx);
|
||||
|
||||
//! Must be implemented by derived class to create game related objects.
|
||||
virtual bool CreateGameObject() { return true; };
|
||||
|
||||
//! If true, all attached chilren will be cloned when the parent object is cloned.
|
||||
virtual bool ShouldCloneChildren() const { return true; }
|
||||
|
||||
/** Called when object is about to be deleted.
|
||||
All Game resources should be freed in this function.
|
||||
All Game resources should be freed in this function.
|
||||
*/
|
||||
virtual void Done();
|
||||
|
||||
/** Change current id of object.
|
||||
*/
|
||||
//virtual void SetId( uint32 objectId ) { m_id = objectId; };
|
||||
|
||||
//! Call this to delete an object.
|
||||
virtual void DeleteThis() = 0;
|
||||
|
||||
@@ -682,17 +560,11 @@ protected:
|
||||
// Function can be used by derived classes.
|
||||
bool HitTestRectBounds(HitContext& hc, const AABB& box);
|
||||
|
||||
// Do helper hit testing as specific location.
|
||||
bool HitHelperAtTest(HitContext& hc, const Vec3& pos);
|
||||
|
||||
// Do helper hit testing taking child objects into account (e.g. opened prefab)
|
||||
virtual bool HitHelperTestForChildObjects([[maybe_unused]] HitContext& hc) { return false; }
|
||||
|
||||
CBaseObject* FindObject(REFGUID id) const;
|
||||
|
||||
// Returns true if game objects should be created.
|
||||
bool IsCreateGameObjects() const;
|
||||
|
||||
// Helper gizmo functions.
|
||||
void AddGizmo(CGizmo* gizmo);
|
||||
void RemoveGizmo(CGizmo* gizmo);
|
||||
@@ -703,14 +575,6 @@ protected:
|
||||
//! Only used by ObjectManager.
|
||||
bool IsPotentiallyVisible() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// May be overridden in derived classes to handle helpers scaling.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual void SetHelperScale([[maybe_unused]] float scale) {};
|
||||
virtual float GetHelperScale() { return 1.0f; };
|
||||
|
||||
void SetNameInternal(const QString& name) { m_name = name; }
|
||||
|
||||
void SetDrawTextureIconProperties(DisplayContext& dc, const Vec3& pos, float alpha = 1.0f, int texIconFlags = 0);
|
||||
const Vec3& GetTextureIconDrawPos(){ return m_vDrawIconPos; };
|
||||
int GetTextureIconFlags(){ return m_nIconFlags; };
|
||||
@@ -732,8 +596,6 @@ private:
|
||||
friend class CObjectArchive;
|
||||
friend class CSelectionGroup;
|
||||
|
||||
void OnMenuShowInAssetBrowser();
|
||||
|
||||
//! Set class description for this object,
|
||||
//! Only called once after creation by ObjectManager.
|
||||
void SetClassDesc(CObjectClassDesc* classDesc);
|
||||
@@ -741,9 +603,6 @@ private:
|
||||
EScaleWarningLevel GetScaleWarningLevel() const;
|
||||
ERotationWarningLevel GetRotationWarningLevel() const;
|
||||
|
||||
// auto resolving
|
||||
void OnMtlResolved(uint32 id, bool success, const char* orgName, const char* newName);
|
||||
|
||||
bool IsInSelectionBox() const { return m_bInSelectionBox; }
|
||||
|
||||
void SetId(REFGUID guid) { m_guid = guid; }
|
||||
@@ -766,13 +625,10 @@ private:
|
||||
//! Unique object Id.
|
||||
GUID m_guid;
|
||||
|
||||
// floor number of object if procedural object flag is set
|
||||
int m_floorNumber;
|
||||
|
||||
//! Flags of this object.
|
||||
int m_flags;
|
||||
|
||||
// Id of the texture icon for this object.
|
||||
//! Id of the texture icon for this object.
|
||||
int m_nTextureIcon;
|
||||
|
||||
//! Display color.
|
||||
@@ -823,13 +679,10 @@ private:
|
||||
mutable uint32 m_bMatrixValid : 1;
|
||||
mutable uint32 m_bWorldBoxValid : 1;
|
||||
uint32 m_bInSelectionBox : 1;
|
||||
uint32 m_nMaterialLayersMask : 8;
|
||||
uint32 m_nMinSpec : 8;
|
||||
|
||||
Vec3 m_vDrawIconPos;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
uint64 m_hideOrder;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(CBaseObject*)
|
||||
|
||||
@@ -81,11 +81,38 @@ struct SANDBOX_API DisplayContext
|
||||
// Draw functions
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Set current materialc color.
|
||||
void SetColor(float r, float g, float b, float a = 1) { m_color4b = ColorB(static_cast<uint8>(r * 255.0f), static_cast<uint8>(g * 255.0f), static_cast<uint8>(b * 255.0f), static_cast<uint8>(a * 255.0f)); };
|
||||
void SetColor(const Vec3& color, float a = 1) { m_color4b = ColorB(static_cast<uint8>(color.x * 255.0f), static_cast<uint8>(color.y * 255.0f), static_cast<uint8>(color.z * 255.0f), static_cast<uint8>(a * 255.0f)); };
|
||||
void SetColor(const QColor& rgb, float a) { m_color4b = ColorB(static_cast<uint8>(rgb.red()), static_cast<uint8>(rgb.green()), static_cast<uint8>(rgb.blue()), static_cast<uint8>(a * 255.0f)); };
|
||||
void SetColor(const QColor& color) { m_color4b = ColorB(static_cast<uint8>(color.red()), static_cast<uint8>(color.green()), static_cast<uint8>(color.blue()), static_cast<uint8>(color.alpha())); };
|
||||
void SetColor(const ColorB& color) { m_color4b = color; };
|
||||
void SetColor(float r, float g, float b, float a = 1)
|
||||
{
|
||||
m_color4b = ColorB(
|
||||
static_cast<uint8>(r * 255.0f), static_cast<uint8>(g * 255.0f), static_cast<uint8>(b * 255.0f), static_cast<uint8>(a * 255.0f));
|
||||
};
|
||||
void SetColor(const Vec3& color, float a = 1)
|
||||
{
|
||||
m_color4b = ColorB(
|
||||
static_cast<uint8>(color.x * 255.0f), static_cast<uint8>(color.y * 255.0f), static_cast<uint8>(color.z * 255.0f),
|
||||
static_cast<uint8>(a * 255.0f));
|
||||
};
|
||||
void SetColor(const AZ::Vector3& color, float a = 1)
|
||||
{
|
||||
m_color4b = ColorB(
|
||||
static_cast<uint8>(color.GetX() * 255.0f), static_cast<uint8>(color.GetY() * 255.0f), static_cast<uint8>(color.GetZ() * 255.0f),
|
||||
static_cast<uint8>(a * 255.0f));
|
||||
};
|
||||
void SetColor(const QColor& rgb, float a)
|
||||
{
|
||||
m_color4b = ColorB(
|
||||
static_cast<uint8>(rgb.red()), static_cast<uint8>(rgb.green()), static_cast<uint8>(rgb.blue()), static_cast<uint8>(a * 255.0f));
|
||||
};
|
||||
void SetColor(const QColor& color)
|
||||
{
|
||||
m_color4b = ColorB(
|
||||
static_cast<uint8>(color.red()), static_cast<uint8>(color.green()), static_cast<uint8>(color.blue()),
|
||||
static_cast<uint8>(color.alpha()));
|
||||
};
|
||||
void SetColor(const ColorB& color)
|
||||
{
|
||||
m_color4b = color;
|
||||
};
|
||||
void SetAlpha(float a = 1) { m_color4b.a = static_cast<uint8>(a * 255.0f); };
|
||||
ColorB GetColor() const { return m_color4b; }
|
||||
|
||||
@@ -108,6 +135,7 @@ struct SANDBOX_API DisplayContext
|
||||
void DrawTrianglesIndexed(const AZStd::vector<Vec3>& vertices, const AZStd::vector<vtx_idx>& indices, const ColorB& color);
|
||||
// Draw wireframe box.
|
||||
void DrawWireBox(const Vec3& min, const Vec3& max);
|
||||
void DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max);
|
||||
// Draw filled box
|
||||
void DrawSolidBox(const Vec3& min, const Vec3& max);
|
||||
void DrawSolidOBB(const Vec3& center, const Vec3& axisX, const Vec3& axisY, const Vec3& axisZ, const Vec3& halfExtents);
|
||||
|
||||
@@ -225,6 +225,12 @@ void DisplayContext::DrawWireBox(const Vec3& min, const Vec3& max)
|
||||
pRenderAuxGeom->DrawAABB(AABB(min, max), m_matrixStack[m_currentMatrix], false, m_color4b, eBBD_Faceted);
|
||||
}
|
||||
|
||||
void DisplayContext::DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max)
|
||||
{
|
||||
pRenderAuxGeom->DrawAABB(
|
||||
AABB(Vec3(min.GetX(), min.GetY(), min.GetZ()), Vec3(max.GetX(), max.GetY(), max.GetZ())),
|
||||
m_matrixStack[m_currentMatrix], false, m_color4b, eBBD_Faceted);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DrawSolidBox(const Vec3& min, const Vec3& max)
|
||||
{
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
#include "HitContext.h"
|
||||
#include "Objects/SelectionGroup.h"
|
||||
|
||||
#include <IEntityRenderState.h>
|
||||
#include <IStatObj.h>
|
||||
static constexpr int VIEW_DISTANCE_MULTIPLIER_MAX = 100;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Undo Entity Link
|
||||
@@ -58,7 +57,6 @@ public:
|
||||
protected:
|
||||
void Release() override { delete this; };
|
||||
int GetSize() override { return sizeof(*this); }; // Return size of xml state.
|
||||
QString GetDescription() override { return "Entity Link"; };
|
||||
QString GetObjectName() override{ return ""; };
|
||||
|
||||
void Undo([[maybe_unused]] bool bUndo) override
|
||||
@@ -139,7 +137,6 @@ private:
|
||||
}
|
||||
|
||||
int GetSize() override { return sizeof(CUndoAttachEntity); }
|
||||
QString GetDescription() override { return "Attachment Changed"; }
|
||||
|
||||
GUID m_attachedEntityGUID;
|
||||
CEntityObject::EAttachmentType m_attachmentType;
|
||||
@@ -151,8 +148,6 @@ private:
|
||||
// CBase implementation.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
float CEntityObject::m_helperScale = 1;
|
||||
|
||||
namespace
|
||||
{
|
||||
CEntityObject* s_pPropertyPanelEntityObject = nullptr;
|
||||
@@ -163,12 +158,9 @@ namespace
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CEntityObject::CEntityObject()
|
||||
: m_listeners(1)
|
||||
{
|
||||
m_bLoadFailed = false;
|
||||
|
||||
m_visualObject = nullptr;
|
||||
|
||||
m_box.min.Set(0, 0, 0);
|
||||
m_box.max.Set(0, 0, 0);
|
||||
|
||||
@@ -223,7 +215,7 @@ CEntityObject::CEntityObject()
|
||||
mv_ratioLOD = 100;
|
||||
mv_viewDistanceMultiplier = 1.0f;
|
||||
mv_ratioLOD.SetLimits(0, 255);
|
||||
mv_viewDistanceMultiplier.SetLimits(0.0f, IRenderNode::VIEW_DISTANCE_MULTIPLIER_MAX);
|
||||
mv_viewDistanceMultiplier.SetLimits(0.0f, VIEW_DISTANCE_MULTIPLIER_MAX);
|
||||
|
||||
m_physicsState = nullptr;
|
||||
|
||||
@@ -247,7 +239,6 @@ CEntityObject::CEntityObject()
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectInAllDirsChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectorFOVChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectorTextureChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnPropertyChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnRadiusChange(var); });
|
||||
}
|
||||
|
||||
@@ -295,11 +286,6 @@ void CEntityObject::Done()
|
||||
ReleaseEventTargets();
|
||||
RemoveAllEntityLinks();
|
||||
|
||||
for (CListenerSet<IEntityObjectListener*>::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
|
||||
{
|
||||
notifier->OnDone();
|
||||
}
|
||||
|
||||
CBaseObject::Done();
|
||||
}
|
||||
|
||||
@@ -365,12 +351,6 @@ void CEntityObject::SetTransformDelegate(ITransformDelegate* pTransformDelegate)
|
||||
ResetCallbacks();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CEntityObject::IsSameClass(CBaseObject* obj)
|
||||
{
|
||||
return (GetClassDesc() == obj->GetClassDesc());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CEntityObject::ConvertFromObject(CBaseObject* object)
|
||||
{
|
||||
@@ -458,33 +438,10 @@ bool CEntityObject::HitTest(HitContext& hc)
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CEntityObject::HitHelperTest(HitContext& hc)
|
||||
{
|
||||
bool bResult = CBaseObject::HitHelperTest(hc);
|
||||
if (bResult)
|
||||
{
|
||||
hc.object = this;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CEntityObject::HitTestRect(HitContext& hc)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
if (m_visualObject && !gSettings.viewports.bShowIcons && !gSettings.viewports.bShowSizeBasedIcons)
|
||||
{
|
||||
AABB box;
|
||||
box.SetTransformedAABB(GetWorldTM(), m_visualObject->GetAABB());
|
||||
bResult = HitTestRectBounds(hc, box);
|
||||
}
|
||||
else
|
||||
{
|
||||
bResult = CBaseObject::HitTestRect(hc);
|
||||
}
|
||||
bool bResult = CBaseObject::HitTestRect(hc);
|
||||
|
||||
if (bResult)
|
||||
{
|
||||
@@ -494,42 +451,6 @@ bool CEntityObject::HitTestRect(HitContext& hc)
|
||||
return bResult;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CEntityObject::MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Entity);
|
||||
|
||||
if (event == eMouseMove || event == eMouseLDown)
|
||||
{
|
||||
Vec3 pos;
|
||||
// Rise Entity above ground on Bounding box amount.
|
||||
if (GetIEditor()->GetAxisConstrains() != AXIS_TERRAIN)
|
||||
{
|
||||
pos = view->MapViewToCP(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Snap to terrain.
|
||||
bool hitTerrain;
|
||||
pos = view->ViewToWorld(point, &hitTerrain);
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x, pos.y);
|
||||
pos.z = pos.z - m_box.min.z;
|
||||
}
|
||||
pos = view->SnapToGrid(pos);
|
||||
}
|
||||
SetPos(pos);
|
||||
|
||||
if (event == eMouseLDown)
|
||||
{
|
||||
return MOUSECREATE_OK;
|
||||
}
|
||||
return MOUSECREATE_CONTINUE;
|
||||
}
|
||||
return CBaseObject::MouseCreateCallback(view, event, point, flags);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IVariable* CEntityObject::FindVariableInSubBlock(CVarBlockPtr& properties, IVariable* pSubBlockVar, const char* pVarName)
|
||||
{
|
||||
@@ -680,11 +601,6 @@ void CEntityObject::SetName(const QString& name)
|
||||
|
||||
CBaseObject::SetName(name);
|
||||
|
||||
CListenerSet<IEntityObjectListener*> listeners = m_listeners;
|
||||
for (CListenerSet<IEntityObjectListener*>::Notifier notifier(listeners); notifier.IsValid(); notifier.Next())
|
||||
{
|
||||
notifier->OnNameChanged(name.toUtf8().data());
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -697,19 +613,6 @@ void CEntityObject::SetSelected(bool bSelect)
|
||||
UpdateLightProperty();
|
||||
}
|
||||
|
||||
for (CListenerSet<IEntityObjectListener*>::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
|
||||
{
|
||||
notifier->OnSelectionChanged(bSelect);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityObject::OnPropertyChange([[maybe_unused]] IVariable* var)
|
||||
{
|
||||
if (s_ignorePropertiesUpdate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -941,11 +844,9 @@ void CEntityObject::Serialize(CObjectArchive& ar)
|
||||
m_eventTargets.emplace_back(AZStd::move(et));
|
||||
if (targetId != GUID_NULL)
|
||||
{
|
||||
using namespace AZStd::placeholders;
|
||||
ar.SetResolveCallback(
|
||||
this, targetId,
|
||||
[this](CBaseObject* object, unsigned int index) { ResolveEventTarget(object, index); },
|
||||
i);
|
||||
[this,i](CBaseObject* object) { ResolveEventTarget(object, i); });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1154,12 +1055,6 @@ XmlNodeRef CEntityObject::Export([[maybe_unused]] const QString& levelPath, XmlN
|
||||
objNode->setAttr("MinSpec", ( uint32 )GetMinSpec());
|
||||
}
|
||||
|
||||
uint32 nMtlLayersMask = GetMaterialLayersMask();
|
||||
if (nMtlLayersMask != 0)
|
||||
{
|
||||
objNode->setAttr("MatLayersMask", nMtlLayersMask);
|
||||
}
|
||||
|
||||
if (mv_hiddenInGame)
|
||||
{
|
||||
objNode->setAttr("HiddenInGame", true);
|
||||
@@ -1256,11 +1151,6 @@ void CEntityObject::OnEvent(ObjectEvent event)
|
||||
|
||||
case EVENT_CONFIG_SPEC_CHANGE:
|
||||
{
|
||||
IObjectManager* objMan = GetIEditor()->GetObjectManager();
|
||||
if (objMan && objMan->IsLightClass(this))
|
||||
{
|
||||
OnPropertyChange(nullptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1350,56 +1240,6 @@ QString CEntityObject::GetLightAnimation() const
|
||||
return "";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityObject::PostClone(CBaseObject* pFromObject, CObjectCloneContext& ctx)
|
||||
{
|
||||
CBaseObject::PostClone(pFromObject, ctx);
|
||||
|
||||
CEntityObject* pFromEntity = ( CEntityObject* )pFromObject;
|
||||
// Clone event targets.
|
||||
if (!pFromEntity->m_eventTargets.empty())
|
||||
{
|
||||
size_t numTargets = pFromEntity->m_eventTargets.size();
|
||||
for (size_t i = 0; i < numTargets; i++)
|
||||
{
|
||||
CEntityEventTarget& et = pFromEntity->m_eventTargets[i];
|
||||
CBaseObject* pClonedTarget = ctx.FindClone(et.target);
|
||||
if (!pClonedTarget)
|
||||
{
|
||||
pClonedTarget = et.target; // If target not cloned, link to original target.
|
||||
}
|
||||
|
||||
// Add cloned event.
|
||||
AddEventTarget(pClonedTarget, et.event, et.sourceEvent, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Clone links.
|
||||
if (!pFromEntity->m_links.empty())
|
||||
{
|
||||
int numTargets = static_cast<int>(pFromEntity->m_links.size());
|
||||
for (int i = 0; i < numTargets; i++)
|
||||
{
|
||||
CEntityLink& et = pFromEntity->m_links[i];
|
||||
CBaseObject* pClonedTarget = ctx.FindClone(et.target);
|
||||
if (!pClonedTarget)
|
||||
{
|
||||
pClonedTarget = et.target; // If target not cloned, link to original target.
|
||||
}
|
||||
|
||||
// Add cloned event.
|
||||
if (pClonedTarget)
|
||||
{
|
||||
AddEntityLink(et.name, pClonedTarget->GetId());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEntityLink(et.name, GUID_NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityObject::ResolveEventTarget(CBaseObject* object, unsigned int index)
|
||||
{
|
||||
@@ -1554,7 +1394,7 @@ void CEntityObject::OnObjectEvent(CBaseObject* target, int event)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CEntityObject::AddEventTarget(CBaseObject* target, const QString& event, const QString& sourceEvent, [[maybe_unused]] bool bUpdateScript)
|
||||
{
|
||||
StoreUndo("Add EventTarget");
|
||||
StoreUndo();
|
||||
CEntityEventTarget et;
|
||||
et.target = target;
|
||||
et.event = event;
|
||||
@@ -1588,7 +1428,7 @@ void CEntityObject::RemoveEventTarget(int index, [[maybe_unused]] bool bUpdateSc
|
||||
{
|
||||
if (index >= 0 && index < m_eventTargets.size())
|
||||
{
|
||||
StoreUndo("Remove EventTarget");
|
||||
StoreUndo();
|
||||
|
||||
if (m_eventTargets[index].pLineGizmo)
|
||||
{
|
||||
@@ -1624,7 +1464,7 @@ int CEntityObject::AddEntityLink(const QString& name, GUID targetEntityId)
|
||||
}
|
||||
}
|
||||
|
||||
StoreUndo("Add EntityLink");
|
||||
StoreUndo();
|
||||
|
||||
CLineGizmo* pLineGizmo = nullptr;
|
||||
|
||||
@@ -1672,7 +1512,7 @@ void CEntityObject::RemoveEntityLink(int index)
|
||||
if (index >= 0 && index < m_links.size())
|
||||
{
|
||||
CEntityLink& link = m_links[index];
|
||||
StoreUndo("Remove EntityLink");
|
||||
StoreUndo();
|
||||
|
||||
if (link.pLineGizmo)
|
||||
{
|
||||
@@ -1695,7 +1535,7 @@ void CEntityObject::RenameEntityLink(int index, const QString& newName)
|
||||
{
|
||||
if (index >= 0 && index < m_links.size())
|
||||
{
|
||||
StoreUndo("Rename EntityLink");
|
||||
StoreUndo();
|
||||
|
||||
if (m_links[index].pLineGizmo)
|
||||
{
|
||||
@@ -1842,18 +1682,6 @@ void CEntityObject::OnLoadFailed()
|
||||
GetIEditor()->GetErrorReport()->ReportError(err);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityObject::SetHelperScale(float scale)
|
||||
{
|
||||
m_helperScale = scale;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float CEntityObject::GetHelperScale()
|
||||
{
|
||||
return m_helperScale;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Analyze errors for this object.
|
||||
void CEntityObject::Validate(IErrorReport* report)
|
||||
@@ -1901,19 +1729,6 @@ bool CEntityObject::IsSimilarObject(CBaseObject* pObject)
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityObject::OnContextMenu(QMenu* pMenu)
|
||||
{
|
||||
if (!pMenu->isEmpty())
|
||||
{
|
||||
pMenu->addSeparator();
|
||||
}
|
||||
|
||||
// Events
|
||||
|
||||
CBaseObject::OnContextMenu(pMenu);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CEntityObject::PreInitLightProperty()
|
||||
{
|
||||
@@ -2171,16 +1986,6 @@ void CEntityObject::StoreUndoEntityLink(CSelectionGroup* pGroup)
|
||||
}
|
||||
}
|
||||
|
||||
void CEntityObject::RegisterListener(IEntityObjectListener* pListener)
|
||||
{
|
||||
m_listeners.Add(pListener);
|
||||
}
|
||||
|
||||
void CEntityObject::UnregisterListener(IEntityObjectListener* pListener)
|
||||
{
|
||||
m_listeners.Remove(pListener);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T CEntityObject::GetEntityProperty(const char* pName, T defaultvalue) const
|
||||
{
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
#include "BaseObject.h"
|
||||
|
||||
#include "IMovieSystem.h"
|
||||
#include "IEntityObjectListener.h"
|
||||
#include "Gizmo.h"
|
||||
#include "CryListenerSet.h"
|
||||
#include "StatObjBus.h"
|
||||
|
||||
#include <QObject>
|
||||
#endif
|
||||
@@ -81,11 +78,6 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Overrides from CBaseObject.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Return type name of Entity.
|
||||
QString GetTypeDescription() const override { return GetEntityClass(); };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool IsSameClass(CBaseObject* obj) override;
|
||||
|
||||
bool Init(IEditor* ie, CBaseObject* prev, const QString& file) override;
|
||||
void InitVariables() override;
|
||||
@@ -102,16 +94,12 @@ public:
|
||||
void SetEntityPropertyFloat(const char* name, float value);
|
||||
void SetEntityPropertyString(const char* name, const QString& value);
|
||||
|
||||
int MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags) override;
|
||||
void OnContextMenu(QMenu* menu) override;
|
||||
|
||||
void SetName(const QString& name) override;
|
||||
void SetSelected(bool bSelect) override;
|
||||
|
||||
void GetLocalBounds(AABB& box) override;
|
||||
|
||||
bool HitTest(HitContext& hc) override;
|
||||
bool HitHelperTest(HitContext& hc) override;
|
||||
bool HitTestRect(HitContext& hc) override;
|
||||
void UpdateVisibility(bool bVisible) override;
|
||||
bool ConvertFromObject(CBaseObject* object) override;
|
||||
@@ -139,14 +127,9 @@ public:
|
||||
EAttachmentType GetAttachType() const { return m_attachmentType; }
|
||||
QString GetAttachTarget() const { return m_attachmentTarget; }
|
||||
|
||||
void SetHelperScale(float scale) override;
|
||||
float GetHelperScale() override;
|
||||
|
||||
void GatherUsedResources(CUsedResources& resources) override;
|
||||
bool IsSimilarObject(CBaseObject* pObject) override;
|
||||
|
||||
bool HasMeasurementAxis() const override { return false; }
|
||||
|
||||
bool IsIsolated() const override { return false; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -220,20 +203,12 @@ public:
|
||||
|
||||
static void StoreUndoEntityLink(CSelectionGroup* pGroup);
|
||||
|
||||
void RegisterListener(IEntityObjectListener* pListener);
|
||||
void UnregisterListener(IEntityObjectListener* pListener);
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
void SetEntityProperty(const char* name, T value);
|
||||
template <typename T>
|
||||
T GetEntityProperty(const char* name, T defaultvalue) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Must be called after cloning the object on clone of object.
|
||||
//! This will make sure object references are cloned correctly.
|
||||
void PostClone(CBaseObject* pFromObject, CObjectCloneContext& ctx) override;
|
||||
|
||||
//! Draw default object items.
|
||||
void DrawProjectorPyramid(DisplayContext& dc, float dist);
|
||||
void DrawProjectorFrustum(DisplayContext& dc, Vec2 size, float dist);
|
||||
@@ -242,10 +217,6 @@ protected:
|
||||
|
||||
CVarBlock* CloneProperties(CVarBlock* srcProperties);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! Callback called when one of entity properties have been modified.
|
||||
void OnPropertyChange(IVariable* var);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void OnObjectEvent(CBaseObject* target, int event) override;
|
||||
void ResolveEventTarget(CBaseObject* object, unsigned int index);
|
||||
@@ -327,7 +298,6 @@ protected:
|
||||
// Used for light entities
|
||||
float m_projectorFOV;
|
||||
|
||||
IStatObj* m_visualObject;
|
||||
AABB m_box;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -388,8 +358,6 @@ protected:
|
||||
XmlNodeRef m_physicsState;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
static float m_helperScale;
|
||||
|
||||
EAttachmentType m_attachmentType;
|
||||
|
||||
bool m_bEnableReload;
|
||||
@@ -433,7 +401,6 @@ private:
|
||||
void ForceVariableUpdate();
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
CListenerSet<IEntityObjectListener*> m_listeners;
|
||||
std::vector< std::pair<IVariable*, IVariable::OnSetCallback*> > m_callbacks;
|
||||
AZStd::fixed_vector< IVariable::OnSetCallback, VariableCallbackIndex::Count > m_onSetCallbacksCache;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class IEntityObjectListener
|
||||
{
|
||||
public:
|
||||
virtual ~IEntityObjectListener() = default;
|
||||
|
||||
virtual void OnNameChanged(const char* pName) = 0;
|
||||
virtual void OnSelectionChanged(const bool bSelected) = 0;
|
||||
virtual void OnDone() = 0;
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user