Merge remote-tracking branch 'upstream/development' into GemUIDownload

This commit is contained in:
AMZN-Phil
2021-10-21 12:39:36 -07:00
276 changed files with 10751 additions and 4607 deletions
@@ -54,4 +54,5 @@ set(ENABLED_GEMS
AWSMetrics
PrefabBuilder
AudioSystem
Profiler
)
@@ -204,7 +204,7 @@ namespace PythonCoverage
return coveringModuleOutputNames;
}
void PythonCoverageEditorSystemComponent::OnStartExecuteByFilenameAsTest(AZStd::string_view filename, AZStd::string_view testCase, [[maybe_unused]] const AZStd::vector<AZStd::string_view>& args)
void PythonCoverageEditorSystemComponent::OnStartExecuteByFilenameAsTest([[maybe_unused]]AZStd::string_view filename, AZStd::string_view testCase, [[maybe_unused]] const AZStd::vector<AZStd::string_view>& args)
{
if (m_coverageState == CoverageState::Disabled)
{
@@ -226,8 +226,7 @@ namespace PythonCoverage
return;
}
const AZStd::string scriptName = AZ::IO::Path(filename).Stem().Native();
const auto coverageFile = m_coverageDir / AZStd::string::format("%s.pycoverage", scriptName.c_str());
const auto coverageFile = m_coverageDir / AZStd::string::format("%.*s.pycoverage", AZ_STRING_ARG(testCase));
// If this is a different python script we clear the existing entity components and start afresh
if (m_coverageFile != coverageFile)
@@ -253,73 +253,3 @@ class TestAtomEditorComponentsMain(object):
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
@pytest.mark.system
class TestMaterialEditorBasicTests(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project):
def delete_files():
file_system.delete(
[
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
],
True,
True,
)
# Cleanup our newly created materials
delete_files()
def teardown():
# Cleanup our newly created materials
delete_files()
request.addfinalizer(teardown)
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
@pytest.mark.test_case_id("C34448118") # Saving Material.
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
def test_MaterialEditorBasicTests(
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
expected_lines = [
"Material opened: True",
"Test asset doesn't exist initially: True",
"New asset created: True",
"New Material opened: True",
"Material closed: True",
"All documents closed: True",
"Close All Except Selected worked as expected: True",
"Actual Document saved with changes: True",
"Document saved as copy is saved with changes: True",
"Document saved as child is saved with changes: True",
"Save All worked as expected: True",
]
unexpected_lines = [
# "Trace::Assert",
# "Trace::Error",
"Traceback (most recent call last):"
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
generic_launcher,
"hydra_AtomMaterialEditor_BasicTests.py",
run_python="--runpython",
timeout=120,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
)
@@ -70,3 +70,75 @@ class TestAtomEditorComponentsSandbox(object):
null_renderer=True,
cfg_args=cfg_args,
)
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
@pytest.mark.system
class TestMaterialEditorBasicTests(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project):
def delete_files():
file_system.delete(
[
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
],
True,
True,
)
# Cleanup our newly created materials
delete_files()
def teardown():
# Cleanup our newly created materials
delete_files()
request.addfinalizer(teardown)
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
@pytest.mark.test_case_id("C34448118") # Saving Material.
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
def test_MaterialEditorBasicTests(
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
expected_lines = [
"Material opened: True",
"Test asset doesn't exist initially: True",
"New asset created: True",
"New Material opened: True",
"Material closed: True",
"All documents closed: True",
"Close All Except Selected worked as expected: True",
"Actual Document saved with changes: True",
"Document saved as copy is saved with changes: True",
"Document saved as child is saved with changes: True",
"Save All worked as expected: True",
]
unexpected_lines = [
# "Trace::Assert",
# "Trace::Error",
"Traceback (most recent call last):"
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
generic_launcher,
"hydra_AtomMaterialEditor_BasicTests.py",
run_python="--runpython",
timeout=120,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
log_file_name="MaterialEditor.log",
)
@@ -33,7 +33,7 @@ add_subdirectory(WhiteBox)
add_subdirectory(NvCloth)
## Prefab ##
add_subdirectory(prefab)
add_subdirectory(Prefab)
## Editor Python Bindings ##
add_subdirectory(EditorPythonBindings)
@@ -122,17 +122,32 @@ class EditorEntity:
# Creation functions
@classmethod
def find_editor_entity(cls, entity_name: str) -> EditorEntity:
def find_editor_entity(cls, entity_name: str, must_be_unique : bool = False) -> EditorEntity:
"""
Given Entity name, outputs entity object
:param entity_name: Name of entity to find
:return: EditorEntity class object
"""
entity_id = general.find_editor_entity(entity_name)
assert entity_id.IsValid(), f"Failure: Couldn't find entity with name: '{entity_name}'"
entity = cls(entity_id)
entities = cls.find_editor_entities([entity_name])
assert len(entities) != 0, f"Failure: Couldn't find entity with name: '{entity_name}'"
if must_be_unique:
assert len(entities) == 1, f"Failure: Multiple entities with name: '{entity_name}' when expected only one"
entity = cls(entities[0])
return entity
@classmethod
def find_editor_entities(cls, entity_names: List[str]) -> EditorEntity:
"""
Given Entities names, returns a list of EditorEntity
:param entity_name: Name of entity to find
:return: List[EditorEntity] class object
"""
searchFilter = azlmbr.entity.SearchFilter()
searchFilter.names = entity_names
ids = azlmbr.entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
return [cls(id) for id in ids]
@classmethod
def create_editor_entity(cls, name: str = None, parent_id=None) -> EditorEntity:
"""
@@ -157,8 +172,7 @@ class EditorEntity:
cls,
entity_position: Union[List, Tuple, math.Vector3],
name: str = None,
parent_id: azlmbr.entity.EntityId = None,
) -> EditorEntity:
parent_id: azlmbr.entity.EntityId = None) -> EditorEntity:
"""
Used to create entity at position using 'CreateNewEntityAtPosition' Bus.
:param entity_position: World Position(X, Y, Z) of entity in viewport.
@@ -227,6 +241,12 @@ class EditorEntity:
"""
return editor.EditorEntityInfoRequestBus(bus.Event, "GetChildren", self.id)
def get_children(self) -> List[EditorEntity]:
"""
:return: List of EditorEntity children. Type: [EditorEntity]
"""
return [EditorEntity(child_id) for child_id in self.get_children_ids()]
def add_component(self, component_name: str) -> EditorComponent:
"""
Used to add new component to Entity.
@@ -51,7 +51,7 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
logger.debug("Running automated test: {}".format(editor_script))
editor.args.extend(["--skipWelcomeScreenDialog", "--regset=/Amazon/Settings/EnableSourceControl=false",
"--regset=/Amazon/Preferences/EnablePrefabSystem=false", run_python, test_case,
f"--pythontestcase={request.node.originalname}", "--runpythonargs", " ".join(cfg_args)])
f"--pythontestcase={request.node.name}", "--runpythonargs", " ".join(cfg_args)])
if auto_test_mode:
editor.args.extend(["--autotest_mode"])
if null_renderer:
@@ -12,20 +12,39 @@ from os import path
from PySide2 import QtWidgets
import azlmbr.legacy.general as general
from azlmbr.entity import EntityId
from azlmbr.math import Vector3
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report
import azlmbr.entity as entity
import azlmbr.bus as bus
import azlmbr.prefab as prefab
import editor_python_test_tools.pyside_utils as pyside_utils
import prefab.Prefab_Test_Utils as prefab_test_utils
def get_prefab_file_path(prefab_path):
if not path.isabs(prefab_path):
prefab_path = path.join(general.get_file_alias("@projectroot@"), prefab_path)
# Append prefab if it doesn't contain .prefab on it
name, ext = path.splitext(prefab_path)
if ext != ".prefab":
prefab_path = name + ".prefab"
return prefab_path
def get_all_entity_ids():
return entity.SearchBus(bus.Broadcast, 'SearchEntities', entity.SearchFilter())
def wait_for_propagation():
general.idle_wait_frames(1)
# This is a helper class which contains some of the useful information about a prefab instance.
class PrefabInstance:
def __init__(self, prefab_file_name: str=None, container_entity: EditorEntity=EntityId()):
def __init__(self, prefab_file_name: str = None, container_entity: EditorEntity = None):
self.prefab_file_name: str = prefab_file_name
self.container_entity: EditorEntity = container_entity
@@ -42,7 +61,7 @@ class PrefabInstance:
See if this instance is valid to be used with other prefab operations.
:return: Whether the target instance is valid or not.
"""
def is_valid() -> bool:
def is_valid(self) -> bool:
return self.container_entity.id.IsValid() and self.prefab_file_name in Prefab.existing_prefabs
"""
@@ -60,7 +79,7 @@ class PrefabInstance:
new_parent_before_reparent_children_ids = set(new_parent.get_children_ids())
pyside_utils.run_soon(lambda: self.container_entity.set_parent_entity(parent_entity_id))
pyside_utils.run_soon(lambda: prefab_test_utils.wait_for_propagation())
pyside_utils.run_soon(lambda: wait_for_propagation())
try:
active_modal_widget = await pyside_utils.wait_for_modal_widget()
@@ -94,19 +113,18 @@ class Prefab:
existing_prefabs = {}
def __init__(self, file_name: str):
self.file_name:str = file_name
self.file_path: str = prefab_test_utils.get_prefab_file_path(file_name)
def __init__(self, file_path: str):
self.file_path: str = get_prefab_file_path(file_path)
self.instances: set[PrefabInstance] = set()
"""
Check if a prefab is ready to be used to generate its instances.
:param file_name: A unique file name of the target prefab.
:param file_path: A unique file path of the target prefab.
:return: Whether the target prefab is loaded or not.
"""
@classmethod
def is_prefab_loaded(cls, file_name: str) -> bool:
return file_name in Prefab.existing_prefabs
def is_prefab_loaded(cls, file_path: str) -> bool:
return file_path in Prefab.existing_prefabs
"""
Check if a prefab exists in the directory for files of prefab tests.
@@ -114,9 +132,8 @@ class Prefab:
:return: Whether the target prefab exists or not.
"""
@classmethod
def prefab_exists(cls, file_name: str) -> bool:
file_path = prefab_test_utils.get_prefab_file_path(file_name)
return path.exists(file_path)
def prefab_exists(cls, file_path: str) -> bool:
return path.exists(get_prefab_file_path(file_path))
"""
Return a prefab which can be used immediately.
@@ -125,10 +142,11 @@ class Prefab:
"""
@classmethod
def get_prefab(cls, file_name: str) -> Prefab:
assert file_name, "Received an empty file_name"
if Prefab.is_prefab_loaded(file_name):
return Prefab.existing_prefabs[file_name]
else:
assert Prefab.prefab_exists(file_name), f"Attempted to get a prefab {file_name} that doesn't exist"
assert Prefab.prefab_exists(file_name), f"Attempted to get a prefab \"{file_name}\" that doesn't exist"
new_prefab = Prefab(file_name)
Prefab.existing_prefabs[file_name] = Prefab(file_name)
return new_prefab
@@ -141,7 +159,7 @@ class Prefab:
:return: Created Prefab object and the very first PrefabInstance object owned by the prefab.
"""
@classmethod
def create_prefab(cls, entities: list[EditorEntity], file_name: str, prefab_instance_name: str=None) -> (Prefab, PrefabInstance):
def create_prefab(cls, entities: list[EditorEntity], file_name: str, prefab_instance_name: str=None) -> tuple(Prefab, PrefabInstance):
assert not Prefab.is_prefab_loaded(file_name), f"Can't create Prefab '{file_name}' since the prefab already exists"
new_prefab = Prefab(file_name)
@@ -155,7 +173,7 @@ class Prefab:
if prefab_instance_name:
container_entity.set_name(prefab_instance_name)
prefab_test_utils.wait_for_propagation()
wait_for_propagation()
new_prefab_instance = PrefabInstance(file_name, EditorEntity(container_entity_id))
new_prefab.instances.add(new_prefab_instance)
@@ -182,12 +200,13 @@ class Prefab:
delete_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'DeleteEntitiesAndAllDescendantsInInstance', container_entity_ids)
assert delete_prefab_result.IsSuccess(), f"Prefab operation 'DeleteEntitiesAndAllDescendantsInInstance' failed. Error: {delete_prefab_result.GetError()}"
prefab_test_utils.wait_for_propagation()
wait_for_propagation()
entity_ids_after_delete = set(prefab_test_utils.get_all_entities())
entity_ids_after_delete = set(get_all_entity_ids())
for entity_id_removed in entity_ids_to_remove:
if entity_id_removed in entity_ids_after_delete:
assert prefab_entities_deleted, "Not all entities and descendants in target prefabs are deleted."
assert False, "Not all entities and descendants in target prefabs are deleted."
for instance in prefab_instances:
instance_deleted_prefab = Prefab.get_prefab(instance.prefab_file_name)
@@ -215,12 +234,10 @@ class Prefab:
if name:
container_entity.set_name(name)
prefab_test_utils.wait_for_propagation()
wait_for_propagation()
new_prefab_instance = PrefabInstance(self.file_name, EditorEntity(container_entity_id))
new_prefab_instance = PrefabInstance(self.file_path, EditorEntity(container_entity_id))
assert not new_prefab_instance in self.instances, "This prefab instance is already existed before this instantiation."
self.instances.add(new_prefab_instance)
prefab_test_utils.check_entity_at_position(container_entity_id, prefab_position)
return new_prefab_instance
@@ -126,7 +126,7 @@ def ForceRegion_LinearDampingForceOnRigidBodies():
# Constants
CLOSE_ENOUGH = 0.001
TIME_OUT = 3.0
TIME_OUT = 10.0
INITIAL_VELOCITY = azmath.Vector3(0.0, 0.0, -10.0)
# 1) Open level / Enter game mode
@@ -29,21 +29,21 @@ class TestAutomation(TestAutomationBase):
autotest_mode=autotest_mode)
def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform):
from . import PrefabLevel_OpensLevelWithEntities as test_module
from .tests import PrefabLevel_OpensLevelWithEntities as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_Prefab_BasicWorkflow_CreatePrefab(self, request, workspace, editor, launcher_platform):
from . import Prefab_BasicWorkflow_CreatePrefab as test_module
def test_PrefabBasicWorkflow_CreatePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreatePrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_Prefab_BasicWorkflow_InstantiatePrefab(self, request, workspace, editor, launcher_platform):
from . import Prefab_BasicWorkflow_InstantiatePrefab as test_module
def test_PrefabBasicWorkflow_InstantiatePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_InstantiatePrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_Prefab_BasicWorkflow_CreateAndDeletePrefab(self, request, workspace, editor, launcher_platform):
from . import Prefab_BasicWorkflow_CreateAndDeletePrefab as test_module
def test_PrefabBasicWorkflow_CreateAndDeletePrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreateAndDeletePrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module)
def test_Prefab_BasicWorkflow_CreateAndReparentPrefab(self, request, workspace, editor, launcher_platform):
from . import Prefab_BasicWorkflow_CreateAndReparentPrefab as test_module
def test_PrefabBasicWorkflow_CreateAndReparentPrefab(self, request, workspace, editor, launcher_platform):
from .tests import PrefabBasicWorkflow_CreateAndReparentPrefab as test_module
self._run_prefab_test(request, workspace, editor, test_module, autotest_mode=False)
@@ -5,14 +5,14 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def Prefab_BasicWorkflow_CreateAndDeletePrefab():
def PrefabBasicWorkflow_CreateAndDeletePrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity
from prefab.Prefab import Prefab
from editor_python_test_tools.prefab_utils import Prefab
import prefab.Prefab_Test_Utils as prefab_test_utils
import PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -21,13 +21,13 @@ def Prefab_BasicWorkflow_CreateAndDeletePrefab():
car_entity = EditorEntity.create_editor_entity()
car_prefab_entities = [car_entity]
# Checks for prefab creation passed or not
# Asserts if prefab creation doesn't succeeds
_, car = Prefab.create_prefab(
car_prefab_entities, CAR_PREFAB_FILE_NAME)
# Checks for prefab deletion passed or not
# Asserts if prefab deletion fails
Prefab.remove_prefabs([car])
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Prefab_BasicWorkflow_CreateAndDeletePrefab)
Report.start_test(PrefabBasicWorkflow_CreateAndDeletePrefab)
@@ -5,7 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def Prefab_BasicWorkflow_CreateAndReparentPrefab():
def PrefabBasicWorkflow_CreateAndReparentPrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab'
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab'
@@ -16,9 +16,9 @@ def Prefab_BasicWorkflow_CreateAndReparentPrefab():
async def run_test():
from editor_python_test_tools.editor_entity_utils import EditorEntity
from prefab.Prefab import Prefab
from editor_python_test_tools.prefab_utils import Prefab
import prefab.Prefab_Test_Utils as prefab_test_utils
import PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -46,4 +46,4 @@ def Prefab_BasicWorkflow_CreateAndReparentPrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Prefab_BasicWorkflow_CreateAndReparentPrefab)
Report.start_test(PrefabBasicWorkflow_CreateAndReparentPrefab)
@@ -5,15 +5,15 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def Prefab_BasicWorkflow_CreatePrefab():
def PrefabBasicWorkflow_CreatePrefab():
CAR_PREFAB_FILE_NAME = 'car_prefab'
from editor_python_test_tools.editor_entity_utils import EditorEntity
from editor_python_test_tools.utils import Report
from prefab.Prefab import Prefab
from editor_python_test_tools.prefab_utils import Prefab
import prefab.Prefab_Test_Utils as prefab_test_utils
import PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -27,4 +27,4 @@ def Prefab_BasicWorkflow_CreatePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Prefab_BasicWorkflow_CreatePrefab)
Report.start_test(PrefabBasicWorkflow_CreatePrefab)
@@ -5,17 +5,17 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
def Prefab_BasicWorkflow_InstantiatePrefab():
def PrefabBasicWorkflow_InstantiatePrefab():
from azlmbr.math import Vector3
EXISTING_TEST_PREFAB_FILE_NAME = "Test"
EXISTING_TEST_PREFAB_FILE_NAME = "Gem/PythonTests/Prefab/data/Test.prefab"
INSTANTIATED_TEST_PREFAB_POSITION = Vector3(10.00, 20.0, 30.0)
EXPECTED_TEST_PREFAB_CHILDREN_COUNT = 1
from prefab.Prefab import Prefab
from editor_python_test_tools.prefab_utils import Prefab
import prefab.Prefab_Test_Utils as prefab_test_utils
import PrefabTestUtils as prefab_test_utils
prefab_test_utils.open_base_tests_level()
@@ -31,4 +31,4 @@ def Prefab_BasicWorkflow_InstantiatePrefab():
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test(Prefab_BasicWorkflow_InstantiatePrefab)
Report.start_test(PrefabBasicWorkflow_InstantiatePrefab)
@@ -7,9 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
# fmt:off
class Tests():
find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level")
empty_entity_pos = ("'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position")
find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level")
find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level")
empty_entity_pos = ("'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position")
find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level")
pxentity_component = ("Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' does *not* have a Physx Collider")
# fmt:on
@@ -18,20 +18,6 @@ import azlmbr.components as components
import azlmbr.entity as entity
import azlmbr.legacy.general as general
def get_prefab_file_name(prefab_name):
return prefab_name + ".prefab"
def get_prefab_file_path(prefab_name):
return os.path.join(os.path.dirname(os.path.abspath(__file__)), get_prefab_file_name(prefab_name))
def find_entities_by_name(entity_name):
searchFilter = entity.SearchFilter()
searchFilter.names = [entity_name]
return entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
def get_all_entities():
return entity.SearchBus(bus.Broadcast, 'SearchEntities', entity.SearchFilter())
def check_entity_at_position(entity_id, expected_entity_position):
entity_at_expected_position_result = (
"entity is at expected position",
@@ -74,9 +60,6 @@ def get_children_ids_by_name(entity_id, entity_name):
return result
def wait_for_propagation():
general.idle_wait_frames(1)
def open_base_tests_level():
helper.init_idle()
helper.open_level("Prefab", "Base")
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c3384e88cd0f47ab8ec81eb75101b02ff9675c76dc070c726a9f3f39f1b2b2df
size 4994448
@@ -1,16 +1,34 @@
ProductName: single_mesh_multiple_materials.dbgsg
debugSceneGraphVersion: 1
single_mesh_multiple_materials
Node Name: Torus
Node Path: RootNode.Torus
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Torus_1
Node Path: RootNode.Torus.Torus_1
Node Type: MeshData
Positions: Count 2304. Hash: 12560656679477605282
Normals: Count 2304. Hash: 14915939258818888021
FaceList: Count 1152. Hash: 3035560221708475304
FaceMaterialIds: Count 1152. Hash: 2033667258170256242
Node Name: Torus_optimized
Node Path: RootNode.Torus_optimized
Node Name: Torus_2
Node Path: RootNode.Torus.Torus_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Torus_1_optimized
Node Path: RootNode.Torus.Torus_1_optimized
Node Type: MeshData
Positions: Count 2304. Hash: 12560656679477605282
Normals: Count 2304. Hash: 14915939258818888021
@@ -18,7 +36,7 @@ Node Type: MeshData
FaceMaterialIds: Count 1152. Hash: 2033667258170256242
Node Name: transform
Node Path: RootNode.Torus.transform
Node Path: RootNode.Torus.Torus_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -27,13 +45,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UV0
Node Path: RootNode.Torus.UV0
Node Path: RootNode.Torus.Torus_1.UV0
Node Type: MeshVertexUVData
UVs: Count 2304. Hash: 6069930558565069665
UVCustomName: UV0
Node Name: OrangeMaterial
Node Path: RootNode.Torus.OrangeMaterial
Node Path: RootNode.Torus.Torus_1.OrangeMaterial
Node Type: MaterialData
MaterialName: OrangeMaterial
UniqueId: 10937477720113828524
@@ -63,7 +81,7 @@ Node Type: MaterialData
BaseColorTexture:
Node Name: SecondTextureMaterial
Node Path: RootNode.Torus.SecondTextureMaterial
Node Path: RootNode.Torus.Torus_1.SecondTextureMaterial
Node Type: MaterialData
MaterialName: SecondTextureMaterial
UniqueId: 16601413836225607467
@@ -93,7 +111,7 @@ Node Type: MaterialData
BaseColorTexture: OneMeshMultipleMaterials/FBXSecondTestTexture.png
Node Name: FirstTextureMaterial
Node Path: RootNode.Torus.FirstTextureMaterial
Node Path: RootNode.Torus.Torus_1.FirstTextureMaterial
Node Type: MaterialData
MaterialName: FirstTextureMaterial
UniqueId: 2580020563915538382
@@ -122,40 +140,21 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: OneMeshMultipleMaterials/FBXTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Torus.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Torus.Torus_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 2304. Hash: 17641066831235827929
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Torus.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Torus.Torus_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 2304. Hash: 6274616552656695154
TangentSpace: 1
Node Name: UV0
Node Path: RootNode.Torus_optimized.UV0
Node Type: MeshVertexUVData
UVs: Count 2304. Hash: 6069930558565069665
UVCustomName: UV0
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Torus_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 2304. Hash: 17641066831235827929
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Torus_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 2304. Hash: 6274616552656695154
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Torus_optimized.transform
Node Path: RootNode.Torus.Torus_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -163,8 +162,14 @@ Node Type: TransformData
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UV0
Node Path: RootNode.Torus.Torus_2.UV0
Node Type: MeshVertexUVData
UVs: Count 2304. Hash: 6069930558565069665
UVCustomName: UV0
Node Name: OrangeMaterial
Node Path: RootNode.Torus_optimized.OrangeMaterial
Node Path: RootNode.Torus.Torus_2.OrangeMaterial
Node Type: MaterialData
MaterialName: OrangeMaterial
UniqueId: 10937477720113828524
@@ -194,7 +199,7 @@ Node Type: MaterialData
BaseColorTexture:
Node Name: SecondTextureMaterial
Node Path: RootNode.Torus_optimized.SecondTextureMaterial
Node Path: RootNode.Torus.Torus_2.SecondTextureMaterial
Node Type: MaterialData
MaterialName: SecondTextureMaterial
UniqueId: 16601413836225607467
@@ -224,7 +229,7 @@ Node Type: MaterialData
BaseColorTexture: OneMeshMultipleMaterials/FBXSecondTestTexture.png
Node Name: FirstTextureMaterial
Node Path: RootNode.Torus_optimized.FirstTextureMaterial
Node Path: RootNode.Torus.Torus_2.FirstTextureMaterial
Node Type: MaterialData
MaterialName: FirstTextureMaterial
UniqueId: 2580020563915538382
@@ -253,3 +258,120 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: OneMeshMultipleMaterials/FBXTestTexture.png
Node Name: UV0
Node Path: RootNode.Torus.Torus_1_optimized.UV0
Node Type: MeshVertexUVData
UVs: Count 2304. Hash: 6069930558565069665
UVCustomName: UV0
Node Name: TangentSet_0
Node Path: RootNode.Torus.Torus_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 2304. Hash: 17641066831235827929
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Torus.Torus_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 2304. Hash: 6274616552656695154
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Torus.Torus_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: OrangeMaterial
Node Path: RootNode.Torus.Torus_1_optimized.OrangeMaterial
Node Type: MaterialData
MaterialName: OrangeMaterial
UniqueId: 10937477720113828524
IsNoDraw: false
DiffuseColor: < 0.800000, 0.113346, 0.000000>
SpecularColor: < 0.800000, 0.113346, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: SecondTextureMaterial
Node Path: RootNode.Torus.Torus_1_optimized.SecondTextureMaterial
Node Type: MaterialData
MaterialName: SecondTextureMaterial
UniqueId: 16601413836225607467
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: OneMeshMultipleMaterials/FBXSecondTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: OneMeshMultipleMaterials/FBXSecondTestTexture.png
Node Name: FirstTextureMaterial
Node Path: RootNode.Torus.Torus_1_optimized.FirstTextureMaterial
Node Type: MaterialData
MaterialName: FirstTextureMaterial
UniqueId: 2580020563915538382
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: OneMeshMultipleMaterials/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: OneMeshMultipleMaterials/FBXTestTexture.png
@@ -1,16 +1,34 @@
ProductName: OneMeshOneMaterial.dbgsg
debugSceneGraphVersion: 1
OneMeshOneMaterial
Node Name: Cube
Node Path: RootNode.Cube
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1
Node Path: RootNode.Cube.Cube_1
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cube_optimized
Node Path: RootNode.Cube_optimized
Node Name: Cube_2
Node Path: RootNode.Cube.Cube_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1_optimized
Node Path: RootNode.Cube.Cube_1_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
@@ -18,7 +36,7 @@ Node Type: MeshData
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: transform
Node Path: RootNode.Cube.transform
Node Path: RootNode.Cube.Cube_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -27,13 +45,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.UVMap
Node Path: RootNode.Cube.Cube_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: CubeMaterial
Node Path: RootNode.Cube.CubeMaterial
Node Path: RootNode.Cube.Cube_1.CubeMaterial
Node Type: MaterialData
MaterialName: CubeMaterial
UniqueId: 973942033197978066
@@ -62,40 +80,21 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: OneMeshOneMaterial/FBXTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
Node Name: UVMap
Node Path: RootNode.Cube_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube_optimized.transform
Node Path: RootNode.Cube.Cube_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -103,8 +102,72 @@ Node Type: TransformData
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.Cube_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: CubeMaterial
Node Path: RootNode.Cube_optimized.CubeMaterial
Node Path: RootNode.Cube.Cube_2.CubeMaterial
Node Type: MaterialData
MaterialName: CubeMaterial
UniqueId: 973942033197978066
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 36.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: OneMeshOneMaterial/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: OneMeshOneMaterial/FBXTestTexture.png
Node Name: UVMap
Node Path: RootNode.Cube.Cube_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube.Cube_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: CubeMaterial
Node Path: RootNode.Cube.Cube_1_optimized.CubeMaterial
Node Type: MaterialData
MaterialName: CubeMaterial
UniqueId: 973942033197978066
@@ -1,64 +1,109 @@
ProductName: lodtest.dbgsg
debugSceneGraphVersion: 1
lodtest
Node Name: lodtest
Node Path: RootNode.lodtest
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: lodtest_1
Node Path: RootNode.lodtest.lodtest_1
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: lodtest_lod3
Node Path: RootNode.lodtest_lod3
Node Name: lodtest_2
Node Path: RootNode.lodtest.lodtest_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: lodtest_1_optimized
Node Path: RootNode.lodtest.lodtest_1_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: lodtest_lod3_1
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1
Node Type: MeshData
Positions: Count 1984. Hash: 6600975913707260286
Normals: Count 1984. Hash: 2708036977889843831
FaceList: Count 960. Hash: 10390417165025722786
FaceMaterialIds: Count 960. Hash: 12510609185544665964
Node Name: lodtest_lod2
Node Path: RootNode.lodtest_lod2
Node Name: lodtest_lod3_2
Node Path: RootNode.lodtest_lod3.lodtest_lod3_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 2.298166, 0.000000>
Node Name: lodtest_lod3_1_optimized
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1_optimized
Node Type: MeshData
Positions: Count 1984. Hash: 6600975913707260286
Normals: Count 1984. Hash: 2708036977889843831
FaceList: Count 960. Hash: 10390417165025722786
FaceMaterialIds: Count 960. Hash: 12510609185544665964
Node Name: lodtest_lod2_1
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1
Node Type: MeshData
Positions: Count 240. Hash: 219362421205407416
Normals: Count 240. Hash: 11195242321181199939
FaceList: Count 80. Hash: 11130917988116538993
FaceMaterialIds: Count 80. Hash: 4190892684086530065
Node Name: lodtest_lod1
Node Path: RootNode.lodtest_lod1
Node Name: lodtest_lod2_2
Node Path: RootNode.lodtest_lod2.lodtest_lod2_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, -0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, -2.211498, 0.000000>
Node Name: lodtest_lod2_1_optimized
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1_optimized
Node Type: MeshData
Positions: Count 240. Hash: 219362421205407416
Normals: Count 240. Hash: 11195242321181199939
FaceList: Count 80. Hash: 11130917988116538993
FaceMaterialIds: Count 80. Hash: 4190892684086530065
Node Name: lodtest_lod1_1
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1
Node Type: MeshData
Positions: Count 192. Hash: 1283526254311745349
Normals: Count 192. Hash: 1873340970602844856
FaceList: Count 124. Hash: 3728991722746136013
FaceMaterialIds: Count 124. Hash: 2372486708814455910
Node Name: lodtest_optimized
Node Path: RootNode.lodtest_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: lodtest_lod1_2
Node Path: RootNode.lodtest_lod1.lodtest_lod1_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 2.410331, 0.000000, 0.000000>
Node Name: lodtest_lod3_optimized
Node Path: RootNode.lodtest_lod3_optimized
Node Type: MeshData
Positions: Count 1984. Hash: 6600975913707260286
Normals: Count 1984. Hash: 2708036977889843831
FaceList: Count 960. Hash: 10390417165025722786
FaceMaterialIds: Count 960. Hash: 12510609185544665964
Node Name: lodtest_lod2_optimized
Node Path: RootNode.lodtest_lod2_optimized
Node Type: MeshData
Positions: Count 240. Hash: 219362421205407416
Normals: Count 240. Hash: 11195242321181199939
FaceList: Count 80. Hash: 11130917988116538993
FaceMaterialIds: Count 80. Hash: 4190892684086530065
Node Name: lodtest_lod1_optimized
Node Path: RootNode.lodtest_lod1_optimized
Node Name: lodtest_lod1_1_optimized
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1_optimized
Node Type: MeshData
Positions: Count 192. Hash: 7921557352486854444
Normals: Count 192. Hash: 1873340970602844856
@@ -66,7 +111,7 @@ Node Type: MeshData
FaceMaterialIds: Count 124. Hash: 2372486708814455910
Node Name: transform
Node Path: RootNode.lodtest.transform
Node Path: RootNode.lodtest.lodtest_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -75,13 +120,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest.UVMap
Node Path: RootNode.lodtest.lodtest_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: Material
Node Path: RootNode.lodtest.Material
Node Path: RootNode.lodtest.lodtest_1.Material
Node Type: MaterialData
MaterialName: Material
UniqueId: 11127505492038345244
@@ -110,21 +155,124 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.lodtest.lodtest_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest.lodtest_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest_lod3.transform
Node Path: RootNode.lodtest.lodtest_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest.lodtest_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: Material
Node Path: RootNode.lodtest.lodtest_2.Material
Node Type: MaterialData
MaterialName: Material
UniqueId: 11127505492038345244
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 36.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UVMap
Node Path: RootNode.lodtest.lodtest_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.lodtest.lodtest_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest.lodtest_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest.lodtest_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Material
Node Path: RootNode.lodtest.lodtest_1_optimized.Material
Node Type: MaterialData
MaterialName: Material
UniqueId: 11127505492038345244
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 36.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: transform
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -133,13 +281,13 @@ Node Type: TransformData
Transl: < 0.000000, 2.298166, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest_lod3.UVMap
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 1984. Hash: 14119273880200542497
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod3.DefaultMaterial
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -168,21 +316,124 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest_lod3.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 1984. Hash: 5664494957869921957
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest_lod3.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 1984. Hash: 5048878728906162461
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest_lod2.transform
Node Path: RootNode.lodtest_lod3.lodtest_lod3_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 2.298166, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest_lod3.lodtest_lod3_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 1984. Hash: 14119273880200542497
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod3.lodtest_lod3_2.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 0.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UVMap
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 1984. Hash: 14119273880200542497
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 1984. Hash: 5664494957869921957
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 1984. Hash: 5048878728906162461
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 2.298166, 0.000000>
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod3.lodtest_lod3_1_optimized.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 0.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: transform
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, -0.000000, 0.000000>
@@ -191,13 +442,13 @@ Node Type: TransformData
Transl: < 0.000000, -2.211498, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest_lod2.UVMap
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 240. Hash: 13702273589593616598
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod2.DefaultMaterial
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -226,21 +477,124 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest_lod2.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 240. Hash: 1390901212717410749
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest_lod2.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 240. Hash: 1379238632949267281
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest_lod1.transform
Node Path: RootNode.lodtest_lod2.lodtest_lod2_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, -0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, -2.211498, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest_lod2.lodtest_lod2_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 240. Hash: 13702273589593616598
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod2.lodtest_lod2_2.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 0.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UVMap
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 240. Hash: 13702273589593616598
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 240. Hash: 1390901212717410749
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 240. Hash: 1379238632949267281
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, -0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, -2.211498, 0.000000>
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod2.lodtest_lod2_1_optimized.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 0.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: transform
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -249,13 +603,13 @@ Node Type: TransformData
Transl: < 2.410331, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest_lod1.UVMap
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod1.DefaultMaterial
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -284,107 +638,36 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest_lod1.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 192. Hash: 11165448242141781141
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest_lod1.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 192. Hash: 7987814487334449536
TangentSpace: 1
Node Name: UVMap
Node Path: RootNode.lodtest_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest_optimized.transform
Node Path: RootNode.lodtest_lod1.lodtest_lod1_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Material
Node Path: RootNode.lodtest_optimized.Material
Node Type: MaterialData
MaterialName: Material
UniqueId: 11127505492038345244
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 36.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Transl: < 2.410331, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.lodtest_lod3_optimized.UVMap
Node Path: RootNode.lodtest_lod1.lodtest_lod1_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 1984. Hash: 14119273880200542497
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest_lod3_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 1984. Hash: 5664494957869921957
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest_lod3_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 1984. Hash: 5048878728906162461
TangentSpace: 1
Node Name: transform
Node Path: RootNode.lodtest_lod3_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 2.298166, 0.000000>
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod3_optimized.DefaultMaterial
Node Path: RootNode.lodtest_lod1.lodtest_lod1_2.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -414,84 +697,26 @@ Node Type: MaterialData
BaseColorTexture:
Node Name: UVMap
Node Path: RootNode.lodtest_lod2_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 240. Hash: 13702273589593616598
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest_lod2_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 240. Hash: 1390901212717410749
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest_lod2_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 240. Hash: 1379238632949267281
TangentSpace: 1
Node Name: transform
Node Path: RootNode.lodtest_lod2_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, -0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, -2.211498, 0.000000>
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod2_optimized.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 0.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UVMap
Node Path: RootNode.lodtest_lod1_optimized.UVMap
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 13790301632763350589
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.lodtest_lod1_optimized.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 192. Hash: 7293001660047850407
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.lodtest_lod1_optimized.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 192. Hash: 2874689498270494796
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.lodtest_lod1_optimized.transform
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -500,7 +725,7 @@ Node Type: TransformData
Transl: < 2.410331, 0.000000, 0.000000>
Node Name: DefaultMaterial
Node Path: RootNode.lodtest_lod1_optimized.DefaultMaterial
Node Path: RootNode.lodtest_lod1.lodtest_lod1_1_optimized.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -528,4 +753,3 @@ Node Type: MaterialData
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
@@ -1,32 +1,59 @@
ProductName: physicstest.dbgsg
debugSceneGraphVersion: 1
physicstest
Node Name: Cone
Node Path: RootNode.Cone
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cone_1
Node Path: RootNode.Cone.Cone_1
Node Type: MeshData
Positions: Count 128. Hash: 7714223793259938211
Normals: Count 128. Hash: 2352668179264002707
FaceList: Count 62. Hash: 14563017593520122982
FaceMaterialIds: Count 62. Hash: 12234218120113875284
Node Name: Cube_phys
Node Path: RootNode.Cube_phys
Node Type: MeshData
Positions: Count 24. Hash: 3478903613105670818
Normals: Count 24. Hash: 7251512570672401149
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cone_2
Node Path: RootNode.Cone.Cone_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cone_optimized
Node Path: RootNode.Cone_optimized
Node Name: Cone_1_optimized
Node Path: RootNode.Cone.Cone_1_optimized
Node Type: MeshData
Positions: Count 128. Hash: 10174710861731544050
Normals: Count 128. Hash: 2352668179264002707
FaceList: Count 62. Hash: 11332459830831720586
FaceMaterialIds: Count 62. Hash: 12234218120113875284
Node Name: Cube_phys_1
Node Path: RootNode.Cube_phys.Cube_phys_1
Node Type: MeshData
Positions: Count 24. Hash: 3478903613105670818
Normals: Count 24. Hash: 7251512570672401149
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cube_phys_2
Node Path: RootNode.Cube_phys.Cube_phys_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: transform
Node Path: RootNode.Cone.transform
Node Path: RootNode.Cone.Cone_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -35,13 +62,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cone.UVMap
Node Path: RootNode.Cone.Cone_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 128. Hash: 10171083346831193808
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.Cone.DefaultMaterial
Node Path: RootNode.Cone.Cone_1.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -70,21 +97,21 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cone.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cone.Cone_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 128. Hash: 14351734474754285313
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cone.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cone.Cone_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 128. Hash: 15997251922861304891
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube_phys.transform
Node Path: RootNode.Cone.Cone_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -93,13 +120,116 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube_phys.UVMap
Node Path: RootNode.Cone.Cone_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 128. Hash: 10171083346831193808
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.Cone.Cone_2.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 0.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UVMap
Node Path: RootNode.Cone.Cone_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 128. Hash: 7873368003484215433
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.Cone.Cone_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 128. Hash: 12937806066914201637
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Cone.Cone_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 128. Hash: 873786942732834087
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cone.Cone_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: DefaultMaterial
Node Path: RootNode.Cone.Cone_1_optimized.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 0.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: transform
Node Path: RootNode.Cube_phys.Cube_phys_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube_phys.Cube_phys_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 13623018071435219250
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.Cube_phys.DefaultMaterial
Node Path: RootNode.Cube_phys.Cube_phys_1.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -128,40 +258,21 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube_phys.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cube_phys.Cube_phys_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 11965897353301448436
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube_phys.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cube_phys.Cube_phys_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 17515781720544086759
TangentSpace: 1
Node Name: UVMap
Node Path: RootNode.Cone_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 128. Hash: 7873368003484215433
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cone_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 128. Hash: 12937806066914201637
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cone_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 128. Hash: 873786942732834087
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cone_optimized.transform
Node Path: RootNode.Cube_phys.Cube_phys_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -169,8 +280,14 @@ Node Type: TransformData
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube_phys.Cube_phys_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 13623018071435219250
UVCustomName: UVMap
Node Name: DefaultMaterial
Node Path: RootNode.Cone_optimized.DefaultMaterial
Node Path: RootNode.Cube_phys.Cube_phys_2.DefaultMaterial
Node Type: MaterialData
MaterialName: DefaultMaterial
UniqueId: 3809502407269006983
@@ -198,4 +315,3 @@ Node Type: MaterialData
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
@@ -1,32 +1,59 @@
ProductName: multiple_mesh_linked_materials.dbgsg
debugSceneGraphVersion: 1
multiple_mesh_linked_materials
Node Name: Cube
Node Path: RootNode.Cube
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1
Node Path: RootNode.Cube.Cube_1
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7113802799051126666
Node Name: Cone
Node Path: RootNode.Cone
Node Name: Cube_2
Node Path: RootNode.Cube.Cube_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1_optimized
Node Path: RootNode.Cube.Cube_1_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7113802799051126666
Node Name: Cone_1
Node Path: RootNode.Cone.Cone_1
Node Type: MeshData
Positions: Count 128. Hash: 12506421592104186200
Normals: Count 128. Hash: 367461522682321485
FaceList: Count 62. Hash: 13208951979626973193
FaceMaterialIds: Count 62. Hash: 15454348664434923102
Node Name: Cube_optimized
Node Path: RootNode.Cube_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7113802799051126666
Node Name: Cone_2
Node Path: RootNode.Cone.Cone_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 2.000000>
Node Name: Cone_optimized
Node Path: RootNode.Cone_optimized
Node Name: Cone_1_optimized
Node Path: RootNode.Cone.Cone_1_optimized
Node Type: MeshData
Positions: Count 128. Hash: 14946490408303214595
Normals: Count 128. Hash: 367461522682321485
@@ -34,7 +61,7 @@ Node Type: MeshData
FaceMaterialIds: Count 62. Hash: 15454348664434923102
Node Name: transform
Node Path: RootNode.Cube.transform
Node Path: RootNode.Cube.Cube_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -43,13 +70,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UV0
Node Path: RootNode.Cube.UV0
Node Path: RootNode.Cube.Cube_1.UV0
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UV0
Node Name: SharedBlack
Node Path: RootNode.Cube.SharedBlack
Node Path: RootNode.Cube.Cube_1.SharedBlack
Node Type: MaterialData
MaterialName: SharedBlack
UniqueId: 5248829540156873090
@@ -79,7 +106,7 @@ Node Type: MaterialData
BaseColorTexture:
Node Name: SharedOrange
Node Path: RootNode.Cube.SharedOrange
Node Path: RootNode.Cube.Cube_1.SharedOrange
Node Type: MaterialData
MaterialName: SharedOrange
UniqueId: 9470651048605569128
@@ -108,21 +135,184 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cone.transform
Node Path: RootNode.Cube.Cube_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UV0
Node Path: RootNode.Cube.Cube_2.UV0
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UV0
Node Name: SharedBlack
Node Path: RootNode.Cube.Cube_2.SharedBlack
Node Type: MaterialData
MaterialName: SharedBlack
UniqueId: 5248829540156873090
IsNoDraw: false
DiffuseColor: < 0.000000, 0.000000, 0.000000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: SharedOrange
Node Path: RootNode.Cube.Cube_2.SharedOrange
Node Type: MaterialData
MaterialName: SharedOrange
UniqueId: 9470651048605569128
IsNoDraw: false
DiffuseColor: < 0.800000, 0.139382, 0.014429>
SpecularColor: < 0.800000, 0.139382, 0.014429>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UV0
Node Path: RootNode.Cube.Cube_1_optimized.UV0
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UV0
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube.Cube_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: SharedBlack
Node Path: RootNode.Cube.Cube_1_optimized.SharedBlack
Node Type: MaterialData
MaterialName: SharedBlack
UniqueId: 5248829540156873090
IsNoDraw: false
DiffuseColor: < 0.000000, 0.000000, 0.000000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: SharedOrange
Node Path: RootNode.Cube.Cube_1_optimized.SharedOrange
Node Type: MaterialData
MaterialName: SharedOrange
UniqueId: 9470651048605569128
IsNoDraw: false
DiffuseColor: < 0.800000, 0.139382, 0.014429>
SpecularColor: < 0.800000, 0.139382, 0.014429>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: transform
Node Path: RootNode.Cone.Cone_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -131,13 +321,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 2.000000>
Node Name: UV0
Node Path: RootNode.Cone.UV0
Node Path: RootNode.Cone.Cone_1.UV0
Node Type: MeshVertexUVData
UVs: Count 128. Hash: 10291654057525777310
UVCustomName: UV0
Node Name: SharedOrange
Node Path: RootNode.Cone.SharedOrange
Node Path: RootNode.Cone.Cone_1.SharedOrange
Node Type: MaterialData
MaterialName: SharedOrange
UniqueId: 9470651048605569128
@@ -167,7 +357,7 @@ Node Type: MaterialData
BaseColorTexture:
Node Name: SharedBlack
Node Path: RootNode.Cone.SharedBlack
Node Path: RootNode.Cone.Cone_1.SharedBlack
Node Type: MaterialData
MaterialName: SharedBlack
UniqueId: 5248829540156873090
@@ -196,79 +386,36 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cone.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cone.Cone_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 128. Hash: 12695232913942738512
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cone.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cone.Cone_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 128. Hash: 9034210764777745751
TangentSpace: 1
Node Name: UV0
Node Path: RootNode.Cube_optimized.UV0
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UV0
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube_optimized.transform
Node Path: RootNode.Cone.Cone_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Transl: < 0.000000, 0.000000, 2.000000>
Node Name: SharedBlack
Node Path: RootNode.Cube_optimized.SharedBlack
Node Type: MaterialData
MaterialName: SharedBlack
UniqueId: 5248829540156873090
IsNoDraw: false
DiffuseColor: < 0.000000, 0.000000, 0.000000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UV0
Node Path: RootNode.Cone.Cone_2.UV0
Node Type: MeshVertexUVData
UVs: Count 128. Hash: 10291654057525777310
UVCustomName: UV0
Node Name: SharedOrange
Node Path: RootNode.Cube_optimized.SharedOrange
Node Path: RootNode.Cone.Cone_2.SharedOrange
Node Type: MaterialData
MaterialName: SharedOrange
UniqueId: 9470651048605569128
@@ -297,27 +444,57 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: SharedBlack
Node Path: RootNode.Cone.Cone_2.SharedBlack
Node Type: MaterialData
MaterialName: SharedBlack
UniqueId: 5248829540156873090
IsNoDraw: false
DiffuseColor: < 0.000000, 0.000000, 0.000000>
SpecularColor: < 0.000000, 0.000000, 0.000000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
Node Name: UV0
Node Path: RootNode.Cone_optimized.UV0
Node Path: RootNode.Cone.Cone_1_optimized.UV0
Node Type: MeshVertexUVData
UVs: Count 128. Hash: 7173974213247584731
UVCustomName: UV0
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cone_optimized.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cone.Cone_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 128. Hash: 10740776669168782230
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cone_optimized.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cone.Cone_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 128. Hash: 6990068477421150065
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cone_optimized.transform
Node Path: RootNode.Cone.Cone_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -326,7 +503,7 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 2.000000>
Node Name: SharedOrange
Node Path: RootNode.Cone_optimized.SharedOrange
Node Path: RootNode.Cone.Cone_1_optimized.SharedOrange
Node Type: MaterialData
MaterialName: SharedOrange
UniqueId: 9470651048605569128
@@ -356,7 +533,7 @@ Node Type: MaterialData
BaseColorTexture:
Node Name: SharedBlack
Node Path: RootNode.Cone_optimized.SharedBlack
Node Path: RootNode.Cone.Cone_1_optimized.SharedBlack
Node Type: MaterialData
MaterialName: SharedBlack
UniqueId: 5248829540156873090
@@ -384,4 +561,3 @@ Node Type: MaterialData
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
@@ -1,32 +1,59 @@
ProductName: multiple_mesh_one_material.dbgsg
debugSceneGraphVersion: 1
multiple_mesh_one_material
Node Name: Cube
Node Path: RootNode.Cube
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1
Node Path: RootNode.Cube.Cube_1
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder
Node Path: RootNode.Cylinder
Node Name: Cube_2
Node Path: RootNode.Cube.Cube_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1_optimized
Node Path: RootNode.Cube.Cube_1_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder_1
Node Path: RootNode.Cylinder.Cylinder_1
Node Type: MeshData
Positions: Count 192. Hash: 1283526254311745349
Normals: Count 192. Hash: 1873340970602844856
FaceList: Count 124. Hash: 3728991722746136013
FaceMaterialIds: Count 124. Hash: 2372486708814455910
Node Name: Cube_optimized
Node Path: RootNode.Cube_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder_2
Node Path: RootNode.Cylinder.Cylinder_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: Cylinder_optimized
Node Path: RootNode.Cylinder_optimized
Node Name: Cylinder_1_optimized
Node Path: RootNode.Cylinder.Cylinder_1_optimized
Node Type: MeshData
Positions: Count 192. Hash: 7921557352486854444
Normals: Count 192. Hash: 1873340970602844856
@@ -34,7 +61,7 @@ Node Type: MeshData
FaceMaterialIds: Count 124. Hash: 2372486708814455910
Node Name: transform
Node Path: RootNode.Cube.transform
Node Path: RootNode.Cube.Cube_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -43,13 +70,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.UVMap
Node Path: RootNode.Cube.Cube_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cube.SingleMaterial
Node Path: RootNode.Cube.Cube_1.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
@@ -78,21 +105,124 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: TwoMeshOneMaterial/FBXTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cylinder.transform
Node Path: RootNode.Cube.Cube_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.Cube_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cube.Cube_2.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshOneMaterial/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshOneMaterial/FBXTestTexture.png
Node Name: UVMap
Node Path: RootNode.Cube.Cube_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube.Cube_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: SingleMaterial
Node Path: RootNode.Cube.Cube_1_optimized.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshOneMaterial/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshOneMaterial/FBXTestTexture.png
Node Name: transform
Node Path: RootNode.Cylinder.Cylinder_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -101,13 +231,13 @@ Node Type: TransformData
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cylinder.UVMap
Node Path: RootNode.Cylinder.Cylinder_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cylinder.SingleMaterial
Node Path: RootNode.Cylinder.Cylinder_1.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
@@ -136,49 +266,36 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: TwoMeshOneMaterial/FBXTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cylinder.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 192. Hash: 11165448242141781141
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cylinder.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 192. Hash: 7987814487334449536
TangentSpace: 1
Node Name: UVMap
Node Path: RootNode.Cube_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube_optimized.transform
Node Path: RootNode.Cylinder.Cylinder_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cylinder.Cylinder_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cube_optimized.SingleMaterial
Node Path: RootNode.Cylinder.Cylinder_2.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
@@ -208,26 +325,26 @@ Node Type: MaterialData
BaseColorTexture: TwoMeshOneMaterial/FBXTestTexture.png
Node Name: UVMap
Node Path: RootNode.Cylinder_optimized.UVMap
Node Path: RootNode.Cylinder.Cylinder_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 13790301632763350589
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cylinder_optimized.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 192. Hash: 7293001660047850407
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cylinder_optimized.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 192. Hash: 2874689498270494796
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cylinder_optimized.transform
Node Path: RootNode.Cylinder.Cylinder_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -236,7 +353,7 @@ Node Type: TransformData
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: SingleMaterial
Node Path: RootNode.Cylinder_optimized.SingleMaterial
Node Path: RootNode.Cylinder.Cylinder_1_optimized.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
@@ -264,4 +381,3 @@ Node Type: MaterialData
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshOneMaterial/FBXTestTexture.png
@@ -1,32 +1,59 @@
ProductName: multiple_mesh_multiple_material.dbgsg
debugSceneGraphVersion: 1
multiple_mesh_multiple_material
Node Name: Cube
Node Path: RootNode.Cube
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1
Node Path: RootNode.Cube.Cube_1
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder
Node Path: RootNode.Cylinder
Node Name: Cube_2
Node Path: RootNode.Cube.Cube_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1_optimized
Node Path: RootNode.Cube.Cube_1_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder_1
Node Path: RootNode.Cylinder.Cylinder_1
Node Type: MeshData
Positions: Count 192. Hash: 1283526254311745349
Normals: Count 192. Hash: 1873340970602844856
FaceList: Count 124. Hash: 3728991722746136013
FaceMaterialIds: Count 124. Hash: 2372486708814455910
Node Name: Cube_optimized
Node Path: RootNode.Cube_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder_2
Node Path: RootNode.Cylinder.Cylinder_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: Cylinder_optimized
Node Path: RootNode.Cylinder_optimized
Node Name: Cylinder_1_optimized
Node Path: RootNode.Cylinder.Cylinder_1_optimized
Node Type: MeshData
Positions: Count 192. Hash: 7921557352486854444
Normals: Count 192. Hash: 1873340970602844856
@@ -34,7 +61,7 @@ Node Type: MeshData
FaceMaterialIds: Count 124. Hash: 2372486708814455910
Node Name: transform
Node Path: RootNode.Cube.transform
Node Path: RootNode.Cube.Cube_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -43,13 +70,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.UVMap
Node Path: RootNode.Cube.Cube_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cube.SingleMaterial
Node Path: RootNode.Cube.Cube_1.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
@@ -78,21 +105,124 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cylinder.transform
Node Path: RootNode.Cube.Cube_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.Cube_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cube.Cube_2.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshTwoMaterial/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
Node Name: UVMap
Node Path: RootNode.Cube.Cube_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube.Cube_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: SingleMaterial
Node Path: RootNode.Cube.Cube_1_optimized.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshTwoMaterial/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
Node Name: transform
Node Path: RootNode.Cylinder.Cylinder_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -101,13 +231,13 @@ Node Type: TransformData
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cylinder.UVMap
Node Path: RootNode.Cylinder.Cylinder_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: SecondMaterial
Node Path: RootNode.Cylinder.SecondMaterial
Node Path: RootNode.Cylinder.Cylinder_1.SecondMaterial
Node Type: MaterialData
MaterialName: SecondMaterial
UniqueId: 5229255358802505087
@@ -136,55 +266,42 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXSecondTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cylinder.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 192. Hash: 11165448242141781141
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cylinder.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 192. Hash: 7987814487334449536
TangentSpace: 1
Node Name: UVMap
Node Path: RootNode.Cube_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube_optimized.transform
Node Path: RootNode.Cylinder.Cylinder_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: SingleMaterial
Node Path: RootNode.Cube_optimized.SingleMaterial
Node Name: UVMap
Node Path: RootNode.Cylinder.Cylinder_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: SecondMaterial
Node Path: RootNode.Cylinder.Cylinder_2.SecondMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
MaterialName: SecondMaterial
UniqueId: 5229255358802505087
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
@@ -197,7 +314,7 @@ Node Type: MaterialData
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshTwoMaterial/FBXTestTexture.png
DiffuseTexture: TwoMeshTwoMaterial/FBXSecondTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
@@ -205,29 +322,29 @@ Node Type: MaterialData
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
BaseColorTexture: TwoMeshTwoMaterial/FBXSecondTestTexture.png
Node Name: UVMap
Node Path: RootNode.Cylinder_optimized.UVMap
Node Path: RootNode.Cylinder.Cylinder_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 13790301632763350589
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cylinder_optimized.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 192. Hash: 7293001660047850407
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cylinder_optimized.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 192. Hash: 2874689498270494796
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cylinder_optimized.transform
Node Path: RootNode.Cylinder.Cylinder_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -236,7 +353,7 @@ Node Type: TransformData
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: SecondMaterial
Node Path: RootNode.Cylinder_optimized.SecondMaterial
Node Path: RootNode.Cylinder.Cylinder_1_optimized.SecondMaterial
Node Type: MaterialData
MaterialName: SecondMaterial
UniqueId: 5229255358802505087
@@ -264,4 +381,3 @@ Node Type: MaterialData
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXSecondTestTexture.png
@@ -1,32 +1,59 @@
ProductName: multiple_mesh_multiple_material.dbgsg
debugSceneGraphVersion: 1
multiple_mesh_multiple_material
Node Name: Cube
Node Path: RootNode.Cube
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1
Node Path: RootNode.Cube.Cube_1
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder
Node Path: RootNode.Cylinder
Node Name: Cube_2
Node Path: RootNode.Cube.Cube_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1_optimized
Node Path: RootNode.Cube.Cube_1_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder_1
Node Path: RootNode.Cylinder.Cylinder_1
Node Type: MeshData
Positions: Count 192. Hash: 1283526254311745349
Normals: Count 192. Hash: 1873340970602844856
FaceList: Count 124. Hash: 3728991722746136013
FaceMaterialIds: Count 124. Hash: 2372486708814455910
Node Name: Cube_optimized
Node Path: RootNode.Cube_optimized
Node Type: MeshData
Positions: Count 24. Hash: 8661923109306356285
Normals: Count 24. Hash: 5807525742165000561
FaceList: Count 12. Hash: 9888799799190757436
FaceMaterialIds: Count 12. Hash: 7110546404675862471
Node Name: Cylinder_2
Node Path: RootNode.Cylinder.Cylinder_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: transform
Node Path: RootNode.Cube.transform
Node Path: RootNode.Cube.Cube_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -35,13 +62,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.UVMap
Node Path: RootNode.Cube.Cube_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cube.SingleMaterial
Node Path: RootNode.Cube.Cube_1.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
@@ -70,21 +97,124 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cylinder.transform
Node Path: RootNode.Cube.Cube_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.Cube_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: SingleMaterial
Node Path: RootNode.Cube.Cube_2.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshTwoMaterial/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
Node Name: UVMap
Node Path: RootNode.Cube.Cube_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube.Cube_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: SingleMaterial
Node Path: RootNode.Cube.Cube_1_optimized.SingleMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshTwoMaterial/FBXTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
Node Name: transform
Node Path: RootNode.Cylinder.Cylinder_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -93,13 +223,13 @@ Node Type: TransformData
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cylinder.UVMap
Node Path: RootNode.Cylinder.Cylinder_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: SecondMaterial
Node Path: RootNode.Cylinder.SecondMaterial
Node Path: RootNode.Cylinder.Cylinder_1.SecondMaterial
Node Type: MaterialData
MaterialName: SecondMaterial
UniqueId: 5229255358802505087
@@ -128,55 +258,42 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXSecondTestTexture.png
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cylinder.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 192. Hash: 11165448242141781141
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cylinder.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cylinder.Cylinder_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 192. Hash: 7987814487334449536
TangentSpace: 1
Node Name: UVMap
Node Path: RootNode.Cube_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24. Hash: 1622169145591646736
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 24. Hash: 13438447437797057049
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24. Hash: 11372562338897179017
TangentSpace: 1
GenerationMethod: 1
Node Name: transform
Node Path: RootNode.Cube_optimized.transform
Node Path: RootNode.Cylinder.Cylinder_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Transl: <-4.388482, 0.000000, 0.000000>
Node Name: SingleMaterial
Node Path: RootNode.Cube_optimized.SingleMaterial
Node Name: UVMap
Node Path: RootNode.Cylinder.Cylinder_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 192. Hash: 27253578623892681
UVCustomName: UVMap
Node Name: SecondMaterial
Node Path: RootNode.Cylinder.Cylinder_2.SecondMaterial
Node Type: MaterialData
MaterialName: SingleMaterial
UniqueId: 14432700632681398127
MaterialName: SecondMaterial
UniqueId: 5229255358802505087
IsNoDraw: false
DiffuseColor: < 0.814049, 0.814049, 0.814049>
SpecularColor: < 0.814049, 0.814049, 0.814049>
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 25.000000
@@ -189,7 +306,7 @@ Node Type: MaterialData
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture: TwoMeshTwoMaterial/FBXTestTexture.png
DiffuseTexture: TwoMeshTwoMaterial/FBXSecondTestTexture.png
SpecularTexture:
BumpTexture:
NormalTexture:
@@ -197,5 +314,4 @@ Node Type: MaterialData
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture: TwoMeshTwoMaterial/FBXTestTexture.png
BaseColorTexture: TwoMeshTwoMaterial/FBXSecondTestTexture.png
@@ -1,30 +1,48 @@
ProductName: vertexcolor.dbgsg
debugSceneGraphVersion: 1
vertexcolor
Node Name: Cube
Node Path: RootNode.Cube
Node Name: RootNode
Node Path: RootNode
Node Type: RootBoneData
WorldTransform:
BasisX: < 1.000000, 0.000000, 0.000000>
BasisY: < 0.000000, 1.000000, 0.000000>
BasisZ: < 0.000000, 0.000000, 1.000000>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1
Node Path: RootNode.Cube.Cube_1
Node Type: MeshData
Positions: Count 24576. Hash: 7031773714680283213
Normals: Count 24576. Hash: 8968157737282745201
FaceList: Count 12288. Hash: 13183441914179219962
FaceMaterialIds: Count 12288. Hash: 12545154121625736090
Node Name: Cube_optimized
Node Path: RootNode.Cube_optimized
Node Name: Cube_2
Node Path: RootNode.Cube.Cube_2
Node Type: BoneData
WorldTransform:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Cube_1_optimized
Node Path: RootNode.Cube.Cube_1_optimized
Node Type: MeshData
Positions: Count 24576. Hash: 7031773714680283213
Normals: Count 24576. Hash: 8968157737282745201
FaceList: Count 12288. Hash: 13183441914179219962
Positions: Count 6376. Hash: 10806296444120211070
Normals: Count 6376. Hash: 3814626075063770280
FaceList: Count 12288. Hash: 15242182080304859208
FaceMaterialIds: Count 12288. Hash: 12545154121625736090
Node Name: Col0
Node Path: RootNode.Cube.Col0
Node Path: RootNode.Cube.Cube_1.Col0
Node Type: MeshVertexColorData
Colors: Count 24576. Hash: 17169952715183318502
ColorsCustomName:
Node Name: transform
Node Path: RootNode.Cube.transform
Node Path: RootNode.Cube.Cube_1.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -33,13 +51,13 @@ Node Type: TransformData
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.UVMap
Node Path: RootNode.Cube.Cube_1.UVMap
Node Type: MeshVertexUVData
UVs: Count 24576. Hash: 4554678369329207802
UVCustomName: UVMap
Node Name: Material
Node Path: RootNode.Cube.Material
Node Path: RootNode.Cube.Cube_1.Material
Node Type: MaterialData
MaterialName: Material
UniqueId: 11127505492038345244
@@ -68,46 +86,27 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube.TangentSet_MikkT_0
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 24576. Hash: 13321090379606717973
TangentSpace: 1
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube.BitangentSet_MikkT_0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24576. Hash: 17217515414004886507
TangentSpace: 1
Node Name: UVMap
Node Path: RootNode.Cube_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 24576. Hash: 4554678369329207802
UVCustomName: UVMap
Node Name: TangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.TangentSet_MikkT_0
Node Type: MeshVertexTangentData
Tangents: Count 24576. Hash: 13321090379606717973
TangentSpace: 1
SetIndex: 0
Node Name: BitangentSet_MikkT_0
Node Path: RootNode.Cube_optimized.BitangentSet_MikkT_0
Node Type: MeshVertexBitangentData
Bitangents: Count 24576. Hash: 17217515414004886507
TangentSpace: 1
GenerationMethod: 1
Node Name: Col0
Node Path: RootNode.Cube_optimized.Col0
Node Path: RootNode.Cube.Cube_2.Col0
Node Type: MeshVertexColorData
Colors: Count 24576. Hash: 17169952715183318502
ColorsCustomName:
Node Name: transform
Node Path: RootNode.Cube_optimized.transform
Node Path: RootNode.Cube.Cube_2.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
@@ -115,8 +114,14 @@ Node Type: TransformData
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: UVMap
Node Path: RootNode.Cube.Cube_2.UVMap
Node Type: MeshVertexUVData
UVs: Count 24576. Hash: 4554678369329207802
UVCustomName: UVMap
Node Name: Material
Node Path: RootNode.Cube_optimized.Material
Node Path: RootNode.Cube.Cube_2.Material
Node Type: MaterialData
MaterialName: Material
UniqueId: 11127505492038345244
@@ -145,3 +150,66 @@ Node Type: MaterialData
EmissiveTexture:
BaseColorTexture:
Node Name: UVMap
Node Path: RootNode.Cube.Cube_1_optimized.UVMap
Node Type: MeshVertexUVData
UVs: Count 6376. Hash: 12957930967905951851
UVCustomName: UVMap
Node Name: TangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.TangentSet_0
Node Type: MeshVertexTangentData
Tangents: Count 6376. Hash: 7712841033379094373
GenerationMethod: 1
SetIndex: 0
Node Name: BitangentSet_0
Node Path: RootNode.Cube.Cube_1_optimized.BitangentSet_0
Node Type: MeshVertexBitangentData
Bitangents: Count 6376. Hash: 12547048737213169362
GenerationMethod: 1
Node Name: Col0
Node Path: RootNode.Cube.Cube_1_optimized.Col0
Node Type: MeshVertexColorData
Colors: Count 6376. Hash: 8761962599807935159
ColorsCustomName:
Node Name: transform
Node Path: RootNode.Cube.Cube_1_optimized.transform
Node Type: TransformData
Matrix:
BasisX: < 100.000000, 0.000000, 0.000000>
BasisY: < 0.000000, -0.000016, 100.000000>
BasisZ: < 0.000000, -100.000000, -0.000016>
Transl: < 0.000000, 0.000000, 0.000000>
Node Name: Material
Node Path: RootNode.Cube.Cube_1_optimized.Material
Node Type: MaterialData
MaterialName: Material
UniqueId: 11127505492038345244
IsNoDraw: false
DiffuseColor: < 0.800000, 0.800000, 0.800000>
SpecularColor: < 0.800000, 0.800000, 0.800000>
EmissiveColor: < 0.000000, 0.000000, 0.000000>
Opacity: 1.000000
Shininess: 36.000000
UseColorMap: Not set
BaseColor: Not set
UseMetallicMap: Not set
MetallicFactor: Not set
UseRoughnessMap: Not set
RoughnessFactor: Not set
UseEmissiveMap: Not set
EmissiveIntensity: Not set
UseAOMap: Not set
DiffuseTexture:
SpecularTexture:
BumpTexture:
NormalTexture:
MetallicTexture:
RoughnessTexture:
AmbientOcclusionTexture:
EmissiveTexture:
BaseColorTexture:
@@ -67,7 +67,7 @@ blackbox_fbx_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
warning_count=1,
products = [
asset_db_utils.DBProduct(
product_name='onemeshonematerial/onemeshonematerial.dbgsg',
@@ -99,7 +99,7 @@ blackbox_fbx_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=9,
warning_count=22,
products = [
asset_db_utils.DBProduct(
product_name='softnaminglod/lodtest.dbgsg',
@@ -131,7 +131,7 @@ blackbox_fbx_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=6,
warning_count=14,
products = [
asset_db_utils.DBProduct(
product_name='softnamingphysics/physicstest.dbgsg',
@@ -165,7 +165,7 @@ blackbox_fbx_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
warning_count=2,
products = [
asset_db_utils.DBProduct(
product_name='twomeshonematerial/multiple_mesh_one_material.dbgsg',
@@ -197,7 +197,7 @@ blackbox_fbx_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
warning_count=2,
products= [
asset_db_utils.DBProduct(
product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.dbgsg',
@@ -230,7 +230,7 @@ blackbox_fbx_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
warning_count=1,
products = [
asset_db_utils.DBProduct(
product_name='onemeshmultiplematerials/single_mesh_multiple_materials.dbgsg',
@@ -260,7 +260,7 @@ blackbox_fbx_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
warning_count=1,
products=[
asset_db_utils.DBProduct(
product_name='vertexcolor/vertexcolor.dbgsg',
@@ -275,6 +275,38 @@ blackbox_fbx_tests = [
id="35796285",
marks=pytest.mark.test_case_id("C35796285"),
),
pytest.param(
BlackboxAssetTest(
test_name= "MotionTest_RunAP_SuccessWithMatchingProducts",
asset_folder= "Motion",
scene_debug_file="Jack_Idle_Aim_ZUp.dbgsg",
assets = [
asset_db_utils.DBSourceAsset(
source_file_name = "Jack_Idle_Aim_ZUp.fbx",
uuid = b"eda904ae0e145f8b973d57fc5809918b",
jobs = [
asset_db_utils.DBJob(
job_key= "Scene compilation",
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
products = [
asset_db_utils.DBProduct(
product_name='motion/jack_idle_aim_zup.dbgsg',
sub_id=-517610290,
asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
asset_db_utils.DBProduct(
product_name='motion/jack_idle_aim_zup.motion',
sub_id=186392073,
asset_type=b'00494b8e75784ba28b28272e90680787')
]
),
]
)
]
),
),
]
@@ -296,7 +328,7 @@ blackbox_fbx_special_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
warning_count=2,
products = [
asset_db_utils.DBProduct(
product_name='twomeshtwomaterial/multiple_mesh_multiple_material.dbgsg',
@@ -317,7 +349,7 @@ blackbox_fbx_special_tests = [
builder_guid=b"bd8bf65894854fe3830e8ec3a23c35f3",
status=4,
error_count=0,
warning_count=0,
warning_count=2,
products = [
asset_db_utils.DBProduct(
product_name='twomeshtwomaterial/multiple_mesh_multiple_material.dbgsg',
@@ -387,7 +419,6 @@ class TestsFBX_AllPlatforms(object):
self.run_fbx_test(workspace, ap_setup_fixture,
asset_processor, project, blackbox_param, True)
def populateAssetInfo(self, workspace, project, assets):
# Check that each given source asset resulted in the expected jobs and products.
@@ -398,7 +429,6 @@ class TestsFBX_AllPlatforms(object):
product.product_name = job.platform + "/" \
+ product.product_name
def run_fbx_test(self, workspace, ap_setup_fixture, asset_processor,
project, blackbox_params: BlackboxAssetTest, overrideAsset = False):
"""
@@ -90,7 +90,7 @@ class TestAutomationBase:
editor_starttime = time.time()
self.logger.debug("Running automated test")
testcase_module_filepath = self._get_testcase_module_filepath(testcase_module)
pycmd = ["--runpythontest", testcase_module_filepath, f"-pythontestcase={request.node.originalname}"]
pycmd = ["--runpythontest", testcase_module_filepath, f"-pythontestcase={request.node.name}"]
if use_null_renderer:
pycmd += ["-rhi=null"]
if batch_mode:
@@ -1,44 +0,0 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
UI Apps: AutomatedTesting.GameLauncher
Launch AutomatedTesting.GameLauncher with Simple level
Test should run in both gpu and non gpu
"""
import pytest
import psutil
import ly_test_tools.environment.waiter as waiter
import editor_python_test_tools.hydra_test_utils as editor_test_utils
from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
from ly_remote_console.remote_console_commands import (
send_command_and_expect_response as send_command_and_expect_response,
)
@pytest.mark.parametrize("launcher_platform", ["windows"])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("level", ["Simple"])
@pytest.mark.SUITE_smoke
class TestRemoteConsoleLoadLevelWorks(object):
@pytest.fixture
def remote_console_instance(self, request):
console = RemoteConsole()
def teardown():
if console.connected:
console.stop()
request.addfinalizer(teardown)
return console
def test_RemoteConsole_LoadLevel_Works(self, launcher, level, remote_console_instance, launcher_platform):
expected_lines = ['Level system is loading "Simple"']
editor_test_utils.launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, null_renderer=True)
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e4937547ca4c486ef59656314401933217e0e0401fec103e1fb91c25ec60a177
size 2806
oid sha256:a5f9e27e0f22c31ca61d866fb594c6fde5b8ceb891e17dda075fa1e0033ec2b9
size 1666
+18 -16
View File
@@ -287,21 +287,22 @@ bool CCryDocManager::DoPromptFileName(QString& fileName, [[maybe_unused]] UINT n
return false;
}
CCryEditDoc* CCryDocManager::OpenDocumentFile(const char* lpszFileName, bool bAddToMRU)
CCryEditDoc* CCryDocManager::OpenDocumentFile(const char* filename, bool addToMostRecentFileList, COpenSameLevelOptions openSameLevelOptions)
{
assert(lpszFileName != nullptr);
assert(filename != nullptr);
const bool reopenIfSame = openSameLevelOptions == COpenSameLevelOptions::ReopenLevelIfSame;
// find the highest confidence
auto pos = m_templateList.begin();
CCrySingleDocTemplate::Confidence bestMatch = CCrySingleDocTemplate::noAttempt;
CCrySingleDocTemplate* pBestTemplate = nullptr;
CCryEditDoc* pOpenDocument = nullptr;
if (lpszFileName[0] == '\"')
if (filename[0] == '\"')
{
++lpszFileName;
++filename;
}
QString szPath = QString::fromUtf8(lpszFileName);
QString szPath = QString::fromUtf8(filename);
if (szPath.endsWith('"'))
{
szPath.remove(szPath.length() - 1, 1);
@@ -325,7 +326,7 @@ CCryEditDoc* CCryDocManager::OpenDocumentFile(const char* lpszFileName, bool bAd
}
}
if (pOpenDocument != nullptr)
if (!reopenIfSame && pOpenDocument != nullptr)
{
return pOpenDocument;
}
@@ -336,7 +337,7 @@ CCryEditDoc* CCryDocManager::OpenDocumentFile(const char* lpszFileName, bool bAd
return nullptr;
}
return pBestTemplate->OpenDocumentFile(szPath.toUtf8().data(), bAddToMRU, false);
return pBestTemplate->OpenDocumentFile(szPath.toUtf8().data(), addToMostRecentFileList, false);
}
//////////////////////////////////////////////////////////////////////////////
@@ -513,7 +514,7 @@ public:
QString m_appRoot;
QString m_logFile;
QString m_pythonArgs;
QString m_pythontTestCase;
QString m_pythonTestCase;
QString m_execFile;
QString m_execLineCmd;
@@ -562,7 +563,7 @@ public:
const std::vector<std::pair<CommandLineStringOption, QString&> > stringOptions = {
{{"logfile", "File name of the log file to write out to.", "logfile"}, m_logFile},
{{"runpythonargs", "Command-line argument string to pass to the python script if --runpython or --runpythontest was used.", "runpythonargs"}, m_pythonArgs},
{{"pythontestcase", "Test case name of python test script if --runpythontest was used.", "pythontestcase"}, m_pythontTestCase},
{{"pythontestcase", "Test case name of python test script if --runpythontest was used.", "pythontestcase"}, m_pythonTestCase},
{{"exec", "cfg file to run on startup, used for systems like automation", "exec"}, m_execFile},
{{"rhi", "Command-line argument to force which rhi to use", "dummyString"}, dummyString },
{{"rhi-device-validation", "Command-line argument to configure rhi validation", "dummyString"}, dummyString },
@@ -818,7 +819,7 @@ CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(const char* lpszPathName, b
return OpenDocumentFile(lpszPathName, true, bMakeVisible);
}
CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(const char* lpszPathName, bool bAddToMRU, [[maybe_unused]] bool bMakeVisible)
CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(const char* lpszPathName, bool addToMostRecentFileList, [[maybe_unused]] bool bMakeVisible)
{
CCryEditDoc* pCurDoc = GetIEditor()->GetDocument();
@@ -848,7 +849,7 @@ CCryEditDoc* CCrySingleDocTemplate::OpenDocumentFile(const char* lpszPathName, b
{
pCurDoc->OnOpenDocument(lpszPathName);
pCurDoc->SetPathName(lpszPathName);
if (bAddToMRU)
if (addToMostRecentFileList)
{
CCryEditApp::instance()->AddToRecentFileList(lpszPathName);
}
@@ -1535,11 +1536,12 @@ void CCryEditApp::RunInitPythonScript(CEditCommandLineInfo& cmdInfo)
{
// Multiple testcases can be specified them with ';', these should match the files to run
AZStd::vector<AZStd::string_view> testcaseList;
QByteArray pythonTestCase = cmdInfo.m_pythonTestCase.toUtf8();
testcaseList.resize(fileList.size());
{
int i = 0;
AzFramework::StringFunc::TokenizeVisitor(
fileStr.constData(),
pythonTestCase.constData(),
[&i, &testcaseList](AZStd::string_view elem)
{
testcaseList[i++] = (elem);
@@ -2630,7 +2632,7 @@ void CCryEditApp::OnShowHelpers()
void CCryEditApp::OnEditLevelData()
{
auto dir = QFileInfo(GetIEditor()->GetDocument()->GetLevelPathName()).dir();
CFileUtil::EditTextFile(dir.absoluteFilePath("LevelData.xml").toUtf8().data());
CFileUtil::EditTextFile(dir.absoluteFilePath("leveldata.xml").toUtf8().data());
}
//////////////////////////////////////////////////////////////////////////
@@ -3364,7 +3366,7 @@ void CCryEditApp::OnOpenSlice()
}
//////////////////////////////////////////////////////////////////////////
CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* lpszFileName)
CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* filename, bool addToMostRecentFileList, COpenSameLevelOptions openSameLevelOptions)
{
if (m_openingLevel)
{
@@ -3404,9 +3406,9 @@ CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* lpszFileName)
openDocTraceHandler.SetShowWindow(false);
}
// in this case, we set bAddToMRU to always be true because adding files to the MRU list
// in this case, we set addToMostRecentFileList to always be true because adding files to the MRU list
// automatically culls duplicate and normalizes paths anyway
m_pDocManager->OpenDocumentFile(lpszFileName, true);
m_pDocManager->OpenDocumentFile(filename, addToMostRecentFileList, openSameLevelOptions);
if (openDocTraceHandler.HasAnyErrors())
{
+11 -3
View File
@@ -85,6 +85,12 @@ public:
using EditorIdleProcessingBus = AZ::EBus<EditorIdleProcessing>;
enum class COpenSameLevelOptions
{
ReopenLevelIfSame,
NotReopenIfSame
};
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
class SANDBOX_API CCryEditApp
@@ -174,7 +180,9 @@ public:
virtual bool InitInstance();
virtual int ExitInstance(int exitCode = 0);
virtual bool OnIdle(LONG lCount);
virtual CCryEditDoc* OpenDocumentFile(const char* lpszFileName);
virtual CCryEditDoc* OpenDocumentFile(const char* filename,
bool addToMostRecentFileList=true,
COpenSameLevelOptions openSameLevelOptions = COpenSameLevelOptions::NotReopenIfSame);
CCryDocManager* GetDocManager() { return m_pDocManager; }
@@ -448,7 +456,7 @@ public:
~CCrySingleDocTemplate() {};
// avoid creating another CMainFrame
// close other type docs before opening any things
virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool bAddToMRU, bool bMakeVisible);
virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool addToMostRecentFileList, bool bMakeVisible);
virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool bMakeVisible = TRUE);
virtual Confidence MatchDocType(const char* lpszPathName, CCryEditDoc*& rpDocMatch);
@@ -468,7 +476,7 @@ public:
virtual void OnFileNew();
virtual bool DoPromptFileName(QString& fileName, UINT nIDSTitle,
DWORD lFlags, bool bOpenFileDialog, CDocTemplate* pTemplate);
virtual CCryEditDoc* OpenDocumentFile(const char* lpszFileName, bool bAddToMRU);
virtual CCryEditDoc* OpenDocumentFile(const char* filename, bool addToMostRecentFileList, COpenSameLevelOptions openSameLevelOptions = COpenSameLevelOptions::NotReopenIfSame);
QVector<CCrySingleDocTemplate*> m_templateList;
};
+11 -13
View File
@@ -143,20 +143,11 @@ namespace
return false;
}
}
const bool addToMostRecentFileList = false;
auto newDocument = CCryEditApp::instance()->OpenDocumentFile(levelPath.toUtf8().data(),
addToMostRecentFileList, COpenSameLevelOptions::ReopenLevelIfSame);
auto previousDocument = GetIEditor()->GetDocument();
QString previousPathName = (previousDocument != nullptr) ? previousDocument->GetLevelPathName() : "";
auto newDocument = CCryEditApp::instance()->OpenDocumentFile(levelPath.toUtf8().data());
// the underlying document pointer doesn't change, so we can't check that; use the path name's instead
bool result = true;
if (newDocument == nullptr || newDocument->IsLevelLoadFailed() || (newDocument->GetLevelPathName() == previousPathName))
{
result = false;
}
return result;
return newDocument != nullptr && !newDocument->IsLevelLoadFailed();
}
bool PyOpenLevelNoPrompt(const char* pLevelName)
@@ -407,6 +398,11 @@ inline namespace Commands
{
return AZ::Debug::Trace::WaitForDebugger(timeoutSeconds);
}
AZStd::string PyGetFileAlias(AZStd::string alias)
{
return AZ::IO::FileIOBase::GetInstance()->GetAlias(alias.c_str());
}
}
namespace AzToolsFramework
@@ -457,6 +453,8 @@ namespace AzToolsFramework
addLegacyGeneral(behaviorContext->Method("attach_debugger", PyAttachDebugger, nullptr, "Prompts for attaching the debugger"));
addLegacyGeneral(behaviorContext->Method("wait_for_debugger", PyWaitForDebugger, behaviorContext->MakeDefaultValues(-1.f), "Pauses this thread execution until the debugger has been attached"));
addLegacyGeneral(behaviorContext->Method("get_file_alias", PyGetFileAlias, nullptr, "Retrieves path for IO alias"));
// this will put these methods into the 'azlmbr.legacy.checkout_dialog' module
auto addCheckoutDialog = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder)
{
@@ -75,7 +75,10 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
->Field("CaptureCursorLook", &CameraMovementSettings::m_captureCursorLook)
->Field("OrbitYawRotationInverted", &CameraMovementSettings::m_orbitYawRotationInverted)
->Field("PanInvertedX", &CameraMovementSettings::m_panInvertedX)
->Field("PanInvertedY", &CameraMovementSettings::m_panInvertedY);
->Field("PanInvertedY", &CameraMovementSettings::m_panInvertedY)
->Field("DefaultPositionX", &CameraMovementSettings::m_defaultCameraPositionX)
->Field("DefaultPositionY", &CameraMovementSettings::m_defaultCameraPositionY)
->Field("DefaultPositionZ", &CameraMovementSettings::m_defaultCameraPositionZ);
serialize.Class<CameraInputSettings>()
->Version(2)
@@ -154,7 +157,16 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
"Invert direction of pan in local Y axis")
->DataElement(
AZ::Edit::UIHandlers::CheckBox, &CameraMovementSettings::m_captureCursorLook, "Camera Capture Look Cursor",
"Should the cursor be captured (hidden) while performing free look");
"Should the cursor be captured (hidden) while performing free look")
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &CameraMovementSettings::m_defaultCameraPositionX, "Default X Camera Position",
"Default X Camera Position when a level is opened")
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &CameraMovementSettings::m_defaultCameraPositionY, "Default Y Camera Position",
"Default Y Camera Position when a level is opened")
->DataElement(
AZ::Edit::UIHandlers::SpinBox, &CameraMovementSettings::m_defaultCameraPositionZ, "Default Z Camera Position",
"Default Z Camera Position when a level is opened");
editContext->Class<CameraInputSettings>("Camera Input Settings", "")
->DataElement(
@@ -271,6 +283,12 @@ void CEditorPreferencesPage_ViewportCamera::OnApply()
SandboxEditor::SetCameraOrbitYawRotationInverted(m_cameraMovementSettings.m_orbitYawRotationInverted);
SandboxEditor::SetCameraPanInvertedX(m_cameraMovementSettings.m_panInvertedX);
SandboxEditor::SetCameraPanInvertedY(m_cameraMovementSettings.m_panInvertedY);
SandboxEditor::SetDefaultCameraEditorPosition(
AZ::Vector3(
m_cameraMovementSettings.m_defaultCameraPositionX,
m_cameraMovementSettings.m_defaultCameraPositionY,
m_cameraMovementSettings.m_defaultCameraPositionZ
));
SandboxEditor::SetCameraTranslateForwardChannelId(m_cameraInputSettings.m_translateForwardChannelId);
SandboxEditor::SetCameraTranslateBackwardChannelId(m_cameraInputSettings.m_translateBackwardChannelId);
@@ -308,6 +326,11 @@ void CEditorPreferencesPage_ViewportCamera::InitializeSettings()
m_cameraMovementSettings.m_panInvertedX = SandboxEditor::CameraPanInvertedX();
m_cameraMovementSettings.m_panInvertedY = SandboxEditor::CameraPanInvertedY();
AZ::Vector3 defaultCameraPosition = SandboxEditor::DefaultEditorCameraPosition();
m_cameraMovementSettings.m_defaultCameraPositionX = defaultCameraPosition.GetX();
m_cameraMovementSettings.m_defaultCameraPositionY = defaultCameraPosition.GetY();
m_cameraMovementSettings.m_defaultCameraPositionZ = defaultCameraPosition.GetZ();
m_cameraInputSettings.m_translateForwardChannelId = SandboxEditor::CameraTranslateForwardChannelId().GetName();
m_cameraInputSettings.m_translateBackwardChannelId = SandboxEditor::CameraTranslateBackwardChannelId().GetName();
m_cameraInputSettings.m_translateLeftChannelId = SandboxEditor::CameraTranslateLeftChannelId().GetName();
@@ -57,6 +57,9 @@ private:
bool m_orbitYawRotationInverted;
bool m_panInvertedX;
bool m_panInvertedY;
float m_defaultCameraPositionX;
float m_defaultCameraPositionY;
float m_defaultCameraPositionZ;
AZ::Crc32 RotateSmoothingVisibility() const
{
+18
View File
@@ -52,6 +52,9 @@ namespace SandboxEditor
constexpr AZStd::string_view CameraOrbitDollyIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitDollyId";
constexpr AZStd::string_view CameraOrbitPanIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitPanId";
constexpr AZStd::string_view CameraFocusIdSetting = "/Amazon/Preferences/Editor/Camera/FocusId";
constexpr AZStd::string_view CameraDefaultStartingPositionX = "/Amazon/Preferences/Editor/Camera/DefaultStartingPosition/x";
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)
@@ -111,6 +114,21 @@ namespace SandboxEditor
return AZStd::make_unique<EditorViewportSettingsCallbacksImpl>();
}
AZ::Vector3 DefaultEditorCameraPosition()
{
float xPosition = aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionX, 0.0));
float yPosition = aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionY, -10.0));
float zPosition = aznumeric_cast<float>(GetRegistry(CameraDefaultStartingPositionZ, 4.0));
return AZ::Vector3(xPosition, yPosition, zPosition);
}
void SetDefaultCameraEditorPosition(const AZ::Vector3 defaultCameraPosition)
{
SetRegistry(CameraDefaultStartingPositionX, defaultCameraPosition.GetX());
SetRegistry(CameraDefaultStartingPositionY, defaultCameraPosition.GetY());
SetRegistry(CameraDefaultStartingPositionZ, defaultCameraPosition.GetZ());
}
AZ::u64 MaxItemsShownInAssetBrowserSearch()
{
return GetRegistry(AssetBrowserMaxItemsShownInSearchSetting, aznumeric_cast<AZ::u64>(50));
+4
View File
@@ -12,6 +12,7 @@
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/Math/Vector3.h>
#include <AzFramework/Input/Channels/InputChannelId.h>
namespace SandboxEditor
@@ -32,6 +33,9 @@ namespace SandboxEditor
//! event will fire when a value in the settings registry (editorpreferences.setreg) is modified.
SANDBOX_API AZStd::unique_ptr<EditorViewportSettingsCallbacks> CreateEditorViewportSettingsCallbacks();
SANDBOX_API AZ::Vector3 DefaultEditorCameraPosition();
SANDBOX_API void SetDefaultCameraEditorPosition(AZ::Vector3 defaultCameraPosition);
SANDBOX_API AZ::u64 MaxItemsShownInAssetBrowserSearch();
SANDBOX_API void SetMaxItemsShownInAssetBrowserSearch(AZ::u64 numberOfItemsShown);
+16 -22
View File
@@ -112,7 +112,6 @@ void StartFixedCursorMode(QObject *viewport);
#define RENDER_MESH_TEST_DISTANCE (0.2f)
#define CURSOR_FONT_HEIGHT 8.0f
namespace AZ::ViewportHelpers
{
static const char TextCantCreateCameraNoLevel[] = "Cannot create camera when no level is loaded.";
@@ -623,16 +622,10 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
PopDisableRendering();
{
AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero());
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb);
float sx = terrainAabb.GetXExtent();
float sy = terrainAabb.GetYExtent();
Matrix34 viewTM;
viewTM.SetIdentity();
// Initial camera will be at middle of the map at the height of 2
// meters above the terrain (default terrain height is 32)
viewTM.SetTranslation(Vec3(sx * 0.5f, sy * 0.5f, 34.0f));
viewTM.SetTranslation(Vec3(m_editorViewportSettings.DefaultEditorCameraPosition()));
SetViewTM(viewTM);
UpdateScene();
@@ -647,16 +640,10 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
PopDisableRendering();
{
AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero());
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb);
float sx = terrainAabb.GetXExtent();
float sy = terrainAabb.GetYExtent();
Matrix34 viewTM;
viewTM.SetIdentity();
// Initial camera will be at middle of the map at the height of 2
// meters above the terrain (default terrain height is 32)
viewTM.SetTranslation(Vec3(sx * 0.5f, sy * 0.5f, 34.0f));
viewTM.SetTranslation(Vec3(m_editorViewportSettings.DefaultEditorCameraPosition()));
SetViewTM(viewTM);
}
break;
@@ -1345,10 +1332,6 @@ void EditorViewportWidget::keyPressEvent(QKeyEvent* event)
void EditorViewportWidget::SetViewTM(const Matrix34& tm)
{
if (m_viewSourceType == ViewSourceType::None)
{
m_defaultViewTM = tm;
}
SetViewTM(tm, false);
}
@@ -1445,6 +1428,10 @@ void EditorViewportWidget::SetViewTM(const Matrix34& camMatrix, bool bMoveOnly)
"Please report this as a bug."
);
}
else if (shouldUpdateObject == ShouldUpdateObject::No)
{
GetCurrentAtomView()->SetCameraTransform(LYTransformToAZMatrix3x4(camMatrix));
}
if (m_pressedKeyState == KeyPressedState::PressedThisFrame)
{
@@ -2028,6 +2015,9 @@ void EditorViewportWidget::SetDefaultCamera()
m_viewSourceType = ViewSourceType::None;
GetViewManager()->SetCameraObjectId(GUID_NULL);
SetName(m_defaultViewName);
// Set the default Editor Camera position.
m_defaultViewTM.SetTranslation(Vec3(m_editorViewportSettings.DefaultEditorCameraPosition()));
SetViewTM(m_defaultViewTM);
// Synchronize the configured editor viewport FOV to the default camera
@@ -2530,6 +2520,11 @@ bool EditorViewportSettings::StickySelectEnabled() const
return SandboxEditor::StickySelectEnabled();
}
AZ::Vector3 EditorViewportSettings::DefaultEditorCameraPosition() const
{
return SandboxEditor::DefaultEditorCameraPosition();
}
AZ_CVAR_EXTERNED(bool, ed_previewGameInFullscreen_once);
bool EditorViewportWidget::ShouldPreviewFullscreen() const
@@ -2641,5 +2636,4 @@ void EditorViewportWidget::StopFullscreenPreview()
// Show the main window
MainWindow::instance()->show();
}
#include <moc_EditorViewportWidget.cpp>
+1
View File
@@ -78,6 +78,7 @@ struct EditorViewportSettings : public AzToolsFramework::ViewportInteraction::Vi
float ManipulatorLineBoundWidth() const override;
float ManipulatorCircleBoundWidth() const override;
bool StickySelectEnabled() const override;
AZ::Vector3 DefaultEditorCameraPosition() const override;
};
// EditorViewportWidget window
+14 -14
View File
@@ -31,11 +31,11 @@
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
//////////////////////////////////////////////////////////////////////////
#define MUSIC_LEVEL_LIBRARY_FILE "Music.xml"
#define MATERIAL_LEVEL_LIBRARY_FILE "Materials.xml"
#define RESOURCE_LIST_FILE "ResourceList.txt"
#define USED_RESOURCE_LIST_FILE "UsedResourceList.txt"
#define SHADER_LIST_FILE "ShadersList.txt"
#define MUSIC_LEVEL_LIBRARY_FILE "music.xml"
#define MATERIAL_LEVEL_LIBRARY_FILE "materials.xml"
#define RESOURCE_LIST_FILE "resourcelist.txt"
#define USED_RESOURCE_LIST_FILE "usedresourcelist.txt"
#define SHADER_LIST_FILE "shaderslist.txt"
#define GetAValue(rgb) ((BYTE)((rgb) >> 24))
@@ -185,9 +185,9 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
ExportOcclusionMesh(sLevelPath.toUtf8().data());
//! Export Level data.
CLogFile::WriteLine("Exporting LevelData.xml");
CLogFile::WriteLine("Exporting leveldata.xml");
ExportLevelData(sLevelPath);
CLogFile::WriteLine("Exporting LevelData.xml done.");
CLogFile::WriteLine("Exporting leveldata.xml done.");
ExportLevelInfo(sLevelPath);
@@ -266,26 +266,26 @@ void CGameExporter::ExportOcclusionMesh(const char* pszGamePath)
void CGameExporter::ExportLevelData(const QString& path, bool /*bExportMission*/)
{
IEditor* pEditor = GetIEditor();
pEditor->SetStatusText(QObject::tr("Exporting LevelData.xml..."));
pEditor->SetStatusText(QObject::tr("Exporting leveldata.xml..."));
char versionString[256];
pEditor->GetFileVersion().ToString(versionString);
XmlNodeRef root = XmlHelpers::CreateXmlNode("LevelData");
XmlNodeRef root = XmlHelpers::CreateXmlNode("leveldata");
root->setAttr("SandboxVersion", versionString);
XmlNodeRef rootAction = XmlHelpers::CreateXmlNode("LevelDataAction");
XmlNodeRef rootAction = XmlHelpers::CreateXmlNode("leveldataaction");
rootAction->setAttr("SandboxVersion", versionString);
//////////////////////////////////////////////////////////////////////////
// Save Level Data XML
//////////////////////////////////////////////////////////////////////////
QString levelDataFile = path + "LevelData.xml";
QString levelDataFile = path + "leveldata.xml";
XmlString xmlData = root->getXML();
CCryMemFile file;
file.Write(xmlData.c_str(), static_cast<unsigned int>(xmlData.length()));
m_levelPak.m_pakFile.UpdateFile(levelDataFile.toUtf8().data(), file);
QString levelDataActionFile = path + "LevelDataAction.xml";
QString levelDataActionFile = path + "leveldataaction.xml";
XmlString xmlDataAction = rootAction->getXML();
CCryMemFile fileAction;
fileAction.Write(xmlDataAction.c_str(), static_cast<unsigned int>(xmlDataAction.length()));
@@ -298,7 +298,7 @@ void CGameExporter::ExportLevelData(const QString& path, bool /*bExportMission*/
if (savedEntities)
{
QString entitiesFile;
entitiesFile = QStringLiteral("%1%2.entities_xml").arg(path, "Mission0");
entitiesFile = QStringLiteral("%1%2.entities_xml").arg(path, "mission0");
m_levelPak.m_pakFile.UpdateFile(entitiesFile.toUtf8().data(), entitySaveBuffer.begin(), static_cast<int>(entitySaveBuffer.size()));
}
}
@@ -326,7 +326,7 @@ void CGameExporter::ExportLevelInfo(const QString& path)
//////////////////////////////////////////////////////////////////////////
// Save LevelInfo file.
//////////////////////////////////////////////////////////////////////////
QString filename = path + "LevelInfo.xml";
QString filename = path + "levelinfo.xml";
XmlString xmlData = root->getXML();
CCryMemFile file;
@@ -38,6 +38,8 @@ namespace UnitTest
void BeginCursorCapture() override;
void EndCursorCapture() override;
bool IsMouseOver() const override;
void SetOverrideCursor(AzToolsFramework::ViewportInteraction::CursorStyleOverride cursorStyleOverride) override;
void ClearOverrideCursor() override;
private:
AzToolsFramework::QtEventToAzInputMapper* m_inputChannelMapper = nullptr;
@@ -58,6 +60,17 @@ namespace UnitTest
return true;
}
void ViewportMouseCursorRequestImpl::SetOverrideCursor(
[[maybe_unused]] AzToolsFramework::ViewportInteraction::CursorStyleOverride cursorStyleOverride)
{
// noop
}
void ViewportMouseCursorRequestImpl::ClearOverrideCursor()
{
// noop
}
class ModularViewportCameraControllerFixture : public AllocatorsTestFixture
{
public:
@@ -76,6 +76,7 @@ namespace AZ
else if (info.m_status == AzToolsFramework::SourceControlStatus::SCS_ProviderIsDown)
{
message = "Failed to put entries/dependencies into source control as the provider is not available.\n";
reportAsWarning = true;
}
else if (info.m_status == AzToolsFramework::SourceControlStatus::SCS_CertificateInvalid)
{
+3 -1
View File
@@ -577,7 +577,9 @@ namespace AZ
}
azstrcat(lines[i], AZ_ARRAY_SIZE(lines[i]), "\n");
AZ_Printf(window, "%s", lines[i]); // feed back into the trace system so that listeners can get it.
// Use Output instead of AZ_Printf to be consistent with the exception output code and avoid
// this accidentally being suppressed as a normal message
Output(window, lines[i]);
}
}
}
@@ -43,7 +43,7 @@ namespace AzFramework
class IMatchmakingAsyncRequests
{
public:
AZ_RTTI(ISessionAsyncRequests, "{53513480-2D02-493C-B44E-96AA27F42429}");
AZ_RTTI(IMatchmakingAsyncRequests, "{53513480-2D02-493C-B44E-96AA27F42429}");
IMatchmakingAsyncRequests() = default;
virtual ~IMatchmakingAsyncRequests() = default;
@@ -60,4 +60,31 @@ namespace AzFramework
// @param stopMatchmakingRequest The request of StopMatchmaking operation
virtual void StopMatchmakingAsync(const StopMatchmakingRequest& stopMatchmakingRequest) = 0;
};
//! MatchmakingAsyncRequestNotifications
//! The notifications correspond to matchmaking async requests
class MatchmakingAsyncRequestNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
// OnAcceptMatchAsyncComplete is fired once AcceptMatchAsync completes
virtual void OnAcceptMatchAsyncComplete() = 0;
// OnStartMatchmakingAsyncComplete is fired once StartMatchmakingAsync completes
// @param matchmakingTicketId The unique identifier for the matchmaking ticket
virtual void OnStartMatchmakingAsyncComplete(const AZStd::string& matchmakingTicketId) = 0;
// OnStopMatchmakingAsyncComplete is fired once StopMatchmakingAsync completes
virtual void OnStopMatchmakingAsyncComplete() = 0;
};
using MatchmakingAsyncRequestNotificationBus = AZ::EBus<MatchmakingAsyncRequestNotifications>;
} // namespace AzFramework
@@ -13,36 +13,10 @@
namespace AzFramework
{
//! MatchmakingAsyncRequestNotifications
//! The notifications correspond to matchmaking async requests
class MatchmakingAsyncRequestNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
// OnAcceptMatchAsyncComplete is fired once AcceptMatchAsync completes
virtual void OnAcceptMatchAsyncComplete() = 0;
// OnStartMatchmakingAsyncComplete is fired once StartMatchmakingAsync completes
// @param matchmakingTicketId The unique identifier for the matchmaking ticket
virtual void OnStartMatchmakingAsyncComplete(const AZStd::string& matchmakingTicketId) = 0;
// OnStopMatchmakingAsyncComplete is fired once StopMatchmakingAsync completes
virtual void OnStopMatchmakingAsyncComplete() = 0;
};
using MatchmakingAsyncRequestNotificationBus = AZ::EBus<MatchmakingAsyncRequestNotifications>;
//! MatchmakingNotifications
//! The matchmaking notifications to listen for performing required operations
class MatchAcceptanceNotifications
//! based on matchmaking ticket event
class MatchmakingNotifications
: public AZ::EBusTraits
{
public:
@@ -55,8 +29,18 @@ namespace AzFramework
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
// OnMatchAcceptance is fired when DescribeMatchmaking ticket status is REQUIRES_ACCEPTANCE
// OnMatchAcceptance is fired when match is found and pending on acceptance
// Use this notification to accept found match
virtual void OnMatchAcceptance() = 0;
// OnMatchComplete is fired when match is complete
virtual void OnMatchComplete() = 0;
// OnMatchError is fired when match is processed with error
virtual void OnMatchError() = 0;
// OnMatchFailure is fired when match is failed to complete
virtual void OnMatchFailure() = 0;
};
using MatchAcceptanceNotificationBus = AZ::EBus<MatchAcceptanceNotifications>;
using MatchmakingNotificationBus = AZ::EBus<MatchmakingNotifications>;
} // namespace AzFramework
@@ -46,6 +46,8 @@ namespace AzManipulatorTestFramework
virtual void UpdateVisibility() = 0;
//! Set if sticky select is enabled or not.
virtual void SetStickySelect(bool enabled) = 0;
//! Get default Editor Camera Position.
virtual AZ::Vector3 DefaultEditorCameraPosition() const = 0;
};
//! This interface is used to simulate the manipulator manager while the manipulators are under test.
@@ -36,6 +36,7 @@ namespace AzManipulatorTestFramework
int GetViewportId() const override;
void UpdateVisibility() override;
void SetStickySelect(bool enabled) override;
AZ::Vector3 DefaultEditorCameraPosition() const override;
// ViewportInteractionRequestBus overrides ...
AzFramework::CameraState GetCameraState() override;
@@ -120,6 +120,11 @@ namespace AzManipulatorTestFramework
m_stickySelect = enabled;
}
AZ::Vector3 ViewportInteraction::DefaultEditorCameraPosition() const
{
return {};
}
void ViewportInteraction::SetGridSize(float size)
{
m_gridSize = size;
@@ -65,7 +65,7 @@ namespace AzNetworking
: m_delta(delta)
, m_dataSerializer(m_delta.GetBufferPtr(), m_delta.GetBufferCapacity())
{
m_namePrefix.reserve(128);
;
}
DeltaSerializerCreate::~DeltaSerializerCreate()
@@ -73,7 +73,7 @@ namespace AzNetworking
// Delete any left over records that might be hanging around
for (auto iter : m_records)
{
delete iter.second;
delete iter;
}
m_records.clear();
}
@@ -160,28 +160,13 @@ namespace AzNetworking
return SerializeHelper(buffer, bufferCapacity, isString, outSize, name);
}
AZStd::string DeltaSerializerCreate::GetNextObjectName(const char* name)
bool DeltaSerializerCreate::BeginObject([[maybe_unused]] const char* name, [[maybe_unused]] const char* typeName)
{
AZStd::string objectName = name;
objectName += ".";
objectName += AZStd::to_string(m_objectCounter);
++m_objectCounter;
return objectName;
}
bool DeltaSerializerCreate::BeginObject(const char* name, [[maybe_unused]] const char* typeName)
{
m_nameLengthStack.push_back(m_namePrefix.length());
m_namePrefix += GetNextObjectName(name);
m_namePrefix += ".";
return true;
}
bool DeltaSerializerCreate::EndObject([[maybe_unused]] const char* name, [[maybe_unused]] const char* typeName)
{
const size_t prevLen = m_nameLengthStack.back();
m_nameLengthStack.pop_back();
m_namePrefix.resize(prevLen);
return true;
}
@@ -205,25 +190,15 @@ namespace AzNetworking
{
typedef AbstractValue::ValueT<T> ValueType;
const size_t prevLen = m_namePrefix.length();
m_namePrefix += GetNextObjectName(name);
const AZ::HashValue32 nameHash = AZ::TypeHash32(m_namePrefix.c_str());
m_namePrefix.resize(prevLen);
AbstractValue::BaseValue*& baseValue = m_records[nameHash];
AbstractValue::BaseValue* baseValue = m_records.size() > m_objectCounter ? m_records[m_objectCounter] : nullptr;
++m_objectCounter;
// If we are in the gather records phase, just save off the value records
if (m_gatheringRecords)
{
if (baseValue != nullptr)
{
AZ_Assert(false, "Duplicate name encountered in delta serializer. This will cause data to be serialized incorrectly.");
return false;
}
AZ_Assert(baseValue == nullptr, "Expected to create a new record but found a pre-existing one at index %d", m_objectCounter - 1);
baseValue = new ValueType(value);
m_records.push_back(baseValue);
}
else // If we are not gathering records, then we are comparing them
{
@@ -90,8 +90,6 @@ namespace AzNetworking
DeltaSerializerCreate(const DeltaSerializerCreate&) = delete;
DeltaSerializerCreate& operator=(const DeltaSerializerCreate&) = delete;
AZStd::string GetNextObjectName(const char* name);
template <typename T>
bool SerializeHelper(T& value, uint32_t bufferCapacity, bool isString, uint32_t& outSize, const char* name);
@@ -105,9 +103,7 @@ namespace AzNetworking
bool m_gatheringRecords = false;
uint32_t m_objectCounter = 0;
AZStd::string m_namePrefix;
AZStd::vector<size_t> m_nameLengthStack;
AZStd::unordered_map<AZ::HashValue32, AbstractValue::BaseValue*> m_records;
AZStd::vector<AbstractValue::BaseValue*> m_records;
NetworkInputSerializer m_dataSerializer;
};
@@ -11,4 +11,213 @@
namespace UnitTest
{
struct DeltaDataElement
{
AzNetworking::PacketId m_packetId = AzNetworking::InvalidPacketId;
uint32_t m_id = 0;
AZ::TimeMs m_timeMs = AZ::TimeMs{ 0 };
float m_blendFactor = 0.f;
AZStd::vector<int> m_growVector, m_shrinkVector;
bool Serialize(AzNetworking::ISerializer& serializer)
{
if (!serializer.Serialize(m_packetId, "PacketId")
|| !serializer.Serialize(m_id, "Id")
|| !serializer.Serialize(m_timeMs, "TimeMs")
|| !serializer.Serialize(m_blendFactor, "BlendFactor")
|| !serializer.Serialize(m_growVector, "GrowVector")
|| !serializer.Serialize(m_shrinkVector, "ShrinkVector"))
{
return false;
}
return true;
}
};
struct DeltaDataContainer
{
AZStd::string m_containerName;
AZStd::array<DeltaDataElement, 32> m_container;
// This logic is modeled after NetworkInputArray serialization in the Multiplayer Gem
bool Serialize(AzNetworking::ISerializer& serializer)
{
// Always serialize the full first element
if(!m_container[0].Serialize(serializer))
{
return false;
}
for (uint32_t i = 1; i < m_container.size(); ++i)
{
if (serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject)
{
AzNetworking::SerializerDelta deltaSerializer;
// Read out the delta
if (!deltaSerializer.Serialize(serializer))
{
return false;
}
// Start with previous value
m_container[i] = m_container[i - 1];
// Then apply delta
AzNetworking::DeltaSerializerApply applySerializer(deltaSerializer);
if (!applySerializer.ApplyDelta(m_container[i]))
{
return false;
}
}
else
{
AzNetworking::SerializerDelta deltaSerializer;
// Create the delta
AzNetworking::DeltaSerializerCreate createSerializer(deltaSerializer);
if (!createSerializer.CreateDelta(m_container[i - 1], m_container[i]))
{
return false;
}
// Then write out the delta
if (!deltaSerializer.Serialize(serializer))
{
return false;
}
}
}
return true;
}
// This logic is modeled after NetworkInputArray serialization in the Multiplayer Gem
bool SerializeNoDelta(AzNetworking::ISerializer& serializer)
{
for (uint32_t i = 0; i < m_container.size(); ++i)
{
if(!m_container[i].Serialize(serializer))
{
return false;
}
}
return true;
}
};
class DeltaSerializerTests
: public UnitTest::AllocatorsTestFixture
{
public:
void SetUp() override
{
UnitTest::AllocatorsTestFixture::SetUp();
}
void TearDown() override
{
UnitTest::AllocatorsTestFixture::TearDown();
}
};
static constexpr float BLEND_FACTOR_SCALE = 1.1f;
static constexpr uint32_t TIME_SCALE = 10;
DeltaDataContainer TestDeltaContainer()
{
DeltaDataContainer testContainer;
AZStd::vector<int> growVector, shrinkVector;
shrinkVector.resize(testContainer.m_container.array_size);
testContainer.m_containerName = "TestContainer";
for (int i = 0; i < testContainer.m_container.array_size; ++i)
{
testContainer.m_container[i].m_packetId = AzNetworking::PacketId(i);
testContainer.m_container[i].m_id = i;
testContainer.m_container[i].m_timeMs = AZ::TimeMs(i * TIME_SCALE);
testContainer.m_container[i].m_blendFactor = BLEND_FACTOR_SCALE * i;
growVector.push_back(i);
testContainer.m_container[i].m_growVector = growVector;
shrinkVector.resize(testContainer.m_container.array_size - i);
testContainer.m_container[i].m_shrinkVector = shrinkVector;
}
return testContainer;
}
TEST_F(DeltaSerializerTests, DeltaArray)
{
DeltaDataContainer inContainer = TestDeltaContainer();
AZStd::array<uint8_t, 2048> buffer;
AzNetworking::NetworkInputSerializer inSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
// Always serialize the full first element
EXPECT_TRUE(inContainer.Serialize(inSerializer));
DeltaDataContainer outContainer;
AzNetworking::NetworkOutputSerializer outSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
EXPECT_TRUE(outContainer.Serialize(outSerializer));
for (uint32_t i = 0; i > outContainer.m_container.size(); ++i)
{
EXPECT_EQ(inContainer.m_container[i].m_blendFactor, outContainer.m_container[i].m_blendFactor);
EXPECT_EQ(inContainer.m_container[i].m_id, outContainer.m_container[i].m_id);
EXPECT_EQ(inContainer.m_container[i].m_packetId, outContainer.m_container[i].m_packetId);
EXPECT_EQ(inContainer.m_container[i].m_timeMs, outContainer.m_container[i].m_timeMs);
EXPECT_EQ(inContainer.m_container[i].m_growVector[i], outContainer.m_container[i].m_growVector[i]);
EXPECT_EQ(inContainer.m_container[i].m_growVector.size(), outContainer.m_container[i].m_growVector.size());
EXPECT_EQ(inContainer.m_container[i].m_shrinkVector.size(), outContainer.m_container[i].m_shrinkVector.size());
}
}
TEST_F(DeltaSerializerTests, DeltaSerializerCreateUnused)
{
// Every function here should return a constant value regardless of inputs
AzNetworking::SerializerDelta deltaSerializer;
AzNetworking::DeltaSerializerCreate createSerializer(deltaSerializer);
EXPECT_EQ(createSerializer.GetCapacity(), 0);
EXPECT_EQ(createSerializer.GetSize(), 0);
EXPECT_EQ(createSerializer.GetBuffer(), nullptr);
EXPECT_EQ(createSerializer.GetSerializerMode(), AzNetworking::SerializerMode::ReadFromObject);
createSerializer.ClearTrackedChangesFlag(); //NO-OP
EXPECT_FALSE(createSerializer.GetTrackedChangesFlag());
EXPECT_TRUE(createSerializer.BeginObject("CreateSerializer", "Begin"));
EXPECT_TRUE(createSerializer.EndObject("CreateSerializer", "End"));
}
TEST_F(DeltaSerializerTests, DeltaArraySize)
{
DeltaDataContainer deltaContainer = TestDeltaContainer();
DeltaDataContainer noDeltaContainer = TestDeltaContainer();
AZStd::array<uint8_t, 2048> deltaBuffer;
AzNetworking::NetworkInputSerializer deltaSerializer(deltaBuffer.data(), static_cast<uint32_t>(deltaBuffer.size()));
AZStd::array<uint8_t, 2048> noDeltaBuffer;
AzNetworking::NetworkInputSerializer noDeltaSerializer(noDeltaBuffer.data(), static_cast<uint32_t>(noDeltaBuffer.size()));
EXPECT_TRUE(deltaContainer.Serialize(deltaSerializer));
EXPECT_FALSE(noDeltaContainer.SerializeNoDelta(noDeltaSerializer)); // Should run out of space
EXPECT_EQ(noDeltaSerializer.GetCapacity(), noDeltaSerializer.GetSize()); // Verify that the serializer filled up
EXPECT_FALSE(noDeltaSerializer.IsValid()); // and that it is no longer valid due to lack of space
}
TEST_F(DeltaSerializerTests, DeltaSerializerApplyUnused)
{
// Every function here should return a constant value regardless of inputs
AzNetworking::SerializerDelta deltaSerializer;
AzNetworking::DeltaSerializerApply applySerializer(deltaSerializer);
EXPECT_EQ(applySerializer.GetCapacity(), 0);
EXPECT_EQ(applySerializer.GetSize(), 0);
EXPECT_EQ(applySerializer.GetBuffer(), nullptr);
EXPECT_EQ(applySerializer.GetSerializerMode(), AzNetworking::SerializerMode::WriteToObject);
applySerializer.ClearTrackedChangesFlag(); //NO-OP
EXPECT_FALSE(applySerializer.GetTrackedChangesFlag());
EXPECT_TRUE(applySerializer.BeginObject("CreateSerializer", "Begin"));
EXPECT_TRUE(applySerializer.EndObject("CreateSerializer", "End"));
}
}
@@ -5,24 +5,19 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <QCursor>
#include <AzCore/Component/Entity.h>
#include <AzQtComponents/Components/ToastNotification.h>
#include <AzQtComponents/Components/ui_ToastNotification.h>
#include <GraphCanvas/Widgets/ToastNotification/ToastNotification.h>
#include <StaticLib/GraphCanvas/Widgets/ToastNotification/ui_ToastNotification.h>
#include <QCursor>
#include <QIcon>
#include <QToolButton>
#include <QPropertyAnimation>
#include <GraphCanvas/Components/ToastBus.h>
namespace GraphCanvas
namespace AzQtComponents
{
//////////////////////
// ToastNotification
//////////////////////
ToastNotification::ToastNotification(QWidget* parent, const ToastConfiguration& toastConfiguration)
: QDialog(parent, Qt::FramelessWindowHint)
, m_toastId(AZ::Entity::MakeId())
, m_closeOnClick(true)
, m_ui(new Ui::ToastNotification())
, m_fadeAnimation(nullptr)
@@ -36,35 +31,35 @@ namespace GraphCanvas
QIcon toastIcon;
switch (toastConfiguration.GetToastType())
switch (toastConfiguration.m_toastType)
{
case ToastType::Error:
toastIcon = QIcon(":/GraphCanvasEditorResources/toast_error_icon.png");
toastIcon = QIcon(":/stylesheet/img/logging/error.svg");
break;
case ToastType::Warning:
toastIcon = QIcon(":/GraphCanvasEditorResources/toast_warning_icon.png");
toastIcon = QIcon(":/stylesheet/img/logging/warning-yellow.svg");
break;
case ToastType::Information:
toastIcon = QIcon(":/GraphCanvasEditorResources/toast_information_icon.png");
toastIcon = QIcon(":/stylesheet/img/logging/information.svg");
break;
case ToastType::Custom:
toastIcon = QIcon(toastConfiguration.GetCustomToastImage().c_str());
toastIcon = QIcon(toastConfiguration.m_customIconImage);
default:
break;
}
m_ui->iconLabel->setPixmap(toastIcon.pixmap(64, 64));
m_ui->titleLabel->setText(toastConfiguration.GetTitleLabel().c_str());
m_ui->mainLabel->setText(toastConfiguration.GetDescriptionLabel().c_str());
m_ui->titleLabel->setText(toastConfiguration.m_title);
m_ui->mainLabel->setText(toastConfiguration.m_description);
m_lifeSpan.setInterval(aznumeric_cast<int>(toastConfiguration.GetDuration().count()));
m_closeOnClick = toastConfiguration.GetCloseOnClick();
m_lifeSpan.setInterval(aznumeric_cast<int>(toastConfiguration.m_duration.count()));
m_closeOnClick = toastConfiguration.m_closeOnClick;
m_ui->closeButton->setVisible(m_closeOnClick);
QObject::connect(m_ui->closeButton, &QToolButton::clicked, this, &ToastNotification::accept);
m_fadeDuration = toastConfiguration.GetFadeDuration();
m_fadeDuration = toastConfiguration.m_fadeDuration;
QObject::connect(&m_lifeSpan, &QTimer::timeout, this, &ToastNotification::FadeOut);
}
@@ -73,11 +68,6 @@ namespace GraphCanvas
{
}
ToastId ToastNotification::GetToastId() const
{
return m_toastId;
}
void ToastNotification::ShowToastAtCursor()
{
QPoint globalCursorPos = QCursor::pos();
@@ -131,8 +121,6 @@ namespace GraphCanvas
{
StartTimer();
}
emit ToastNotificationShown();
}
void ToastNotification::hideEvent(QHideEvent* hideEvent)
@@ -147,7 +135,6 @@ namespace GraphCanvas
delete m_fadeAnimation;
}
ToastNotificationBus::Event(GetToastId(), &ToastNotifications::OnToastDismissed);
emit ToastNotificationHidden();
}
@@ -155,7 +142,7 @@ namespace GraphCanvas
{
if (m_closeOnClick)
{
ToastNotificationBus::Event(GetToastId(), &ToastNotifications::OnToastInteraction);
emit ToastNotificationInteraction();
accept();
}
}
@@ -205,5 +192,5 @@ namespace GraphCanvas
accept();
}
}
#include <StaticLib/GraphCanvas/Widgets/ToastNotification/moc_ToastNotification.cpp>
#include "Components/moc_ToastNotification.cpp"
}
@@ -8,17 +8,13 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzQtComponents/AzQtComponentsAPI.h>
#include <AzQtComponents/Components/ToastNotificationConfiguration.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <QEvent>
#include <QDialog>
#include <QMouseEvent>
#include <QPropertyAnimation>
#include <QTimer>
#include <AzCore/Component/TickBus.h>
#include <AzCore/std/chrono/chrono.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <GraphCanvas/Editor/EditorTypes.h>
#endif
namespace Ui
@@ -26,20 +22,20 @@ namespace Ui
class ToastNotification;
}
namespace GraphCanvas
QT_FORWARD_DECLARE_CLASS(QPropertyAnimation)
namespace AzQtComponents
{
class ToastNotification
class AZ_QT_COMPONENTS_API ToastNotification
: public QDialog
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(ToastNotification, AZ::SystemAllocator, 0);
ToastNotification(QWidget* parent, const ToastConfiguration& configuration);
ToastNotification(QWidget* parent, const ToastConfiguration& toastConfiguration);
virtual ~ToastNotification();
ToastId GetToastId() const;
// Shows the toast notification relative to the current cursor.
void ShowToastAtCursor();
@@ -53,30 +49,26 @@ namespace GraphCanvas
// QDialog
void showEvent(QShowEvent* showEvent) override;
void hideEvent(QHideEvent* hideEvent) override;
void mousePressEvent(QMouseEvent* mouseEvent) override;
bool eventFilter(QObject* object, QEvent* event) override;
////
public slots:
void StartTimer();
void FadeOut();
signals:
void ToastNotificationShown();
void ToastNotificationHidden();
void ToastNotificationInteraction();
private:
QPropertyAnimation* m_fadeAnimation;
AZStd::chrono::milliseconds m_fadeDuration;
ToastId m_toastId;
bool m_closeOnClick;
QTimer m_lifeSpan;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZStd::chrono::milliseconds m_fadeDuration;
AZStd::unique_ptr<Ui::ToastNotification> m_ui;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
}
} // namespace AzQtComponents
@@ -101,7 +101,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../Resources/GraphCanvasEditorResources.qrc">:/GraphCanvasEditorResources/toast_information_icon.png</pixmap>
<pixmap resource="resources.qrc">:/stylesheet/img/logging/information.svg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
@@ -203,8 +203,8 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="../Resources/GraphCanvasEditorResources.qrc">
<normaloff>:/GraphCanvasEditorResources/lineedit_clear.png</normaloff>:/GraphCanvasEditorResources/lineedit_clear.png</iconset>
<iconset resource="resources.qrc">
<normaloff>:/stylesheet/img/close_x.svg</normaloff>:/stylesheet/img/close_x.svg</iconset>
</property>
</widget>
</item>
@@ -230,8 +230,7 @@
</layout>
</widget>
<resources>
<include location="../Resources/GraphCanvasEditorResources.qrc"/>
<include location="../Resources/GraphCanvasEditorResources.qrc"/>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>
@@ -0,0 +1,18 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzQtComponents/Components/ToastNotificationConfiguration.h>
namespace AzQtComponents
{
ToastConfiguration::ToastConfiguration(ToastType toastType, const QString& title, const QString& description)
: m_toastType(toastType)
, m_title(title)
, m_description(description)
{
}
} // namespace AzQtComponents
@@ -0,0 +1,46 @@
/*
* 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
#if !defined(Q_MOC_RUN)
#include <AzQtComponents/AzQtComponentsAPI.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/chrono/chrono.h>
#include <QString>
#endif
namespace AzQtComponents
{
enum class ToastType
{
Information,
Warning,
Error,
Custom
};
class AZ_QT_COMPONENTS_API ToastConfiguration
{
public:
AZ_CLASS_ALLOCATOR(ToastConfiguration, AZ::SystemAllocator, 0);
ToastConfiguration(ToastType toastType, const QString& title, const QString& description);
bool m_closeOnClick = true;
ToastType m_toastType = ToastType::Information;
QString m_title;
QString m_description;
QString m_customIconImage;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZStd::chrono::milliseconds m_duration = AZStd::chrono::milliseconds(5000);
AZStd::chrono::milliseconds m_fadeDuration = AZStd::chrono::milliseconds(250);
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
} // namespace AzQtComponents
@@ -49,6 +49,11 @@ set(FILES
Components/Titlebar.h
Components/TitleBarOverdrawHandler.cpp
Components/TitleBarOverdrawHandler.h
Components/ToastNotification.cpp
Components/ToastNotification.h
Components/ToastNotificationConfiguration.h
Components/ToastNotificationConfiguration.cpp
Components/ToastNotification.ui
Components/ToolButtonComboBox.cpp
Components/ToolButtonComboBox.h
Components/ToolButtonLineEdit.cpp
@@ -53,7 +53,7 @@ namespace AzToolsFramework
AZ_Assert(m_loaderInterface != nullptr,
"Couldn't get prefab loader interface, it's a requirement for PrefabEntityOwnership system to work");
m_rootInstance = AZStd::unique_ptr<Prefab::Instance>(m_prefabSystemComponent->CreatePrefab({}, {}, "NewLevel.prefab"));
m_rootInstance = AZStd::unique_ptr<Prefab::Instance>(m_prefabSystemComponent->CreatePrefab({}, {}, "newLevel.prefab"));
m_sliceOwnershipService.BusConnect(m_entityContextId);
m_sliceOwnershipService.m_shouldAssertForLegacySlicesUsage = m_shouldAssertForLegacySlicesUsage;
m_editorSliceOwnershipService.BusConnect();
@@ -244,6 +244,17 @@ namespace AzToolsFramework
const auto eventType = event->type();
if (eventType == QEvent::Type::MouseMove)
{
// clear override cursor when moving outside of the viewport
const auto* mouseEvent = static_cast<const QMouseEvent*>(event);
if (m_overrideCursor && !m_sourceWidget->geometry().contains(m_sourceWidget->mapFromGlobal(mouseEvent->globalPos())))
{
qApp->restoreOverrideCursor();
m_overrideCursor = false;
}
}
// Only accept mouse & key release events that originate from an object that is not our target widget,
// as we don't want to erroneously intercept user input meant for another component.
if (object != m_sourceWidget && eventType != QEvent::Type::KeyRelease && eventType != QEvent::Type::MouseButtonRelease)
@@ -262,7 +273,7 @@ namespace AzToolsFramework
if (eventType == QEvent::FocusIn)
{
const auto globalCursorPosition = QCursor::pos();
if (m_sourceWidget->geometry().contains(globalCursorPosition))
if (m_sourceWidget->geometry().contains(m_sourceWidget->mapFromGlobal(globalCursorPosition)))
{
HandleMouseMoveEvent(globalCursorPosition);
}
@@ -452,4 +463,32 @@ namespace AzToolsFramework
}
}
}
static Qt::CursorShape QtCursorFromAzCursor(const ViewportInteraction::CursorStyleOverride cursorStyleOverride)
{
switch (cursorStyleOverride)
{
case ViewportInteraction::CursorStyleOverride::Forbidden:
return Qt::ForbiddenCursor;
default:
return Qt::ArrowCursor;
}
}
void QtEventToAzInputMapper::SetOverrideCursor(ViewportInteraction::CursorStyleOverride cursorStyleOverride)
{
ClearOverrideCursor();
qApp->setOverrideCursor(QtCursorFromAzCursor(cursorStyleOverride));
m_overrideCursor = true;
}
void QtEventToAzInputMapper::ClearOverrideCursor()
{
if (m_overrideCursor)
{
qApp->restoreOverrideCursor();
m_overrideCursor = false;
}
}
} // namespace AzToolsFramework
@@ -15,10 +15,11 @@
#include <AzFramework/Input/Channels/InputChannelDeltaWithSharedPosition2D.h>
#include <AzFramework/Input/Channels/InputChannelDigitalWithSharedModifierKeyStates.h>
#include <AzFramework/Input/Channels/InputChannelDigitalWithSharedPosition2D.h>
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <QEvent>
#include <QObject>
#include <QPoint>
@@ -55,6 +56,9 @@ namespace AzToolsFramework
//! like a dolly or rotation, where mouse movement is important but cursor location is not.
void SetCursorCaptureEnabled(bool enabled);
void SetOverrideCursor(ViewportInteraction::CursorStyleOverride cursorStyleOverride);
void ClearOverrideCursor();
// QObject overrides...
bool eventFilter(QObject* object, QEvent* event) override;
@@ -164,6 +168,8 @@ namespace AzToolsFramework
bool m_enabled = true;
// Flags whether or not the cursor is being constrained to the source widget (for invisible mouse movement).
bool m_capturingCursor = false;
// Flags whether the cursor has been overridden.
bool m_overrideCursor = false;
// Our viewport-specific AZ devices. We control their internal input channel states.
AZStd::unique_ptr<EditorQtMouseDevice> m_mouseDevice;
@@ -28,7 +28,9 @@ namespace AzToolsFramework::Prefab
"Instance Entity Mapper Interface could not be found. "
"Check that it is being correctly initialized.");
EditorEntityInfoNotificationBus::Handler::BusConnect();
EditorEntityContextNotificationBus::Handler::BusConnect();
PrefabPublicNotificationBus::Handler::BusConnect();
AZ::Interface<PrefabFocusInterface>::Register(this);
AZ::Interface<PrefabFocusPublicInterface>::Register(this);
}
@@ -37,10 +39,12 @@ namespace AzToolsFramework::Prefab
{
AZ::Interface<PrefabFocusPublicInterface>::Unregister(this);
AZ::Interface<PrefabFocusInterface>::Unregister(this);
PrefabPublicNotificationBus::Handler::BusDisconnect();
EditorEntityContextNotificationBus::Handler::BusDisconnect();
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
}
void PrefabFocusHandler::Initialize()
void PrefabFocusHandler::InitializeEditorInterfaces()
{
m_containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
AZ_Assert(
@@ -55,13 +59,6 @@ namespace AzToolsFramework::Prefab
"Prefab - PrefabFocusHandler - "
"Focus Mode Interface could not be found. "
"Check that it is being correctly initialized.");
m_instanceEntityMapperInterface = AZ::Interface<InstanceEntityMapperInterface>::Get();
AZ_Assert(
m_instanceEntityMapperInterface,
"Prefab - PrefabFocusHandler - "
"Instance Entity Mapper Interface could not be found. "
"Check that it is being correctly initialized.");
}
PrefabFocusOperationResult PrefabFocusHandler::FocusOnOwningPrefab(AZ::EntityId entityId)
@@ -90,12 +87,12 @@ namespace AzToolsFramework::Prefab
PrefabFocusOperationResult PrefabFocusHandler::FocusOnPathIndex([[maybe_unused]] AzFramework::EntityContextId entityContextId, int index)
{
if (index < 0 || index >= m_instanceFocusVector.size())
if (index < 0 || index >= m_instanceFocusHierarchy.size())
{
return AZ::Failure(AZStd::string("Prefab Focus Handler: Invalid index on FocusOnPathIndex."));
}
InstanceOptionalReference focusedInstance = m_instanceFocusVector[index];
InstanceOptionalReference focusedInstance = m_instanceFocusHierarchy[index];
FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId());
@@ -134,42 +131,38 @@ namespace AzToolsFramework::Prefab
return AZ::Failure(AZStd::string("Prefab Focus Handler: invalid instance to focus on."));
}
if (!m_isInitialized)
// Close all container entities in the old path.
CloseInstanceContainers(m_instanceFocusHierarchy);
m_focusedInstance = focusedInstance;
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
AZ::EntityId containerEntityId;
if (focusedInstance->get().GetParentInstance() != AZStd::nullopt)
{
Initialize();
containerEntityId = focusedInstance->get().GetContainerEntityId();
}
if (!m_focusedInstance.has_value() || &m_focusedInstance->get() != &focusedInstance->get())
else
{
// Close all container entities in the old path
CloseInstanceContainers(m_instanceFocusVector);
m_focusedInstance = focusedInstance;
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
AZ::EntityId containerEntityId;
if (focusedInstance->get().GetParentInstance() != AZStd::nullopt)
{
containerEntityId = focusedInstance->get().GetContainerEntityId();
}
else
{
containerEntityId = AZ::EntityId();
}
containerEntityId = AZ::EntityId();
}
// Focus on the descendants of the container entity
// Focus on the descendants of the container entity in the Editor, if the interface is initialized.
if (m_focusModeInterface)
{
m_focusModeInterface->SetFocusRoot(containerEntityId);
// Refresh path variables
RefreshInstanceFocusList();
// Open all container entities in the new path
OpenInstanceContainers(m_instanceFocusVector);
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
}
// Refresh path variables.
RefreshInstanceFocusList();
RefreshInstanceFocusPath();
// Open all container entities in the new path.
OpenInstanceContainers(m_instanceFocusHierarchy);
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
return AZ::Success();
}
@@ -220,49 +213,80 @@ namespace AzToolsFramework::Prefab
const int PrefabFocusHandler::GetPrefabFocusPathLength([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
return aznumeric_cast<int>(m_instanceFocusVector.size());
return aznumeric_cast<int>(m_instanceFocusHierarchy.size());
}
void PrefabFocusHandler::OnEntityStreamLoadSuccess()
void PrefabFocusHandler::OnContextReset()
{
if (!m_isInitialized)
{
Initialize();
}
// Clear the old focus vector
m_instanceFocusVector.clear();
m_instanceFocusHierarchy.clear();
// Focus on the root prefab (AZ::EntityId() will default to it)
FocusOnPrefabInstanceOwningEntityId(AZ::EntityId());
}
void PrefabFocusHandler::OnEntityInfoUpdatedName(AZ::EntityId entityId, [[maybe_unused]]const AZStd::string& name)
{
// Determine if the entityId is the container for any of the instances in the vector
auto result = AZStd::find_if(
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
[entityId](const InstanceOptionalReference& instance)
{
return (instance->get().GetContainerEntityId() == entityId);
}
);
if (result != m_instanceFocusHierarchy.end())
{
// Refresh the path and notify changes.
RefreshInstanceFocusPath();
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
}
}
void PrefabFocusHandler::OnPrefabInstancePropagationEnd()
{
// Refresh the path and notify changes in case propagation updated any container names.
RefreshInstanceFocusPath();
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
}
void PrefabFocusHandler::RefreshInstanceFocusList()
{
m_instanceFocusVector.clear();
m_instanceFocusPath.clear();
m_instanceFocusHierarchy.clear();
AZStd::list<InstanceOptionalReference> instanceFocusList;
// Use a support list to easily push front while traversing the prefab hierarchy
InstanceOptionalReference currentInstance = m_focusedInstance;
while (currentInstance.has_value())
{
instanceFocusList.push_front(currentInstance);
m_instanceFocusHierarchy.emplace_back(currentInstance);
currentInstance = currentInstance->get().GetParentInstance();
}
// Populate internals using the support list
for (auto& instance : instanceFocusList)
// Invert the vector, since we need the top instance to be at index 0
AZStd::reverse(m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end());
}
void PrefabFocusHandler::RefreshInstanceFocusPath()
{
m_instanceFocusPath.clear();
for (const InstanceOptionalReference& instance : m_instanceFocusHierarchy)
{
m_instanceFocusPath.Append(instance->get().GetContainerEntity()->get().GetName());
m_instanceFocusVector.emplace_back(instance);
}
}
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
{
// If this is called outside the Editor, this interface won't be initialized.
if (!m_containerEntityInterface)
{
return;
}
for (const InstanceOptionalReference& instance : instances)
{
if (instance.has_value())
@@ -274,6 +298,12 @@ namespace AzToolsFramework::Prefab
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
{
// If this is called outside the Editor, this interface won't be initialized.
if (!m_containerEntityInterface)
{
return;
}
for (const InstanceOptionalReference& instance : instances)
{
if (instance.has_value())
@@ -11,9 +11,11 @@
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/Prefab/Template/Template.h>
namespace AzToolsFramework
@@ -30,7 +32,9 @@ namespace AzToolsFramework::Prefab
class PrefabFocusHandler final
: private PrefabFocusInterface
, private PrefabFocusPublicInterface
, private PrefabPublicNotificationBus::Handler
, private EditorEntityContextNotificationBus::Handler
, private EditorEntityInfoNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(PrefabFocusHandler, AZ::SystemAllocator, 0);
@@ -38,9 +42,8 @@ namespace AzToolsFramework::Prefab
PrefabFocusHandler();
~PrefabFocusHandler();
void Initialize();
// PrefabFocusInterface overrides ...
void InitializeEditorInterfaces() override;
PrefabFocusOperationResult FocusOnPrefabInstanceOwningEntityId(AZ::EntityId entityId) override;
TemplateId GetFocusedPrefabTemplateId(AzFramework::EntityContextId entityContextId) const override;
InstanceOptionalReference GetFocusedPrefabInstance(AzFramework::EntityContextId entityContextId) const override;
@@ -54,25 +57,34 @@ namespace AzToolsFramework::Prefab
const int GetPrefabFocusPathLength(AzFramework::EntityContextId entityContextId) const override;
// EditorEntityContextNotificationBus overrides ...
void OnEntityStreamLoadSuccess() override;
void OnContextReset() override;
// EditorEntityInfoNotificationBus overrides ...
void OnEntityInfoUpdatedName(AZ::EntityId entityId, const AZStd::string& name) override;
// PrefabPublicNotifications overrides ...
void OnPrefabInstancePropagationEnd();
private:
PrefabFocusOperationResult FocusOnPrefabInstance(InstanceOptionalReference focusedInstance);
void RefreshInstanceFocusList();
void RefreshInstanceFocusPath();
void OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
void CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
//! The instance the editor is currently focusing on.
InstanceOptionalReference m_focusedInstance;
//! The templateId of the focused instance.
TemplateId m_focusedTemplateId;
AZStd::vector<InstanceOptionalReference> m_instanceFocusVector;
//! The list of instances going from the root (index 0) to the focused instance.
AZStd::vector<InstanceOptionalReference> m_instanceFocusHierarchy;
//! A path containing the names of the containers in the instance focus hierarchy, separated with a /.
AZ::IO::Path m_instanceFocusPath;
ContainerEntityInterface* m_containerEntityInterface = nullptr;
FocusModeInterface* m_focusModeInterface = nullptr;
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
bool m_isInitialized = false;
};
} // namespace AzToolsFramework::Prefab
@@ -26,6 +26,11 @@ namespace AzToolsFramework::Prefab
public:
AZ_RTTI(PrefabFocusInterface, "{F3CFA37B-5FD8-436A-9C30-60EB54E350E1}");
//! Initializes the editor interfaces for Prefab Focus mode.
//! If this is not called on initialization, the Prefab Focus Mode functions will still work
//! but won't trigger the Editor APIs to visualize focus mode on the UI.
virtual void InitializeEditorInterfaces() = 0;
//! Set the focused prefab instance to the owning instance of the entityId provided.
//! @param entityId The entityId of the entity whose owning instance we want the prefab system to focus on.
virtual PrefabFocusOperationResult FocusOnPrefabInstanceOwningEntityId(AZ::EntityId entityId) = 0;
@@ -66,7 +66,16 @@ namespace AzToolsFramework
bool Template::IsValid() const
{
return !m_prefabDom.IsNull() && !m_filePath.empty();
if (m_prefabDom.IsNull() || m_filePath.empty())
{
return false;
}
else if (!m_prefabDom.IsObject())
{
return false;
}
auto source = m_prefabDom.FindMember(PrefabDomUtils::SourceName);
return (source != m_prefabDom.MemberEnd());
}
bool Template::IsLoadedWithErrors() const
@@ -175,6 +184,26 @@ namespace AzToolsFramework
return findInstancesResult->get();
}
bool Template::IsProcedural() const
{
if (m_isProcedural.has_value())
{
return m_isProcedural.value();
}
else if (!IsValid())
{
return false;
}
auto source = m_prefabDom.FindMember(PrefabDomUtils::SourceName);
if (!source->value.IsString())
{
return false;
}
AZ::IO::PathView path(source->value.GetString());
m_isProcedural = AZStd::make_optional(path.Extension().Match(".procprefab"));
return m_isProcedural.value();
}
const AZ::IO::Path& Template::GetFilePath() const
{
return m_filePath;
@@ -65,6 +65,9 @@ namespace AzToolsFramework
const AZ::IO::Path& GetFilePath() const;
void SetFilePath(const AZ::IO::PathView& path);
// To tell if this Template was created from an product asset
bool IsProcedural() const;
private:
// Container for keeping links representing the Template's nested instances.
Links m_links;
@@ -80,6 +83,9 @@ namespace AzToolsFramework
// Flag to tell if this Template has changes that have yet to be saved to file.
bool m_isDirty = false;
// Flag to tell if this Template was generated outside the Editor
mutable AZStd::optional<bool> m_isProcedural;
};
} // namespace Prefab
} // namespace AzToolsFramework
@@ -20,6 +20,8 @@
#include <AzFramework/Process/ProcessWatcher.h>
#include <AzToolsFramework/SourceControl/PerforceConnection.h>
#include <QProcess>
namespace AzToolsFramework
{
namespace
@@ -75,9 +77,17 @@ namespace AzToolsFramework
m_resolveKey = true;
m_testTrust = false;
// set up signals before we start thread.
m_shutdownThreadSignal = false;
m_WorkerThread = AZStd::thread(AZStd::bind(&PerforceComponent::ThreadWorker, this));
// Check to see if the 'p4' command is available at the command line
int p4VersionExitCode = QProcess::execute("p4", QStringList{ "-V" });
m_p4ApplicationDetected = (p4VersionExitCode == 0);
if (m_p4ApplicationDetected)
{
m_WorkerThread = AZStd::thread(AZStd::bind(&PerforceComponent::ThreadWorker, this));
}
SourceControlConnectionRequestBus::Handler::BusConnect();
SourceControlCommandBus::Handler::BusConnect();
@@ -88,10 +98,13 @@ namespace AzToolsFramework
SourceControlCommandBus::Handler::BusDisconnect();
SourceControlConnectionRequestBus::Handler::BusDisconnect();
m_shutdownThreadSignal = true; // tell the thread to die.
m_WorkerSemaphore.release(1); // wake up the thread so that it sees the signal
m_WorkerThread.join(); // wait for the thread to finish.
m_WorkerThread = AZStd::thread();
if (m_p4ApplicationDetected)
{
m_shutdownThreadSignal = true; // tell the thread to die.
m_WorkerSemaphore.release(1); // wake up the thread so that it sees the signal
m_WorkerThread.join(); // wait for the thread to finish.
m_WorkerThread = AZStd::thread();
}
SetConnection(nullptr);
}
@@ -260,5 +260,7 @@ namespace AzToolsFramework
AZStd::atomic_bool m_validConnection;
SourceControlState m_connectionState;
bool m_p4ApplicationDetected { false };
};
} // namespace AzToolsFramework
@@ -0,0 +1,91 @@
/*
* 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
#if !defined(Q_MOC_RUN)
#include <AzCore/EBus/EBus.h>
#include <AzCore/Component/EntityId.h>
#include <AzQtComponents/Components/ToastNotificationConfiguration.h>
#include <QPoint>
#endif
namespace AzToolsFramework
{
typedef AZ::EntityId ToastId;
/**
* An EBus for receiving notifications when a user interacts with or dismisses
* a toast notification.
*/
class ToastNotifications
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = ToastId;
virtual void OnToastInteraction() {}
virtual void OnToastDismissed() {}
};
using ToastNotificationBus = AZ::EBus<ToastNotifications>;
typedef AZ::u32 ToastRequestBusId;
/**
* An EBus used to hide or show toast notifications. Generally, these request are handled by a
* ToastNotificationsView that has been created with a specific ToastRequestBusId
* e.g. AZ_CRC("ExampleToastNotificationView")
*/
class ToastRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = ToastRequestBusId; // bus is addressed by CRC of the view name
/**
* Hide a toast notification widget.
*
* @param toastId The toast notification's ToastId
*/
virtual void HideToastNotification(const ToastId& toastId) = 0;
/**
* Show a toast notification with the specified toast configuration. When handled by a ToastNotificationsView,
* notifications are queued and presented to the user in sequence.
*
* @param toastConfiguration The toast configuration
* @return a ToastId
*/
virtual ToastId ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) = 0;
/**
* Show a toast notification with the specified toast configuration at the current moust cursor location.
*
* @param toastConfiguration The toast configuration
* @return a ToastId
*/
virtual ToastId ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) = 0;
/**
* Show a toast notification with the specified toast configuration at the specified location.
*
* @param screenPosition The screen position
* @param anchorPoint The anchorPoint for the toast notification widget
* @param toastConfiguration The toast configuration
* @return a ToastId
*/
virtual ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration&) = 0;
};
using ToastRequestBus = AZ::EBus<ToastRequests>;
}
@@ -0,0 +1,180 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzToolsFramework/UI/Notifications/ToastNotificationsView.h>
#include <AzQtComponents/Components/ToastNotification.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/functional.h>
namespace AzToolsFramework
{
ToastNotificationsView::ToastNotificationsView(QWidget* parent, ToastRequestBusId busId)
: QWidget(parent)
{
ToastRequestBus::Handler::BusConnect(busId);
}
ToastNotificationsView::~ToastNotificationsView()
{
ToastRequestBus::Handler::BusDisconnect();
}
void ToastNotificationsView::OnHide()
{
QWidget::hide();
if (m_activeNotification.IsValid())
{
auto notificationIter = m_notifications.find(m_activeNotification);
if (notificationIter != m_notifications.end())
{
notificationIter->second->hide();
}
}
}
void ToastNotificationsView::UpdateToastPosition()
{
if (m_activeNotification.IsValid())
{
auto notificationIter = m_notifications.find(m_activeNotification);
if (notificationIter != m_notifications.end())
{
notificationIter->second->UpdatePosition(GetGlobalPoint(), m_anchorPoint);
}
}
}
void ToastNotificationsView::OnShow()
{
QWidget::show();
if (m_activeNotification.IsValid() || !m_queuedNotifications.empty())
{
DisplayQueuedNotification();
}
}
ToastId ToastNotificationsView::ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration)
{
ToastId toastId = CreateToastNotification(toastConfiguration);
m_queuedNotifications.emplace_back(toastId);
if (!m_activeNotification.IsValid())
{
DisplayQueuedNotification();
}
return toastId;
}
ToastId ToastNotificationsView::ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration)
{
ToastId toastId = CreateToastNotification(toastConfiguration);
m_notifications[toastId]->ShowToastAtCursor();
return toastId;
}
ToastId ToastNotificationsView::ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration& toastConfiguration)
{
ToastId toastId = CreateToastNotification(toastConfiguration);
m_notifications[toastId]->ShowToastAtPoint(screenPosition, anchorPoint);
return toastId;
}
void ToastNotificationsView::HideToastNotification(const ToastId& toastId)
{
auto notificationIter = m_notifications.find(toastId);
if (notificationIter != m_notifications.end())
{
auto queuedIter = AZStd::find(m_queuedNotifications.begin(), m_queuedNotifications.end(), toastId);
if (queuedIter != m_queuedNotifications.end())
{
m_queuedNotifications.erase(queuedIter);
}
notificationIter->second->reject();
}
}
ToastId ToastNotificationsView::CreateToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration)
{
AzQtComponents::ToastNotification* notification = aznew AzQtComponents::ToastNotification(parentWidget(), toastConfiguration);
ToastId toastId = AZ::Entity::MakeId();
m_notifications[toastId] = notification;
QObject::connect(
m_notifications[toastId], &AzQtComponents::ToastNotification::ToastNotificationHidden,
[toastId]()
{
ToastNotificationBus::Event(toastId, &ToastNotificationBus::Events::OnToastDismissed);
});
QObject::connect(
m_notifications[toastId], &AzQtComponents::ToastNotification::ToastNotificationInteraction,
[toastId]()
{
ToastNotificationBus::Event(toastId, &ToastNotificationBus::Events::OnToastInteraction);
});
return toastId;
}
QPoint ToastNotificationsView::GetGlobalPoint()
{
QPoint relativePoint = m_offset;
AZ_Assert(parentWidget(), "ToastNotificationsView has invalid parent QWidget");
if (m_anchorPoint.x() == 1.0)
{
relativePoint.setX(parentWidget()->width() - m_offset.x());
}
if (m_anchorPoint.y() == 1.0)
{
relativePoint.setY(parentWidget()->height() - m_offset.y());
}
return parentWidget()->mapToGlobal(relativePoint);
}
void ToastNotificationsView::DisplayQueuedNotification()
{
AZ_Assert(parentWidget(), "ToastNotificationsView has invalid parent QWidget");
if (m_queuedNotifications.empty() || !parentWidget()->isVisible() || !isVisible())
{
return;
}
ToastId toastId = m_queuedNotifications.front();
m_queuedNotifications.erase(m_queuedNotifications.begin());
auto notificationIter = m_notifications.find(toastId);
if (notificationIter != m_notifications.end())
{
m_activeNotification = toastId;
notificationIter->second->ShowToastAtPoint(GetGlobalPoint(), m_anchorPoint);
QObject::connect(
notificationIter->second, &AzQtComponents::ToastNotification::ToastNotificationHidden,
[&]()
{
m_activeNotification.SetInvalid();
DisplayQueuedNotification();
}
);
}
// If we didn't actually show something, recurse to avoid things getting stuck in the queue.
if (!m_activeNotification.IsValid())
{
DisplayQueuedNotification();
}
}
}
@@ -0,0 +1,65 @@
/*
* 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
#if !defined(Q_MOC_RUN)
#include <QWidget>
#include <QPoint>
#include <QPointF>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzToolsFramework/UI/Notifications/ToastBus.h>
#endif
namespace AzQtComponents
{
class ToastNotification;
}
namespace AzToolsFramework
{
/**
* \brief A QWidget that displays and manages a queue of toast notifications.
*
* This view must be updated by its parent when the parent widget is show, hidden, moved
* or resized because toast notifications are displayed on top of the parent and are not part
* of the layout, so they must be manually moved.
*/
class ToastNotificationsView final
: public QWidget
, protected ToastRequestBus::Handler
{
Q_OBJECT
public:
ToastNotificationsView(QWidget* parent, ToastRequestBusId busId);
~ToastNotificationsView() override;
void HideToastNotification(const ToastId& toastId) override;
ToastId ShowToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration) override;
ToastId ShowToastAtCursor(const AzQtComponents::ToastConfiguration& toastConfiguration) override;
ToastId ShowToastAtPoint(const QPoint& screenPosition, const QPointF& anchorPoint, const AzQtComponents::ToastConfiguration&) override;
void OnHide();
void OnShow();
void UpdateToastPosition();
private:
ToastId CreateToastNotification(const AzQtComponents::ToastConfiguration& toastConfiguration);
void DisplayQueuedNotification();
QPoint GetGlobalPoint();
ToastId m_activeNotification;
AZStd::unordered_map<ToastId, AzQtComponents::ToastNotification*> m_notifications;
AZStd::vector<ToastId> m_queuedNotifications;
QPoint m_offset = QPoint(10, 10);
QPointF m_anchorPoint = QPointF(1, 0);
};
} // AzToolsFramework
@@ -27,6 +27,7 @@
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
#include <AzToolsFramework/Prefab/Procedural/ProceduralPrefabAsset.h>
@@ -135,6 +136,10 @@ namespace AzToolsFramework
return;
}
// Initialize Editor functionality for the Prefab Focus Handler
auto prefabFocusInterface = AZ::Interface<PrefabFocusInterface>::Get();
prefabFocusInterface->InitializeEditorInterfaces();
EditorContextMenuBus::Handler::BusConnect();
EditorEventsBus::Handler::BusConnect();
PrefabInstanceContainerNotificationBus::Handler::BusConnect();
@@ -250,7 +255,7 @@ namespace AzToolsFramework
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntity))
{
// Edit Prefab
if (prefabWipFeaturesEnabled && !s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
if (!s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
{
QAction* editAction = menu->addAction(QObject::tr("Edit Prefab"));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
@@ -1154,25 +1159,14 @@ namespace AzToolsFramework
{
s_editorEntityUiInterface->RegisterEntity(entityId, m_prefabUiHandler.GetHandlerId());
bool prefabWipFeaturesEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
if (prefabWipFeaturesEnabled)
{
// Register entity as a container
s_containerEntityInterface->RegisterEntityAsContainer(entityId);
}
// Register entity as a container
s_containerEntityInterface->RegisterEntityAsContainer(entityId);
}
}
void PrefabIntegrationManager::OnPrefabComponentDeactivate(AZ::EntityId entityId)
{
bool prefabWipFeaturesEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
if (prefabWipFeaturesEnabled && !s_prefabPublicInterface->IsLevelInstanceContainerEntity(entityId))
if (!s_prefabPublicInterface->IsLevelInstanceContainerEntity(entityId))
{
// Unregister entity as a container
s_containerEntityInterface->UnregisterEntityAsContainer(entityId);
@@ -316,14 +316,7 @@ namespace AzToolsFramework
void PrefabUiHandler::OnDoubleClick(AZ::EntityId entityId) const
{
bool prefabWipFeaturesEnabled = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
if (prefabWipFeaturesEnabled)
{
// Focus on this prefab
m_prefabFocusPublicInterface->FocusOnOwningPrefab(entityId);
}
// Focus on this prefab
m_prefabFocusPublicInterface->FocusOnOwningPrefab(entityId);
}
}
@@ -198,6 +198,8 @@ namespace AzToolsFramework
virtual float ManipulatorCircleBoundWidth() const = 0;
//! Returns if sticky select is enabled or not.
virtual bool StickySelectEnabled() const = 0;
//! Returns the default viewport camera position.
virtual AZ::Vector3 DefaultEditorCameraPosition() const = 0;
protected:
~ViewportSettingsRequests() = default;
@@ -300,6 +302,12 @@ namespace AzToolsFramework
using EditorViewportInputTimeNowRequestBus = AZ::EBus<EditorViewportInputTimeNowRequests>;
//! The style of cursor override.
enum class CursorStyleOverride
{
Forbidden
};
//! Viewport requests for managing the viewport cursor state.
class ViewportMouseCursorRequests
{
@@ -310,6 +318,10 @@ namespace AzToolsFramework
virtual void EndCursorCapture() = 0;
//! Is the mouse over the viewport.
virtual bool IsMouseOver() const = 0;
//! Set the cursor style override.
virtual void SetOverrideCursor(CursorStyleOverride cursorStyleOverride) = 0;
//! Clear the cursor style override.
virtual void ClearOverrideCursor() = 0;
protected:
~ViewportMouseCursorRequests() = default;
@@ -44,6 +44,13 @@ AZ_CVAR(
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Display the aggregate world bounds for a given entity (the union of all world component Aabbs)");
AZ_CVAR(
bool,
ed_useCursorLockIconInFocusMode,
false,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Use a lock icon when the cursor is over entities that cannot be interacted with");
namespace AzToolsFramework
{
@@ -222,6 +229,13 @@ namespace AzToolsFramework
// verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
if (entityIdUnderCursor.IsValid() && !IsSelectableAccordingToFocusMode(entityIdUnderCursor))
{
if (ed_useCursorLockIconInFocusMode)
{
ViewportInteraction::ViewportMouseCursorRequestBus::Event(
viewportId, &ViewportInteraction::ViewportMouseCursorRequestBus::Events::SetOverrideCursor,
ViewportInteraction::CursorStyleOverride::Forbidden);
}
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() &&
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down ||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick)
@@ -232,6 +246,9 @@ namespace AzToolsFramework
return CursorEntityIdQuery(AZ::EntityId(), AZ::EntityId());
}
ViewportInteraction::ViewportMouseCursorRequestBus::Event(
viewportId, &ViewportInteraction::ViewportMouseCursorRequestBus::Events::ClearOverrideCursor);
// container entity support - if the entity that is being selected is part of a closed container,
// change the selection to the container instead.
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
@@ -759,6 +759,9 @@ set(FILES
UI/Prefab/PrefabUiHandler.cpp
UI/Prefab/PrefabViewportFocusPathHandler.h
UI/Prefab/PrefabViewportFocusPathHandler.cpp
UI/Notifications/ToastNotificationsView.cpp
UI/Notifications/ToastNotificationsView.h
UI/Notifications/ToastBus.h
PythonTerminal/ScriptHelpDialog.cpp
PythonTerminal/ScriptHelpDialog.h
PythonTerminal/ScriptHelpDialog.ui
@@ -14,6 +14,7 @@
#include <Prefab/PrefabTestFixture.h>
#include <Prefab/Procedural/ProceduralPrefabAsset.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzToolsFramework/Prefab/Template/Template.h>
namespace UnitTest
{
@@ -132,4 +133,32 @@ namespace UnitTest
EXPECT_TRUE(outputValue.HasMember("member"));
EXPECT_STREQ(outputValue.FindMember("member")->value.GetString(), "value");
}
TEST_F(ProceduralPrefabAssetTest, Template_IsProcPrefab_DefaultsToNotProcPrefab)
{
AzToolsFramework::Prefab::PrefabDom dom;
dom.SetObject();
dom.AddMember("Source", "foo.prefab", dom.GetAllocator());
AzToolsFramework::Prefab::Template fooTemplate("foo", AZStd::move(dom));
EXPECT_FALSE(fooTemplate.IsProcedural());
}
TEST_F(ProceduralPrefabAssetTest, Template_IsProcPrefab_DomDrivesFlagToTrue)
{
AzToolsFramework::Prefab::PrefabDom dom;
dom.SetObject();
dom.AddMember("Source", "foo.procprefab", dom.GetAllocator());
AzToolsFramework::Prefab::Template fooTemplate("foo", AZStd::move(dom));
EXPECT_TRUE(fooTemplate.IsProcedural());
// the second time should use the cached version of the flag
EXPECT_TRUE(fooTemplate.IsProcedural());
}
TEST_F(ProceduralPrefabAssetTest, Template_IsProcPrefab_FailsWithNoSource)
{
AzToolsFramework::Prefab::PrefabDom dom;
dom.SetObject();
AzToolsFramework::Prefab::Template fooTemplate("foo", AZStd::move(dom));
EXPECT_FALSE(fooTemplate.IsProcedural());
}
}
@@ -90,8 +90,7 @@ namespace UnitTest
// Update our undo cache entry to include the rename / reparent as one atomic operation.
m_prefabPublicInterface->GenerateUndoNodesForEntityChangeAndUpdateCache(entityId, m_undoStack->GetTop());
// Force a prefab propagation as updates are deferred to the next tick.
m_prefabSystemComponent->OnSystemTick();
ProcessDeferredUpdates();
return entityId;
}
@@ -125,6 +124,30 @@ namespace UnitTest
return m_model->index(0, 0);
}
// Kicks off any updates scheduled for the next tick
void ProcessDeferredUpdates()
{
// Force a prefab propagation for updates that are deferred to the next tick.
m_prefabSystemComponent->OnSystemTick();
// Ensure the model process its entity update queue
m_model->ProcessEntityUpdates();
}
// Performs an undo operation and ensures the tick-scheduled updates happen
void Undo()
{
m_undoStack->Undo();
ProcessDeferredUpdates();
}
// Performs a redo operation and ensures the tick-scheduled updates happen
void Redo()
{
m_undoStack->Redo();
ProcessDeferredUpdates();
}
AZStd::unique_ptr<AzToolsFramework::EntityOutlinerListModel> m_model;
AZStd::unique_ptr<QAbstractItemModelTester> m_modelTester;
AzToolsFramework::UndoSystem::UndoStack* m_undoStack = nullptr;
@@ -139,21 +162,18 @@ namespace UnitTest
CreateNamedEntity(AZStd::string::format("Entity%zu", i));
EXPECT_EQ(m_model->rowCount(GetRootIndex()), i + 1);
}
m_model->ProcessEntityUpdates();
for (int i = entityCount; i > 0; --i)
{
m_undoStack->Undo();
Undo();
EXPECT_EQ(m_model->rowCount(GetRootIndex()), i - 1);
}
m_model->ProcessEntityUpdates();
for (size_t i = 0; i < entityCount; ++i)
{
m_undoStack->Redo();
Redo();
EXPECT_EQ(m_model->rowCount(GetRootIndex()), i + 1);
}
m_model->ProcessEntityUpdates();
}
TEST_F(EntityOutlinerTest, TestCreateNestedHierarchyUndoAndRedoWorks)
@@ -177,21 +197,18 @@ namespace UnitTest
{
parentId = CreateNamedEntity(AZStd::string::format("EntityDepth%i", i), parentId);
EXPECT_EQ(modelDepth(), i + 1);
m_model->ProcessEntityUpdates();
}
for (int i = depth - 1; i >= 0; --i)
{
m_undoStack->Undo();
Undo();
EXPECT_EQ(modelDepth(), i);
m_model->ProcessEntityUpdates();
}
for (int i = 0; i < depth; ++i)
{
m_undoStack->Redo();
Redo();
EXPECT_EQ(modelDepth(), i + 1);
m_model->ProcessEntityUpdates();
}
}
} // namespace UnitTest
@@ -86,7 +86,7 @@ bool CLevelInfo::ReadInfo()
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
// Set up a default game type for legacy code.
m_defaultGameTypeName = "Mission0";
m_defaultGameTypeName = "mission0";
if (usePrefabSystemForLevels)
{
@@ -96,17 +96,17 @@ bool CLevelInfo::ReadInfo()
AZStd::string levelPath(m_levelPath);
AZStd::string xmlFile(levelPath);
xmlFile += "/LevelInfo.xml";
xmlFile += "/levelinfo.xml";
XmlNodeRef rootNode = GetISystem()->LoadXmlFromFile(xmlFile.c_str());
if (rootNode)
{
AZStd::string dataFile(levelPath);
dataFile += "/LevelDataAction.xml";
dataFile += "/leveldataaction.xml";
XmlNodeRef dataNode = GetISystem()->LoadXmlFromFile(dataFile.c_str());
if (!dataNode)
{
dataFile = levelPath + "/LevelData.xml";
dataFile = levelPath + "/leveldata.xml";
dataNode = GetISystem()->LoadXmlFromFile(dataFile.c_str());
}
@@ -614,7 +614,7 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName)
}
{
AZStd::string missionXml("Mission_");
AZStd::string missionXml("mission_");
missionXml += pLevelInfo->m_defaultGameTypeName;
missionXml += ".xml";
AZStd::string xmlFile(pLevelInfo->GetPath());
@@ -3573,19 +3573,61 @@ namespace AssetProcessor
QString knownPathBeforeWildcard = encodedFileData.left(slashBeforeWildcardIndex + 1); // include the slash
QString relativeSearch = encodedFileData.mid(slashBeforeWildcardIndex + 1); // skip the slash
for (int i = 0; i < m_platformConfig->GetScanFolderCount(); ++i)
// Absolute path, just check the 1 scan folder
if (AZ::IO::PathView(encodedFileData.toUtf8().constData()).IsAbsolute())
{
const ScanFolderInfo* scanFolderInfo = &m_platformConfig->GetScanFolderAt(i);
if (!scanFolderInfo->RecurseSubFolders() && encodedFileData.contains("/"))
QString scanFolderName;
if (!m_platformConfig->ConvertToRelativePath(encodedFileData, resultDatabaseSourceName, scanFolderName))
{
continue;
AZ_Warning(
AssetProcessor::ConsoleChannel, false,
"'%s' does not appear to be in any input folder. Use relative paths instead.",
sourceDependency.m_sourceFileDependencyPath.c_str());
}
QDir rooted(scanFolderInfo->ScanPath());
QString absolutePath = rooted.absoluteFilePath(knownPathBeforeWildcard);
auto scanFolderInfo = m_platformConfig->GetScanFolderByPath(scanFolderName);
resolvedDependencyList.append(m_platformConfig->FindWildcardMatches(absolutePath, relativeSearch, false, scanFolderInfo->RecurseSubFolders()));
// Make an absolute path that is ScanFolderPath + Part of search path before the wildcard
QDir rooted(scanFolderName);
QString scanFolderAndKnownSubPath = rooted.absoluteFilePath(knownPathBeforeWildcard);
resolvedDependencyList.append(m_platformConfig->FindWildcardMatches(
scanFolderAndKnownSubPath, relativeSearch, false, scanFolderInfo->RecurseSubFolders()));
}
else // Relative path, check every scan folder
{
for (int i = 0; i < m_platformConfig->GetScanFolderCount(); ++i)
{
const ScanFolderInfo* scanFolderInfo = &m_platformConfig->GetScanFolderAt(i);
if (!scanFolderInfo->RecurseSubFolders() && encodedFileData.contains("/"))
{
continue;
}
QDir rooted(scanFolderInfo->ScanPath());
QString absolutePath = rooted.absoluteFilePath(knownPathBeforeWildcard);
resolvedDependencyList.append(m_platformConfig->FindWildcardMatches(
absolutePath, relativeSearch, false, scanFolderInfo->RecurseSubFolders()));
}
}
// Convert to relative paths
for (auto dependencyItr = resolvedDependencyList.begin(); dependencyItr != resolvedDependencyList.end();)
{
QString relativePath, scanFolder;
if (m_platformConfig->ConvertToRelativePath(*dependencyItr, relativePath, scanFolder))
{
*dependencyItr = relativePath;
++dependencyItr;
}
else
{
AZ_Warning("AssetProcessor", false, "Failed to get relative path for wildcard dependency file %s. Is the file within a scan folder?",
dependencyItr->toUtf8().constData());
dependencyItr = resolvedDependencyList.erase(dependencyItr);
}
}
resultDatabaseSourceName = encodedFileData.replace('\\', '/');
@@ -10,7 +10,9 @@
#include <utilities/BatchApplicationManager.h>
#include <utilities/ApplicationServer.h>
#include <AzFramework/Asset/AssetSystemComponent.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Utils/Utils.h>
#include <connection/connectionManager.h>
#include <QCoreApplication>
#include <QTemporaryDir>
@@ -98,10 +100,26 @@ namespace AssetProcessorMessagesTests
int argC = 0;
m_batchApplicationManager = AZStd::make_unique<UnitTestBatchApplicationManager>(&argC, nullptr, nullptr);
m_batchApplicationManager->BeforeRun();
// Override Game Name to be "AutomatedTesting"
AssetUtilities::ComputeProjectName("AutomatedTesting", true);
auto registry = AZ::SettingsRegistry::Get();
EXPECT_NE(registry, nullptr);
constexpr AZ::SettingsRegistryInterface::FixedValueString bootstrapKey{
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey
};
constexpr AZ::SettingsRegistryInterface::FixedValueString projectPathKey{ bootstrapKey + "/project_path" };
registry->Set(projectPathKey, "AutomatedTesting");
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
// Force the branch token into settings registry before starting the application manager.
// This avoids writing the asset_processor.setreg file which can cause fileIO errors.
const AZ::IO::FixedMaxPathString enginePath = AZ::Utils::GetEnginePath();
constexpr AZ::SettingsRegistryInterface::FixedValueString branchTokenKey{ bootstrapKey + "/assetProcessor_branch_token" };
AZStd::string token;
AZ::StringFunc::AssetPath::CalculateBranchToken(enginePath.c_str(), token);
registry->Set(branchTokenKey, token.c_str());
auto status = m_batchApplicationManager->BeforeRun();
ASSERT_EQ(status, ApplicationManager::BeforeRunStatus::Status_Success);
m_batchApplicationManager->m_platformConfiguration = new PlatformConfiguration();
m_batchApplicationManager->InitAssetProcessorManager();
@@ -159,21 +177,25 @@ namespace AssetProcessorMessagesTests
ASSERT_TRUE(result);
});
}
void TearDown() override
{
QEventLoop eventLoop;
if (m_batchApplicationManager->m_connectionManager)
{
QEventLoop eventLoop;
QObject::connect(m_batchApplicationManager->m_connectionManager, &ConnectionManager::ReadyToQuit, &eventLoop, &QEventLoop::quit);
QObject::connect(m_batchApplicationManager->m_connectionManager, &ConnectionManager::ReadyToQuit, &eventLoop, &QEventLoop::quit);
m_batchApplicationManager->m_connectionManager->QuitRequested();
m_batchApplicationManager->m_connectionManager->QuitRequested();
eventLoop.exec();
eventLoop.exec();
}
m_assetSystemComponent->Deactivate();
if (m_assetSystemComponent)
{
m_assetSystemComponent->Deactivate();
}
m_batchApplicationManager->Destroy();
}
@@ -505,6 +505,14 @@ bool ApplicationManager::StartAZFramework()
AzFramework::Application::Descriptor appDescriptor;
AZ::ComponentApplication::StartupParameters params;
QDir projectPath{ AssetUtilities::ComputeProjectPath() };
if (!projectPath.exists("project.json"))
{
AZStd::string errorMsg = AZStd::string::format("Path '%s' is not a valid project path.", projectPath.path().toUtf8().constData());
AssetProcessor::MessageInfoBus::Broadcast(&AssetProcessor::MessageInfoBus::Events::OnErrorMessage, errorMsg.c_str());
return false;
}
QString projectName = AssetUtilities::ComputeProjectName();
// Prevent loading of gems in the Create method of the ComponentApplication
@@ -520,7 +528,6 @@ bool ApplicationManager::StartAZFramework()
//Registering all the Components
m_frameworkApp.RegisterComponentDescriptor(AzFramework::LogComponent::CreateDescriptor());
Reflect();
const AzFramework::CommandLine* commandLine = nullptr;
@@ -95,6 +95,8 @@ GUIApplicationManager::~GUIApplicationManager()
ApplicationManager::BeforeRunStatus GUIApplicationManager::BeforeRun()
{
AssetProcessor::MessageInfoBus::Handler::BusConnect();
ApplicationManager::BeforeRunStatus status = ApplicationManagerBase::BeforeRun();
if (status != ApplicationManager::BeforeRunStatus::Status_Success)
{
@@ -109,7 +111,6 @@ ApplicationManager::BeforeRunStatus GUIApplicationManager::BeforeRun()
#if defined(EXTERNAL_CRASH_REPORTING)
CrashHandler::ToolsCrashHandler::InitCrashHandler("AssetProcessor", projectAssetRoot.absolutePath().toStdString());
#endif
AssetProcessor::MessageInfoBus::Handler::BusConnect();
// we have to monitor both the cache folder and the database file and restart AP if either of them gets deleted
// It is important to note that we are monitoring the parent folder and not the actual cache folder itself since
@@ -436,98 +437,7 @@ bool GUIApplicationManager::OnError(const char* /*window*/, const char* message)
connection = Qt::QueuedConnection;
}
if (m_isCurrentlyLoadingGems)
{
// if something goes wrong during gem initialization, this is a special case and we need to be extra helpful.
const char* userSettingsFile = "_WAF_/user_settings.options";
const char* defaultSettingsFile = "_WAF_/default_settings.json";
QDir engineRoot;
AssetUtilities::ComputeEngineRoot(engineRoot);
QString settingsPath = engineRoot.absoluteFilePath(userSettingsFile);
QString friendlyErrorMessage;
bool usingDefaults = false;
if (QFile::exists(settingsPath))
{
QSettings loader(settingsPath, QSettings::IniFormat);
QVariant settingValue = loader.value("Game Projects/enabled_game_projects");
QStringList compiledProjects = settingValue.toStringList();
if (compiledProjects.isEmpty())
{
QByteArray byteArray;
QFile jsonFile;
jsonFile.setFileName(engineRoot.absoluteFilePath(defaultSettingsFile));
jsonFile.open(QIODevice::ReadOnly | QIODevice::Text);
byteArray = jsonFile.readAll();
jsonFile.close();
QJsonObject settingsObject = QJsonDocument::fromJson(byteArray).object();
QJsonArray projectsArray = settingsObject["Game Projects"].toArray();
if (!projectsArray.isEmpty())
{
auto projectObject = projectsArray[0].toObject();
QString projects = projectObject["default_value"].toString();
if (!projects.isEmpty())
{
compiledProjects = projects.split(',');
usingDefaults = true;
}
}
}
for (int i = 0; i < compiledProjects.size(); ++i)
{
compiledProjects[i] = compiledProjects[i].trimmed();
}
QString enabledProject = AssetUtilities::ComputeProjectName();
if (!compiledProjects.contains(enabledProject))
{
QString projectSourceLine;
if (usingDefaults)
{
projectSourceLine = QString("The currently compiled projects according to the defaults in %1 are '%2'").arg(defaultSettingsFile);
}
else
{
projectSourceLine = QString("The currently compiled projects according to %1 are '%2'").arg(userSettingsFile);
}
projectSourceLine = projectSourceLine.arg(compiledProjects.join(", "));
friendlyErrorMessage = QString("An error occurred while loading gems.\n"
"The enabled game project is not in the list of compiled projects.\n"
"Please configure the enabled project to be compiled and rebuild or change the enabled project.\n"
"The currently enabled game project (from bootstrap.cfg or /%4 command-line parameter) is '%1'.\n"
"%2\n"
"Full error text:\n"
"%3"
).arg(enabledProject).arg(projectSourceLine).arg(message).arg(AssetUtilities::ProjectPathOverrideParameter);
}
}
if (friendlyErrorMessage.isEmpty())
{
friendlyErrorMessage = QString("An error occurred while loading gems.\n"
"This can happen when new gems are added to a project, but those gems need to be built in order to function.\n"
"This can also happen when switching to a different project, one which uses gems which are not yet built.\n"
"To continue, please build the current project before attempting to run Asset Processor again.\n\n"
"Full error text:\n"
"%1").arg(message);
}
QMetaObject::invokeMethod(this, "ShowMessageBox", connection, Q_ARG(QString, QString("Error")), Q_ARG(QString, friendlyErrorMessage), Q_ARG(bool, true));
}
else
{
QMetaObject::invokeMethod(this, "ShowMessageBox", connection, Q_ARG(QString, QString("Error")), Q_ARG(QString, QString(message)), Q_ARG(bool, true));
}
QMetaObject::invokeMethod(this, "ShowMessageBox", connection, Q_ARG(QString, QString("Error")), Q_ARG(QString, QString(message)), Q_ARG(bool, true));
return true;
}
@@ -1435,32 +1435,35 @@ namespace AssetProcessor
return QString();
}
QStringList PlatformConfiguration::FindWildcardMatches(const QString& sourceFolder, QString relativeName, bool includeFolders, bool recursiveSearch) const
QStringList PlatformConfiguration::FindWildcardMatches(
const QString& sourceFolder, QString relativeName, bool includeFolders, bool recursiveSearch) const
{
if (relativeName.isEmpty())
{
return QStringList();
}
const int pathLen = sourceFolder.length() + 1;
QDir sourceFolderDir(sourceFolder);
relativeName.replace('\\', '/');
QString posixRelativeName = QDir::fromNativeSeparators(relativeName);
QStringList returnList;
QRegExp nameMatch{ relativeName, Qt::CaseInsensitive, QRegExp::Wildcard };
QDirIterator diretoryIterator(sourceFolder, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, recursiveSearch ? QDirIterator::Subdirectories : QDirIterator::NoIteratorFlags);
QRegExp nameMatch{ posixRelativeName, Qt::CaseInsensitive, QRegExp::Wildcard };
QDirIterator dirIterator(
sourceFolderDir.path(), QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot,
recursiveSearch ? QDirIterator::Subdirectories : QDirIterator::NoIteratorFlags);
QStringList files;
while (diretoryIterator.hasNext())
while (dirIterator.hasNext())
{
diretoryIterator.next();
if (!includeFolders && !diretoryIterator.fileInfo().isFile())
dirIterator.next();
if (!includeFolders && !dirIterator.fileInfo().isFile())
{
continue;
}
QString pathMatch{ diretoryIterator.filePath().mid(pathLen) };
QString pathMatch{ sourceFolderDir.relativeFilePath(dirIterator.filePath()) };
if (nameMatch.exactMatch(pathMatch))
{
returnList.append(AssetUtilities::NormalizeFilePath(diretoryIterator.filePath()));
returnList.append(QDir::fromNativeSeparators(dirIterator.filePath()));
}
}
return returnList;
@@ -51,4 +51,21 @@ namespace AWSCore
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-metrics/advanced-topics/";
static constexpr const char AWSMetricsSettingsUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-metrics/";
static constexpr const char AWSGameLiftGemOverviewUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/";
static constexpr const char AWSGameLiftGemSetupUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/gem-setup/";
static constexpr const char AWSGameLiftScriptingUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/scripting/";
static constexpr const char AWSGameLiftAPIReferenceUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/cpp-api/";
static constexpr const char AWSGameLiftAdvancedTopicsUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/advanced-topics/";
static constexpr const char AWSGameLiftLocalTestingUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/local-testing/";
static constexpr const char AWSGameLiftBuildPackagingUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/build-packaging-for-windows/";
static constexpr const char AWSGameLiftResourceManagementUrl[] =
"https://o3de.org/docs/user-guide/gems/reference/aws/aws-gamelift/resource-management/";
} // namespace AWSCore
@@ -38,4 +38,14 @@ namespace AWSCore
static constexpr const char AWSMetricsAPIReferenceActionText[] = "API reference";
static constexpr const char AWSMetricsAdvancedTopicsActionText[] = "Advanced topics";
static constexpr const char AWSMetricsSettingsActionText[] = "Metrics settings";
static constexpr const char AWSGameLiftActionText[] = "GameLift Gem";
static constexpr const char AWSGameLiftGemOverviewActionText[] = "Gem overview";
static constexpr const char AWSGameLiftGemSetupActionText[] = "Setup";
static constexpr const char AWSMGameLiftScriptingActionText[] = "Scripting reference";
static constexpr const char AWSGameLiftAPIReferenceActionText[] = "API reference";
static constexpr const char AWSGameLiftAdvancedTopicsActionText[] = "Advanced topics";
static constexpr const char AWSGameLiftLocalTestingActionText[] = "Local testing";
static constexpr const char AWSGameLiftBuildPackagingActionText[] = "Build packaging (Windows)";
static constexpr const char AWSGameLiftResourceManagementActionText[] = "Resource Management";
} // namespace AWSCore
@@ -48,6 +48,7 @@ namespace AWSCore
// AWSCoreEditorRequestBus interface implementation
void SetAWSClientAuthEnabled() override;
void SetAWSMetricsEnabled() override;
void SetAWSGameLiftEnabled() override;
QMenu* SetAWSFeatureSubMenu(const AZStd::string& menuText);
@@ -53,6 +53,7 @@ namespace AWSCore
public:
virtual void SetAWSClientAuthEnabled() = 0;
virtual void SetAWSMetricsEnabled() = 0;
virtual void SetAWSGameLiftEnabled() = 0;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
@@ -156,6 +156,11 @@ namespace AWSCore
metrics->setIcon(QIcon(QString(":/Notifications/download.svg")));
metrics->setDisabled(true);
this->addAction(metrics);
QAction* gamelift = new QAction(QObject::tr(AWSGameLiftActionText));
gamelift->setIcon(QIcon(QString(":/Notifications/download.svg")));
gamelift->setDisabled(true);
this->addAction(gamelift);
}
void AWSCoreEditorMenu::SetAWSClientAuthEnabled()
@@ -181,6 +186,23 @@ namespace AWSCore
AddSpaceForIcon(subMenu);
}
void AWSCoreEditorMenu::SetAWSGameLiftEnabled()
{
// TODO: instead of creating submenu in core editor, aws feature gem should return submenu component directly
QMenu* subMenu = SetAWSFeatureSubMenu(AWSGameLiftActionText);
subMenu->addAction(AddExternalLinkAction(AWSGameLiftGemOverviewActionText, AWSGameLiftGemOverviewUrl, ":/Notifications/link.svg"));
subMenu->addAction(AddExternalLinkAction(AWSGameLiftGemSetupActionText, AWSGameLiftGemSetupUrl, ":/Notifications/link.svg"));
subMenu->addAction(AddExternalLinkAction(AWSMGameLiftScriptingActionText, AWSGameLiftScriptingUrl, ":/Notifications/link.svg"));
subMenu->addAction(AddExternalLinkAction(AWSGameLiftAPIReferenceActionText, AWSGameLiftAPIReferenceUrl, ":/Notifications/link.svg"));
subMenu->addAction(AddExternalLinkAction(AWSGameLiftAdvancedTopicsActionText, AWSGameLiftAdvancedTopicsUrl, ":/Notifications/link.svg"));
subMenu->addAction(AddExternalLinkAction(AWSGameLiftLocalTestingActionText, AWSGameLiftLocalTestingUrl, ":/Notifications/link.svg"));
subMenu->addAction(AddExternalLinkAction(AWSGameLiftBuildPackagingActionText, AWSGameLiftBuildPackagingUrl, ":/Notifications/link.svg"));
subMenu->addAction(AddExternalLinkAction(AWSGameLiftResourceManagementActionText, AWSGameLiftResourceManagementUrl, ":/Notifications/link.svg"));
AddSpaceForIcon(subMenu);
}
void AWSCoreEditorMenu::SetAWSMetricsEnabled()
{
// TODO: instead of creating submenu in core editor, aws feature gem should return submenu component directly
@@ -21,8 +21,8 @@
using namespace AWSCore;
static constexpr const int ExpectedActionNumOnWindowsPlatform = 8;
static constexpr const int ExpectedActionNumOnOtherPlatform = 6;
static constexpr const int ExpectedActionNumOnWindowsPlatform = 9;
static constexpr const int ExpectedActionNumOnOtherPlatform = 7;
class AWSCoreEditorMenuTest
: public AWSCoreFixture
@@ -60,6 +60,7 @@ TEST_F(AWSCoreEditorMenuTest, AWSCoreEditorMenu_BroadcastFeatureGemsAreEnabled_C
AWSCoreEditorRequestBus::Broadcast(&AWSCoreEditorRequests::SetAWSClientAuthEnabled);
AWSCoreEditorRequestBus::Broadcast(&AWSCoreEditorRequests::SetAWSMetricsEnabled);
AWSCoreEditorRequestBus::Broadcast(&AWSCoreEditorRequests::SetAWSGameLiftEnabled);
QList<QAction*> actualActions = testMenu.actions();
for (QList<QAction*>::iterator itr = actualActions.begin(); itr != actualActions.end(); itr++)
@@ -73,5 +74,10 @@ TEST_F(AWSCoreEditorMenuTest, AWSCoreEditorMenu_BroadcastFeatureGemsAreEnabled_C
{
EXPECT_TRUE((*itr)->isEnabled());
}
if (QString::compare((*itr)->text(), AWSGameLiftActionText) == 0)
{
EXPECT_TRUE((*itr)->isEnabled());
}
}
}
@@ -5,75 +5,16 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/string/string.h>
#include <AzFramework/Matchmaking/IMatchmakingRequests.h>
#include <AzFramework/Session/ISessionRequests.h>
namespace AWSGameLift
{
//! IAWSGameLiftRequests
//! GameLift Gem interfaces to configure client manager
class IAWSGameLiftRequests
{
public:
AZ_RTTI(IAWSGameLiftRequests, "{494167AD-1185-4AF3-8BF9-C8C37FC9C199}");
IAWSGameLiftRequests() = default;
virtual ~IAWSGameLiftRequests() = default;
//! ConfigureGameLiftClient
//! Configure GameLift client to interact with Amazon GameLift service
//! @param region Specifies the AWS region to use
//! @return True if client configuration succeeds, false otherwise
virtual bool ConfigureGameLiftClient(const AZStd::string& region) = 0;
//! CreatePlayerId
//! Create a new, random ID number for every player in every new game session.
//! @param includeBrackets Whether includes brackets in player id
//! @param includeDashes Whether includes dashes in player id
//! @return The player id to use in game session
virtual AZStd::string CreatePlayerId(bool includeBrackets, bool includeDashes) = 0;
};
// IAWSGameLiftRequests EBus wrapper for scripting
class AWSGameLiftRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using AWSGameLiftRequestBus = AZ::EBus<IAWSGameLiftRequests, AWSGameLiftRequests>;
// ISessionAsyncRequests EBus wrapper for scripting
class AWSGameLiftSessionAsyncRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using AWSGameLiftSessionAsyncRequestBus = AZ::EBus<AzFramework::ISessionAsyncRequests, AWSGameLiftSessionAsyncRequests>;
// ISessionRequests EBus wrapper for scripting
class AWSGameLiftSessionRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using AWSGameLiftSessionRequestBus = AZ::EBus<AzFramework::ISessionRequests, AWSGameLiftSessionRequests>;
// IMatchmakingAsyncRequests EBus wrapper for scripting
// IMatchmakingAsyncRequests EBus wrapper
class AWSGameLiftMatchmakingAsyncRequests
: public AZ::EBusTraits
{
@@ -84,7 +25,7 @@ namespace AWSGameLift
};
using AWSGameLiftMatchmakingAsyncRequestBus = AZ::EBus<AzFramework::IMatchmakingAsyncRequests, AWSGameLiftMatchmakingAsyncRequests>;
// IMatchmakingRequests EBus wrapper for scripting
// IMatchmakingRequests EBus wrapper
class AWSGameLiftMatchmakingRequests
: public AZ::EBusTraits
{
@@ -121,7 +62,7 @@ namespace AWSGameLift
virtual void StopPolling() = 0;
};
// IAWSGameLiftMatchmakingEventRequests EBus wrapper for scripting
// IAWSGameLiftMatchmakingEventRequests EBus wrapper
class AWSGameLiftMatchmakingEventRequests
: public AZ::EBusTraits
{
@@ -0,0 +1,51 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
namespace AWSGameLift
{
//! IAWSGameLiftRequests
//! GameLift Gem interfaces to configure GameLift client and other help functions,
//! like creating random GameLift player id
class IAWSGameLiftRequests
{
public:
AZ_RTTI(IAWSGameLiftRequests, "{494167AD-1185-4AF3-8BF9-C8C37FC9C199}");
IAWSGameLiftRequests() = default;
virtual ~IAWSGameLiftRequests() = default;
//! ConfigureGameLiftClient
//! Configure GameLift client to interact with Amazon GameLift service
//! @param region Specifies the AWS region to use
//! @return True if client configuration succeeds, false otherwise
virtual bool ConfigureGameLiftClient(const AZStd::string& region) = 0;
//! CreatePlayerId
//! Create a new, random ID number for every player in every new game session.
//! @param includeBrackets Whether includes brackets in player id
//! @param includeDashes Whether includes dashes in player id
//! @return The player id to use in game session
virtual AZStd::string CreatePlayerId(bool includeBrackets, bool includeDashes) = 0;
};
// IAWSGameLiftRequests EBus wrapper
class AWSGameLiftRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using AWSGameLiftRequestBus = AZ::EBus<IAWSGameLiftRequests, AWSGameLiftRequests>;
} // namespace AWSGameLift
@@ -0,0 +1,38 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
#include <AzFramework/Session/ISessionRequests.h>
namespace AWSGameLift
{
// ISessionAsyncRequests EBus wrapper
class AWSGameLiftSessionAsyncRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using AWSGameLiftSessionAsyncRequestBus = AZ::EBus<AzFramework::ISessionAsyncRequests, AWSGameLiftSessionAsyncRequests>;
// ISessionRequests EBus wrapper
class AWSGameLiftSessionRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using AWSGameLiftSessionRequestBus = AZ::EBus<AzFramework::ISessionRequests, AWSGameLiftSessionRequests>;
} // namespace AWSGameLift
@@ -97,6 +97,7 @@ namespace AWSGameLift
AZ_TracePrintf(AWSGameLiftClientLocalTicketTrackerName,
"Matchmaking ticket %s is complete.", ticket.GetTicketId().c_str());
RequestPlayerJoinMatch(ticket, playerId);
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchComplete);
m_status = TicketTrackerStatus::Idle;
return;
}
@@ -104,25 +105,28 @@ namespace AWSGameLift
ticket.GetStatus() == Aws::GameLift::Model::MatchmakingConfigurationStatus::FAILED ||
ticket.GetStatus() == Aws::GameLift::Model::MatchmakingConfigurationStatus::CANCELLED)
{
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, "Matchmaking ticket %s is not complete, %s",
ticket.GetTicketId().c_str(), ticket.GetStatusReason().c_str());
AZ_Warning(AWSGameLiftClientLocalTicketTrackerName, false, "Matchmaking ticket %s is not complete, %s",
ticket.GetTicketId().c_str(), ticket.GetStatusMessage().c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchFailure);
m_status = TicketTrackerStatus::Idle;
return;
}
else if (ticket.GetStatus() == Aws::GameLift::Model::MatchmakingConfigurationStatus::REQUIRES_ACCEPTANCE)
{
// broadcast acceptance requires to player
AzFramework::MatchAcceptanceNotificationBus::Broadcast(&AzFramework::MatchAcceptanceNotifications::OnMatchAcceptance);
AZ_TracePrintf(AWSGameLiftClientLocalTicketTrackerName, "Matchmaking ticket %s is pending on acceptance, %s.",
ticket.GetTicketId().c_str(), ticket.GetStatusMessage().c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchAcceptance);
}
else
{
AZ_TracePrintf(AWSGameLiftClientLocalTicketTrackerName, "Matchmaking ticket %s is processing, %s.",
ticket.GetTicketId().c_str(), ticket.GetStatusReason().c_str());
ticket.GetTicketId().c_str(), ticket.GetStatusMessage().c_str());
}
}
else
{
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, "Unable to find expected ticket with id %s", ticketId.c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchError);
}
}
else
@@ -130,11 +134,13 @@ namespace AWSGameLift
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, AWSGameLiftErrorMessageTemplate,
describeMatchmakingOutcome.GetError().GetExceptionName().c_str(),
describeMatchmakingOutcome.GetError().GetMessage().c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchError);
}
}
else
{
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, AWSGameLiftClientMissingErrorMessage);
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchError);
}
m_waitEvent.try_acquire_for(AZStd::chrono::milliseconds(m_pollingPeriodInMS));
}
@@ -12,7 +12,7 @@
#include <AzCore/std/parallel/mutex.h>
#include <AzCore/std/parallel/thread.h>
#include <Request/IAWSGameLiftRequests.h>
#include <Request/AWSGameLiftMatchmakingRequestBus.h>
#include <aws/gamelift/model/MatchmakingTicket.h>
@@ -14,6 +14,7 @@
#include <AWSCoreBus.h>
#include <Credential/AWSCredentialBus.h>
#include <Framework/AWSApiJobConfig.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <AWSGameLiftClientManager.h>
@@ -75,7 +76,15 @@ namespace AWSGameLift
bool AWSGameLiftClientManager::ConfigureGameLiftClient(const AZStd::string& region)
{
AZ::Interface<IAWSGameLiftInternalRequests>::Get()->SetGameLiftClient(nullptr);
Aws::Client::ClientConfiguration clientConfig;
AWSCore::AwsApiJobConfig* defaultConfig = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(defaultConfig, &AWSCore::AWSCoreRequests::GetDefaultConfig);
if (defaultConfig)
{
clientConfig = defaultConfig->GetClientConfiguration();
}
// Set up client endpoint or region
AZStd::string localEndpoint = "";
#if defined(AWSGAMELIFT_DEV)
@@ -8,10 +8,13 @@
#pragma once
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Matchmaking/MatchmakingNotifications.h>
#include <Request/IAWSGameLiftRequests.h>
#include <Request/AWSGameLiftRequestBus.h>
#include <Request/AWSGameLiftSessionRequestBus.h>
#include <Request/AWSGameLiftMatchmakingRequestBus.h>
namespace AWSGameLift
{
@@ -23,22 +26,37 @@ namespace AWSGameLift
struct AWSGameLiftStartMatchmakingRequest;
struct AWSGameLiftStopMatchmakingRequest;
// MatchAcceptanceNotificationBus EBus handler for scripting
class AWSGameLiftMatchAcceptanceNotificationBusHandler
: public AzFramework::MatchAcceptanceNotificationBus::Handler
// MatchmakingNotificationBus EBus handler for scripting
class AWSGameLiftMatchmakingNotificationBusHandler
: public AzFramework::MatchmakingNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(
AWSGameLiftMatchAcceptanceNotificationBusHandler,
AWSGameLiftMatchmakingNotificationBusHandler,
"{CBE057D3-F5CE-46D3-B02D-8A6A1446B169}",
AZ::SystemAllocator,
OnMatchAcceptance);
OnMatchAcceptance, OnMatchComplete, OnMatchError, OnMatchFailure);
void OnMatchAcceptance() override
{
Call(FN_OnMatchAcceptance);
}
void OnMatchComplete() override
{
Call(FN_OnMatchComplete);
}
void OnMatchError() override
{
Call(FN_OnMatchError);
}
void OnMatchFailure() override
{
Call(FN_OnMatchFailure);
}
};
// MatchmakingAsyncRequestNotificationBus EBus handler for scripting

Some files were not shown because too many files have changed in this diff Show More