Merge branch 'main' into hultonha_PR-37_follow-up

This commit is contained in:
hultonha
2021-04-28 09:27:00 +01:00
649 changed files with 42698 additions and 60245 deletions
@@ -15,9 +15,9 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ActorSplitsAfterDamage import Tests from ActorSplitsAfterDamage import Tests
def run(): def ActorSplitsAfterCapsuleDamage():
from ActorSplitsAfterDamage import run as internal_run from ActorSplitsAfterDamage import base_run as internal_run
from editor_python_test_tools.utils import Constants from BlastUtils import Constants
def CapsuleDamage(target_id, position0): def CapsuleDamage(target_id, position0):
position1 = azlmbr.object.construct('Vector3', position0.x + 1.0, position0.y, position0.z) position1 = azlmbr.object.construct('Vector3', position0.x + 1.0, position0.y, position0.z)
@@ -30,4 +30,8 @@ def run():
if __name__ == "__main__": if __name__ == "__main__":
run() import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(ActorSplitsAfterCapsuleDamage)
@@ -22,7 +22,7 @@ class Tests():
# fmt: on # fmt: on
def run(): def ActorSplitsAfterCollision():
""" """
Summary: Summary:
@@ -60,8 +60,8 @@ def run():
import azlmbr.legacy.general as general import azlmbr.legacy.general as general
import azlmbr.bus import azlmbr.bus
from editor_python_test_tools.utils import CollisionHandler from BlastUtils import CollisionHandler
from editor_python_test_tools.utils import BlastNotificationHandler from BlastUtils import BlastNotificationHandler
# Constants # Constants
TIMEOUT = 2.0 TIMEOUT = 2.0
@@ -107,4 +107,8 @@ def run():
if __name__ == "__main__": if __name__ == "__main__":
run() import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(ActorSplitsAfterCollision)
@@ -20,7 +20,7 @@ class Tests():
# fmt: on # fmt: on
def run(damage_func): def base_run(damage_func):
""" """
Summary: Summary:
@@ -56,7 +56,7 @@ def run(damage_func):
import azlmbr.legacy.general as general import azlmbr.legacy.general as general
import azlmbr.bus import azlmbr.bus
from editor_python_test_tools.utils import BlastNotificationHandler from BlastUtils import BlastNotificationHandler
# Constants # Constants
TIMEOUT = 2.0 TIMEOUT = 2.0
@@ -15,9 +15,9 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ActorSplitsAfterDamage import Tests from ActorSplitsAfterDamage import Tests
def run(): def ActorSplitsAfterImpactSpreadDamage():
from ActorSplitsAfterDamage import run as internal_run from ActorSplitsAfterDamage import base_run as internal_run
from editor_python_test_tools.utils import Constants from BlastUtils import Constants
def ImpactSpreadDamage(target_id, position): def ImpactSpreadDamage(target_id, position):
azlmbr.destruction.BlastFamilyDamageRequestBus(azlmbr.bus.Event, "Impact Spread Damage", target_id, azlmbr.destruction.BlastFamilyDamageRequestBus(azlmbr.bus.Event, "Impact Spread Damage", target_id,
@@ -28,4 +28,8 @@ def run():
if __name__ == "__main__": if __name__ == "__main__":
run() import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(ActorSplitsAfterImpactSpreadDamage)
@@ -15,9 +15,9 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ActorSplitsAfterDamage import Tests from ActorSplitsAfterDamage import Tests
def run(): def ActorSplitsAfterRadialDamage():
from ActorSplitsAfterDamage import run as internal_run from ActorSplitsAfterDamage import base_run as internal_run
from editor_python_test_tools.utils import Constants from BlastUtils import Constants
def RadialDamage(target_id, position): def RadialDamage(target_id, position):
azlmbr.destruction.BlastFamilyDamageRequestBus(azlmbr.bus.Event, "Radial Damage", target_id, azlmbr.destruction.BlastFamilyDamageRequestBus(azlmbr.bus.Event, "Radial Damage", target_id,
@@ -28,4 +28,8 @@ def run():
if __name__ == "__main__": if __name__ == "__main__":
run() import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(ActorSplitsAfterRadialDamage)
@@ -15,9 +15,9 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ActorSplitsAfterDamage import Tests from ActorSplitsAfterDamage import Tests
def run(): def ActorSplitsAfterShearDamage():
from ActorSplitsAfterDamage import run as internal_run from ActorSplitsAfterDamage import base_run as internal_run
from editor_python_test_tools.utils import Constants from BlastUtils import Constants
def ShearDamage(target_id, position): def ShearDamage(target_id, position):
normal = azlmbr.object.construct('Vector3', 1.0, 0.0, 0.0) normal = azlmbr.object.construct('Vector3', 1.0, 0.0, 0.0)
@@ -29,4 +29,8 @@ def run():
if __name__ == "__main__": if __name__ == "__main__":
run() import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(ActorSplitsAfterShearDamage)
@@ -15,9 +15,9 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ActorSplitsAfterDamage import Tests from ActorSplitsAfterDamage import Tests
def run(): def ActorSplitsAfterStressDamage():
from ActorSplitsAfterDamage import run as internal_run from ActorSplitsAfterDamage import base_run as internal_run
from editor_python_test_tools.utils import Constants from BlastUtils import Constants
def StressDamage(target_id, position): def StressDamage(target_id, position):
force = azlmbr.object.construct('Vector3', 0.0, 0.0, -100.0) # Should be enough to break `brittle` objects force = azlmbr.object.construct('Vector3', 0.0, 0.0, -100.0) # Should be enough to break `brittle` objects
@@ -28,4 +28,8 @@ def run():
if __name__ == "__main__": if __name__ == "__main__":
run() import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(ActorSplitsAfterStressDamage)
@@ -15,9 +15,9 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ActorSplitsAfterDamage import Tests from ActorSplitsAfterDamage import Tests
def run(): def ActorSplitsAfterTriangleDamage():
from ActorSplitsAfterDamage import run as internal_run from ActorSplitsAfterDamage import base_run as internal_run
from editor_python_test_tools.utils import Constants from BlastUtils import Constants
def TriangleDamage(target_id, position): def TriangleDamage(target_id, position):
# Some points that form a triangle that contains the given position # Some points that form a triangle that contains the given position
@@ -32,4 +32,8 @@ def run():
if __name__ == "__main__": if __name__ == "__main__":
run() import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(ActorSplitsAfterTriangleDamage)
@@ -170,7 +170,7 @@ endif()
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest( ly_add_pytest(
NAME AutomatedTesting::BlastTests NAME AutomatedTesting::BlastTests
TEST_SUITE periodic TEST_SUITE main
TEST_SERIAL TRUE TEST_SERIAL TRUE
PATH ${CMAKE_CURRENT_LIST_DIR}/Blast/TestSuite_Active.py PATH ${CMAKE_CURRENT_LIST_DIR}/Blast/TestSuite_Active.py
TIMEOUT 3600 TIMEOUT 3600
@@ -178,6 +178,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Legacy::Editor Legacy::Editor
AZ::AssetProcessor AZ::AssetProcessor
AutomatedTesting.Assets AutomatedTesting.Assets
COMPONENT Blast
) )
endif() endif()
@@ -7,25 +7,10 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS, remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Hydra script that creates an entity and attaches Atom components to it for test verification.
""" """
# This module does a bulk test and update of many components at once.
# Each test case is listed below in the format:
# "Test Case ID: Test Case Title (URL)"
# C32078130: Tone Mapper (https://testrail.agscollab.com/index.php?/cases/view/32078130)
# C32078129: Light (https://testrail.agscollab.com/index.php?/cases/view/32078129)
# C32078131: Radius Weight Modifier (https://testrail.agscollab.com/index.php?/cases/view/32078131)
# C32078127: PostFX Layer (https://testrail.agscollab.com/index.php?/cases/view/32078127)
# C32078126: Point Light (https://testrail.agscollab.com/index.php?/cases/view/32078126)
# C32078125: Physical Sky (https://testrail.agscollab.com/index.php?/cases/view/32078125)
# C32078115: Global Skylight (IBL) (https://testrail.agscollab.com/index.php?/cases/view/32078115)
# C32078121: Exposure Control (https://testrail.agscollab.com/index.php?/cases/view/32078121)
# C32078120: Directional Light (https://testrail.agscollab.com/index.php?/cases/view/32078120)
# C32078119: DepthOfField (https://testrail.agscollab.com/index.php?/cases/view/32078119)
# C32078118: Decal (https://testrail.agscollab.com/index.php?/cases/view/32078118)
# C32078117: Area Light (https://testrail.agscollab.com/index.php?/cases/view/32078117)
import os import os
import sys import sys
@@ -41,10 +26,6 @@ sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "P
import editor_python_test_tools.hydra_editor_utils as hydra import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import TestHelper from editor_python_test_tools.utils import TestHelper
from editor_python_test_tools.editor_test_helper import EditorTestHelper
EditorTestHelper = EditorTestHelper(log_prefix="AtomEditorComponents")
def run(): def run():
@@ -151,28 +132,6 @@ def run():
# Wait for Editor idle loop before executing Python hydra scripts. # Wait for Editor idle loop before executing Python hydra scripts.
TestHelper.init_idle() TestHelper.init_idle()
# Create a new level.
new_level_name = "tmp_level" # Specified in TestAllComponentsBasicTests.py
heightmap_resolution = 512
heightmap_meters_per_pixel = 1
terrain_texture_resolution = 412
use_terrain = False
# Return codes are ECreateLevelResult defined in CryEdit.h
return_code = general.create_level_no_prompt(
new_level_name, heightmap_resolution, heightmap_meters_per_pixel, terrain_texture_resolution, use_terrain)
if return_code == 1:
general.log(f"{new_level_name} level already exists")
elif return_code == 2:
general.log("Failed to create directory")
elif return_code == 3:
general.log("Directory length is too long")
elif return_code != 0:
general.log("Unknown error, failed to create level")
else:
general.log(f"{new_level_name} level created successfully")
EditorTestHelper.after_level_load(bypass_viewport_resize=True)
# Delete all existing entities initially # Delete all existing entities initially
search_filter = azlmbr.entity.SearchFilter() search_filter = azlmbr.entity.SearchFilter()
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
@@ -209,12 +168,12 @@ def run():
entity_obj, ["Capsule Shape"], area_light)) entity_obj, ["Capsule Shape"], area_light))
# Decal Component # Decal Component
material_asset_path = os.path.join("Materials", "decal", "aiirship_nose_number_decal.material") material_asset_path = os.path.join("AutomatedTesting", "Materials", "basic_grey.material")
material_asset = asset.AssetCatalogRequestBus( material_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False) bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False)
ComponentTests( ComponentTests(
"Decal", lambda entity_obj: verify_set_property( "Decal (Atom)", lambda entity_obj: verify_set_property(
entity_obj, "Settings|Decal Settings|Material", material_asset)) entity_obj, "Controller|Configuration|Material", material_asset))
# DepthOfField Component # DepthOfField Component
camera_entity = hydra.Entity("camera_entity") camera_entity = hydra.Entity("camera_entity")
@@ -263,9 +222,12 @@ def run():
# Radius Weight Modifier Component # Radius Weight Modifier Component
ComponentTests("Radius Weight Modifier") ComponentTests("Radius Weight Modifier")
# Spot Light Component # Light Component
ComponentTests("Light") ComponentTests("Light")
# Display Mapper Component
ComponentTests("Display Mapper")
if __name__ == "__main__": if __name__ == "__main__":
run() run()
@@ -7,38 +7,214 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS, remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
Main suite tests for the Atom renderer.
"""
import logging import logging
import os import os
import pytest
import ly_test_tools.environment.file_system as file_system import pytest
import editor_python_test_tools.hydra_test_utils as hydra import editor_python_test_tools.hydra_test_utils as hydra
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
EDITOR_TIMEOUT = 60 EDITOR_TIMEOUT = 120
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
@pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("level", ["tmp_level"]) @pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponents(object): class TestAtomEditorComponentsMain(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project, level):
# Cleanup our temp level
file_system.delete(
[os.path.join(workspace.paths.engine_root(), project, "Levels", "AtomLevels", level)], True, True)
def teardown(): @pytest.mark.test_case_id(
# Cleanup our temp level "C32078117", # Area Light
file_system.delete( "C32078130", # Display Mapper
[os.path.join(workspace.paths.engine_root(), project, "Levels", "AtomLevels", level)], True, True) "C32078129", # Light
"C32078131", # Radius Weight Modifier
"C32078127", # PostFX Layer
"C32078126", # Point Light
"C32078125", # Physical Sky
"C32078115", # Global Skylight (IBL)
"C32078121", # Exposure Control
"C32078120", # Directional Light
"C32078119", # DepthOfField
"C32078118") # Decal
def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
cfg_args = [level]
request.addfinalizer(teardown) expected_lines = [
# Area Light Component
"Area Light Entity successfully created",
"Area Light_test: Component added to the entity: True",
"Area Light_test: Component removed after UNDO: True",
"Area Light_test: Component added after REDO: True",
"Area Light_test: Entered game mode: True",
"Area Light_test: Entity enabled after adding required components: True",
"Area Light_test: Entity is hidden: True",
"Area Light_test: Entity is shown: True",
"Area Light_test: Entity deleted: True",
"Area Light_test: UNDO entity deletion works: True",
"Area Light_test: REDO entity deletion works: True",
# Decal Component
"Decal (Atom) Entity successfully created",
"Decal (Atom)_test: Component added to the entity: True",
"Decal (Atom)_test: Component removed after UNDO: True",
"Decal (Atom)_test: Component added after REDO: True",
"Decal (Atom)_test: Entered game mode: True",
"Decal (Atom)_test: Exit game mode: True",
"Decal (Atom) Controller|Configuration|Material: SUCCESS",
"Decal (Atom)_test: Entity is hidden: True",
"Decal (Atom)_test: Entity is shown: True",
"Decal (Atom)_test: Entity deleted: True",
"Decal (Atom)_test: UNDO entity deletion works: True",
"Decal (Atom)_test: REDO entity deletion works: True",
# DepthOfField Component
"DepthOfField Entity successfully created",
"DepthOfField_test: Component added to the entity: True",
"DepthOfField_test: Component removed after UNDO: True",
"DepthOfField_test: Component added after REDO: True",
"DepthOfField_test: Entered game mode: True",
"DepthOfField_test: Exit game mode: True",
"DepthOfField_test: Entity disabled initially: True",
"DepthOfField_test: Entity enabled after adding required components: True",
"DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
"DepthOfField_test: Entity is hidden: True",
"DepthOfField_test: Entity is shown: True",
"DepthOfField_test: Entity deleted: True",
"DepthOfField_test: UNDO entity deletion works: True",
"DepthOfField_test: REDO entity deletion works: True",
# Directional Light Component
"Directional Light Entity successfully created",
"Directional Light_test: Component added to the entity: True",
"Directional Light_test: Component removed after UNDO: True",
"Directional Light_test: Component added after REDO: True",
"Directional Light_test: Entered game mode: True",
"Directional Light_test: Exit game mode: True",
"Directional Light Controller|Configuration|Shadow|Camera: SUCCESS",
"Directional Light_test: Entity is hidden: True",
"Directional Light_test: Entity is shown: True",
"Directional Light_test: Entity deleted: True",
"Directional Light_test: UNDO entity deletion works: True",
"Directional Light_test: REDO entity deletion works: True",
# Exposure Control Component
"Exposure Control Entity successfully created",
"Exposure Control_test: Component added to the entity: True",
"Exposure Control_test: Component removed after UNDO: True",
"Exposure Control_test: Component added after REDO: True",
"Exposure Control_test: Entered game mode: True",
"Exposure Control_test: Exit game mode: True",
"Exposure Control_test: Entity disabled initially: True",
"Exposure Control_test: Entity enabled after adding required components: True",
"Exposure Control_test: Entity is hidden: True",
"Exposure Control_test: Entity is shown: True",
"Exposure Control_test: Entity deleted: True",
"Exposure Control_test: UNDO entity deletion works: True",
"Exposure Control_test: REDO entity deletion works: True",
# Global Skylight (IBL) Component
"Global Skylight (IBL) Entity successfully created",
"Global Skylight (IBL)_test: Component added to the entity: True",
"Global Skylight (IBL)_test: Component removed after UNDO: True",
"Global Skylight (IBL)_test: Component added after REDO: True",
"Global Skylight (IBL)_test: Entered game mode: True",
"Global Skylight (IBL)_test: Exit game mode: True",
"Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
"Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
"Global Skylight (IBL)_test: Entity is hidden: True",
"Global Skylight (IBL)_test: Entity is shown: True",
"Global Skylight (IBL)_test: Entity deleted: True",
"Global Skylight (IBL)_test: UNDO entity deletion works: True",
"Global Skylight (IBL)_test: REDO entity deletion works: True",
# Physical Sky Component
"Physical Sky Entity successfully created",
"Physical Sky component was added to entity",
"Entity has a Physical Sky component",
"Physical Sky_test: Component added to the entity: True",
"Physical Sky_test: Component removed after UNDO: True",
"Physical Sky_test: Component added after REDO: True",
"Physical Sky_test: Entered game mode: True",
"Physical Sky_test: Exit game mode: True",
"Physical Sky_test: Entity is hidden: True",
"Physical Sky_test: Entity is shown: True",
"Physical Sky_test: Entity deleted: True",
"Physical Sky_test: UNDO entity deletion works: True",
"Physical Sky_test: REDO entity deletion works: True",
# Point Light Component
"Point Light Entity successfully created",
"Point Light_test: Component added to the entity: True",
"Point Light_test: Component removed after UNDO: True",
"Point Light_test: Component added after REDO: True",
"Point Light_test: Entered game mode: True",
"Point Light_test: Exit game mode: True",
"Point Light_test: Entity is hidden: True",
"Point Light_test: Entity is shown: True",
"Point Light_test: Entity deleted: True",
"Point Light_test: UNDO entity deletion works: True",
"Point Light_test: REDO entity deletion works: True",
# PostFX Layer Component
"PostFX Layer Entity successfully created",
"PostFX Layer_test: Component added to the entity: True",
"PostFX Layer_test: Component removed after UNDO: True",
"PostFX Layer_test: Component added after REDO: True",
"PostFX Layer_test: Entered game mode: True",
"PostFX Layer_test: Exit game mode: True",
"PostFX Layer_test: Entity is hidden: True",
"PostFX Layer_test: Entity is shown: True",
"PostFX Layer_test: Entity deleted: True",
"PostFX Layer_test: UNDO entity deletion works: True",
"PostFX Layer_test: REDO entity deletion works: True",
# Radius Weight Modifier Component
"Radius Weight Modifier Entity successfully created",
"Radius Weight Modifier_test: Component added to the entity: True",
"Radius Weight Modifier_test: Component removed after UNDO: True",
"Radius Weight Modifier_test: Component added after REDO: True",
"Radius Weight Modifier_test: Entered game mode: True",
"Radius Weight Modifier_test: Exit game mode: True",
"Radius Weight Modifier_test: Entity is hidden: True",
"Radius Weight Modifier_test: Entity is shown: True",
"Radius Weight Modifier_test: Entity deleted: True",
"Radius Weight Modifier_test: UNDO entity deletion works: True",
"Radius Weight Modifier_test: REDO entity deletion works: True",
# Light Component
"Light Entity successfully created",
"Light_test: Component added to the entity: True",
"Light_test: Component removed after UNDO: True",
"Light_test: Component added after REDO: True",
"Light_test: Entered game mode: True",
"Light_test: Exit game mode: True",
"Light_test: Entity is hidden: True",
"Light_test: Entity is shown: True",
"Light_test: Entity deleted: True",
"Light_test: UNDO entity deletion works: True",
"Light_test: REDO entity deletion works: True",
# Display Mapper Component
"Display Mapper Entity successfully created",
"Display Mapper_test: Component added to the entity: True",
"Display Mapper_test: Component removed after UNDO: True",
"Display Mapper_test: Component added after REDO: True",
"Display Mapper_test: Entered game mode: True",
"Display Mapper_test: Exit game mode: True",
"Display Mapper_test: Entity is hidden: True",
"Display Mapper_test: Entity is shown: True",
"Display Mapper_test: Entity deleted: True",
"Display Mapper_test: UNDO entity deletion works: True",
"Display Mapper_test: REDO entity deletion works: True",
]
# It requires at least one test unexpected_lines = [
def test_Dummy(self, request, editor, level, workspace, project, launcher_platform): "failed to open",
pass "Traceback (most recent call last):",
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
editor,
"hydra_AtomEditorComponents_AddedToEntity.py",
timeout=EDITOR_TIMEOUT,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
)
@@ -7,213 +7,18 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS, remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Sandbox suite tests for the Atom renderer.
""" """
import logging
import os
import pytest import pytest
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
logger = logging.getLogger(__name__)
EDITOR_TIMEOUT = 60
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
@pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("level", ["tmp_level"]) @pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponents(object): class TestAtomEditorComponentsSandbox(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project, level):
# Cleanup our temp level
file_system.delete(
[os.path.join(workspace.paths.engine_root(), project, "Levels", "AtomLevels", level)], True, True)
def teardown(): # It requires at least one test
# Cleanup our temp level def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
file_system.delete( pass
[os.path.join(workspace.paths.engine_root(), project, "Levels", "AtomLevels", level)], True, True)
request.addfinalizer(teardown)
@pytest.mark.test_case_id(
"C32078130", # Tone Mapper
"C32078129", # Light
"C32078131", # Radius Weight Modifier
"C32078127", # PostFX Layer
"C32078126", # Point Light
"C32078125", # Physical Sky
"C32078115", # Global Skylight (IBL)
"C32078121", # Exposure Control
"C32078120", # Directional Light
"C32078119", # DepthOfField
"C32078118") # Decal
def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
cfg_args = [level]
expected_lines = [
# Area Light Component
"Area Light Entity successfully created",
"Area Light_test: Component added to the entity: True",
"Area Light_test: Component removed after UNDO: True",
"Area Light_test: Component added after REDO: True",
"Area Light_test: Entered game mode: True",
"Area Light_test: Entity enabled after adding required components: True",
"Area Light_test: Entity is hidden: True",
"Area Light_test: Entity is shown: True",
"Area Light_test: Entity deleted: True",
"Area Light_test: UNDO entity deletion works: True",
"Area Light_test: REDO entity deletion works: True",
# Decal Component
"Decal Entity successfully created",
"Decal_test: Component added to the entity: True",
"Decal_test: Component removed after UNDO: True",
"Decal_test: Component added after REDO: True",
"Decal_test: Entered game mode: True",
"Decal_test: Exit game mode: True",
"Decal Settings|Decal Settings|Material: SUCCESS",
"Decal_test: Entity is hidden: True",
"Decal_test: Entity is shown: True",
"Decal_test: Entity deleted: True",
"Decal_test: UNDO entity deletion works: True",
"Decal_test: REDO entity deletion works: True",
# DepthOfField Component
"DepthOfField Entity successfully created",
"DepthOfField_test: Component added to the entity: True",
"DepthOfField_test: Component removed after UNDO: True",
"DepthOfField_test: Component added after REDO: True",
"DepthOfField_test: Entered game mode: True",
"DepthOfField_test: Exit game mode: True",
"DepthOfField_test: Entity disabled initially: True",
"DepthOfField_test: Entity enabled after adding required components: True",
"DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
"DepthOfField_test: Entity is hidden: True",
"DepthOfField_test: Entity is shown: True",
"DepthOfField_test: Entity deleted: True",
"DepthOfField_test: UNDO entity deletion works: True",
"DepthOfField_test: REDO entity deletion works: True",
# Directional Light Component
"Directional Light Entity successfully created",
"Directional Light_test: Component added to the entity: True",
"Directional Light_test: Component removed after UNDO: True",
"Directional Light_test: Component added after REDO: True",
"Directional Light_test: Entered game mode: True",
"Directional Light_test: Exit game mode: True",
"Directional Light Controller|Configuration|Shadow|Camera: SUCCESS",
"Directional Light_test: Entity is hidden: True",
"Directional Light_test: Entity is shown: True",
"Directional Light_test: Entity deleted: True",
"Directional Light_test: UNDO entity deletion works: True",
"Directional Light_test: REDO entity deletion works: True",
# Exposure Control Component
"Exposure Control Entity successfully created",
"Exposure Control_test: Component added to the entity: True",
"Exposure Control_test: Component removed after UNDO: True",
"Exposure Control_test: Component added after REDO: True",
"Exposure Control_test: Entered game mode: True",
"Exposure Control_test: Exit game mode: True",
"Exposure Control_test: Entity disabled initially: True",
"Exposure Control_test: Entity enabled after adding required components: True",
"Exposure Control_test: Entity is hidden: True",
"Exposure Control_test: Entity is shown: True",
"Exposure Control_test: Entity deleted: True",
"Exposure Control_test: UNDO entity deletion works: True",
"Exposure Control_test: REDO entity deletion works: True",
# Global Skylight (IBL) Component
"Global Skylight (IBL) Entity successfully created",
"Global Skylight (IBL)_test: Component added to the entity: True",
"Global Skylight (IBL)_test: Component removed after UNDO: True",
"Global Skylight (IBL)_test: Component added after REDO: True",
"Global Skylight (IBL)_test: Entered game mode: True",
"Global Skylight (IBL)_test: Exit game mode: True",
"Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
"Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
"Global Skylight (IBL)_test: Entity is hidden: True",
"Global Skylight (IBL)_test: Entity is shown: True",
"Global Skylight (IBL)_test: Entity deleted: True",
"Global Skylight (IBL)_test: UNDO entity deletion works: True",
"Global Skylight (IBL)_test: REDO entity deletion works: True",
# Physical Sky Component
"Physical Sky Entity successfully created",
"Physical Sky component was added to entity",
"Entity has a Physical Sky component",
"Physical Sky_test: Component added to the entity: True",
"Physical Sky_test: Component removed after UNDO: True",
"Physical Sky_test: Component added after REDO: True",
"Physical Sky_test: Entered game mode: True",
"Physical Sky_test: Exit game mode: True",
"Physical Sky_test: Entity is hidden: True",
"Physical Sky_test: Entity is shown: True",
"Physical Sky_test: Entity deleted: True",
"Physical Sky_test: UNDO entity deletion works: True",
"Physical Sky_test: REDO entity deletion works: True",
# Point Light Component
"Point Light Entity successfully created",
"Point Light_test: Component added to the entity: True",
"Point Light_test: Component removed after UNDO: True",
"Point Light_test: Component added after REDO: True",
"Point Light_test: Entered game mode: True",
"Point Light_test: Exit game mode: True",
"Point Light_test: Entity is hidden: True",
"Point Light_test: Entity is shown: True",
"Point Light_test: Entity deleted: True",
"Point Light_test: UNDO entity deletion works: True",
"Point Light_test: REDO entity deletion works: True",
# PostFX Layer Component
"PostFX Layer Entity successfully created",
"PostFX Layer_test: Component added to the entity: True",
"PostFX Layer_test: Component removed after UNDO: True",
"PostFX Layer_test: Component added after REDO: True",
"PostFX Layer_test: Entered game mode: True",
"PostFX Layer_test: Exit game mode: True",
"PostFX Layer_test: Entity is hidden: True",
"PostFX Layer_test: Entity is shown: True",
"PostFX Layer_test: Entity deleted: True",
"PostFX Layer_test: UNDO entity deletion works: True",
"PostFX Layer_test: REDO entity deletion works: True",
# Radius Weight Modifier Component
"Radius Weight Modifier Entity successfully created",
"Radius Weight Modifier_test: Component added to the entity: True",
"Radius Weight Modifier_test: Component removed after UNDO: True",
"Radius Weight Modifier_test: Component added after REDO: True",
"Radius Weight Modifier_test: Entered game mode: True",
"Radius Weight Modifier_test: Exit game mode: True",
"Radius Weight Modifier_test: Entity is hidden: True",
"Radius Weight Modifier_test: Entity is shown: True",
"Radius Weight Modifier_test: Entity deleted: True",
"Radius Weight Modifier_test: UNDO entity deletion works: True",
"Radius Weight Modifier_test: REDO entity deletion works: True",
# Light Component
"Light Entity successfully created",
"Light_test: Component added to the entity: True",
"Light_test: Component removed after UNDO: True",
"Light_test: Component added after REDO: True",
"Light_test: Entered game mode: True",
"Light_test: Exit game mode: True",
"Light_test: Entity is hidden: True",
"Light_test: Entity is shown: True",
"Light_test: Entity deleted: True",
"Light_test: UNDO entity deletion works: True",
"Light_test: REDO entity deletion works: True",
]
unexpected_lines = [
"failed to open",
"Traceback (most recent call last):",
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
editor,
"hydra_AtomEditorComponents_AddedToEntity.py",
timeout=EDITOR_TIMEOUT,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
)
@@ -41,7 +41,7 @@ class TestDynamicSliceInstanceSpawner(object):
return console return console
@pytest.mark.test_case_id("C28851763") @pytest.mark.test_case_id("C28851763")
@pytest.mark.SUITE_main @pytest.mark.SUITE_sandbox
@pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, editor, level, workspace, project, def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, editor, level, workspace, project,
launcher_platform): launcher_platform):
@@ -36,8 +36,13 @@ class TestEmptyInstanceSpawner(object):
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
@pytest.mark.test_case_id("C28851762") # Main suite needs at least one test
@pytest.mark.SUITE_main @pytest.mark.SUITE_main
def test_EmptyInstanceSpawner_Dummy(self, request, editor, level, workspace, project, launcher_platform):
pass
@pytest.mark.test_case_id("C28851762")
@pytest.mark.SUITE_sandbox
def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, editor, level, launcher_platform): def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, editor, level, launcher_platform):
cfg_args = [level] cfg_args = [level]
@@ -269,6 +269,8 @@ class TestAutomation(TestAutomationBase):
from . import C18977601_Material_FrictionCombinePriority as test_module from . import C18977601_Material_FrictionCombinePriority as test_module
self._run_test(request, workspace, editor, test_module) self._run_test(request, workspace, editor, test_module)
@pytest.mark.xfail(
reason="Something with the CryRenderer disabling is causing this test to fail now.")
@revert_physics_config @revert_physics_config
def test_C13895144_Ragdoll_ChangeLevel(self, request, workspace, editor, launcher_platform): def test_C13895144_Ragdoll_ChangeLevel(self, request, workspace, editor, launcher_platform):
from . import C13895144_Ragdoll_ChangeLevel as test_module from . import C13895144_Ragdoll_ChangeLevel as test_module
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -118,6 +118,7 @@ namespace AZ
const static AZ::Crc32 StringLineEditingCompleteNotify = AZ_CRC("StringLineEditingCompleteNotify", 0x139e5fa9); const static AZ::Crc32 StringLineEditingCompleteNotify = AZ_CRC("StringLineEditingCompleteNotify", 0x139e5fa9);
const static AZ::Crc32 NameLabelOverride = AZ_CRC("NameLabelOverride", 0x9ff79cab); const static AZ::Crc32 NameLabelOverride = AZ_CRC("NameLabelOverride", 0x9ff79cab);
const static AZ::Crc32 AssetPickerTitle = AZ_CRC_CE("AssetPickerTitle");
const static AZ::Crc32 ChildNameLabelOverride = AZ_CRC("ChildNameLabelOverride", 0x73dd2909); const static AZ::Crc32 ChildNameLabelOverride = AZ_CRC("ChildNameLabelOverride", 0x73dd2909);
//! Container attribute that is used to override labels for its elements given the index of the element //! Container attribute that is used to override labels for its elements given the index of the element
const static AZ::Crc32 IndexedChildNameLabelOverride = AZ_CRC("IndexedChildNameLabelOverride", 0x5f313ac2); const static AZ::Crc32 IndexedChildNameLabelOverride = AZ_CRC("IndexedChildNameLabelOverride", 0x5f313ac2);
@@ -78,7 +78,7 @@ namespace Physics
float m_minimumMovementDistance = 0.001f; //!< To avoid jittering, the controller will not attempt to move distances below this. float m_minimumMovementDistance = 0.001f; //!< To avoid jittering, the controller will not attempt to move distances below this.
float m_maximumSpeed = 100.0f; //!< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped. float m_maximumSpeed = 100.0f; //!< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped.
AZStd::string m_colliderTag; //!< Used to identify the collider associated with the character controller. AZStd::string m_colliderTag; //!< Used to identify the collider associated with the character controller.
AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfig = nullptr; //!< The shape to use when creating the character controller. AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfig; //!< The shape to use when creating the character controller.
AZStd::vector<AZStd::shared_ptr<Physics::Shape>> m_colliders; //!< The list of colliders to attach to the character controller. AZStd::vector<AZStd::shared_ptr<Physics::Shape>> m_colliders; //!< The list of colliders to attach to the character controller.
}; };
@@ -55,7 +55,7 @@ namespace AzPhysics
//! Flag to determine if the body is part of the simulation. //! Flag to determine if the body is part of the simulation.
//! When true the body will be affected by any forces, collisions, and found with scene queries. //! When true the body will be affected by any forces, collisions, and found with scene queries.
bool m_simulating = true; bool m_simulating = false;
//! Helper functions for setting user data. //! Helper functions for setting user data.
//! @param userData Can be a pointer to any type as internally will be cast to a void*. Object lifetime not managed by the SimulatedBody. //! @param userData Can be a pointer to any type as internally will be cast to a void*. Object lifetime not managed by the SimulatedBody.
@@ -46,6 +46,7 @@ namespace AzPhysics
->Field("orientation", &SimulatedBodyConfiguration::m_orientation) ->Field("orientation", &SimulatedBodyConfiguration::m_orientation)
->Field("scale", &SimulatedBodyConfiguration::m_scale) ->Field("scale", &SimulatedBodyConfiguration::m_scale)
->Field("entityId", &SimulatedBodyConfiguration::m_entityId) ->Field("entityId", &SimulatedBodyConfiguration::m_entityId)
->Field("startSimulationEnabled", &SimulatedBodyConfiguration::m_startSimulationEnabled)
; ;
} }
} }
@@ -39,6 +39,7 @@ namespace AzPhysics
AZ::Vector3 m_position = AZ::Vector3::CreateZero(); AZ::Vector3 m_position = AZ::Vector3::CreateZero();
AZ::Quaternion m_orientation = AZ::Quaternion::CreateIdentity(); AZ::Quaternion m_orientation = AZ::Quaternion::CreateIdentity();
AZ::Vector3 m_scale = AZ::Vector3::CreateOne(); AZ::Vector3 m_scale = AZ::Vector3::CreateOne();
bool m_startSimulationEnabled = true;
// Entity/object association. // Entity/object association.
AZ::EntityId m_entityId = AZ::EntityId(AZ::EntityId::InvalidEntityId); AZ::EntityId m_entityId = AZ::EntityId(AZ::EntityId::InvalidEntityId);
@@ -52,6 +52,11 @@ namespace Physics
} }
} }
RagdollConfiguration::RagdollConfiguration()
{
m_startSimulationEnabled = false; //ragdolls do not start enabled.
}
void RagdollConfiguration::Reflect(AZ::ReflectContext* context) void RagdollConfiguration::Reflect(AZ::ReflectContext* context)
{ {
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context); AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
@@ -24,6 +24,8 @@
namespace Physics namespace Physics
{ {
using ParentIndices = AZStd::vector<size_t>;
class RagdollNodeConfiguration class RagdollNodeConfiguration
: public AzPhysics::RigidBodyConfiguration : public AzPhysics::RigidBodyConfiguration
{ {
@@ -46,7 +48,7 @@ namespace Physics
AZ_RTTI(RagdollConfiguration, "{7C96D332-61D8-4C58-A2BF-707716D38D14}", AzPhysics::SimulatedBodyConfiguration); AZ_RTTI(RagdollConfiguration, "{7C96D332-61D8-4C58-A2BF-707716D38D14}", AzPhysics::SimulatedBodyConfiguration);
static void Reflect(AZ::ReflectContext* context); static void Reflect(AZ::ReflectContext* context);
RagdollConfiguration() = default; RagdollConfiguration();
explicit RagdollConfiguration(const RagdollConfiguration& settings) = default; explicit RagdollConfiguration(const RagdollConfiguration& settings) = default;
RagdollNodeConfiguration* FindNodeConfigByName(const AZStd::string& nodeName) const; RagdollNodeConfiguration* FindNodeConfigByName(const AZStd::string& nodeName) const;
@@ -56,6 +58,8 @@ namespace Physics
AZStd::vector<RagdollNodeConfiguration> m_nodes; AZStd::vector<RagdollNodeConfiguration> m_nodes;
CharacterColliderConfiguration m_colliders; CharacterColliderConfiguration m_colliders;
RagdollState m_initialState;
ParentIndices m_parentIndices;
}; };
/// Represents a single rigid part of a ragdoll. /// Represents a single rigid part of a ragdoll.
@@ -79,7 +83,7 @@ namespace Physics
{ {
public: public:
AZ_CLASS_ALLOCATOR(Ragdoll, AZ::SystemAllocator, 0); AZ_CLASS_ALLOCATOR(Ragdoll, AZ::SystemAllocator, 0);
AZ_RTTI(Ragdoll, "{01F09602-80EC-4693-A0E7-C2719239044B}", AzPhysics::SimulatedBody); AZ_RTTI(Physics::Ragdoll, "{01F09602-80EC-4693-A0E7-C2719239044B}", AzPhysics::SimulatedBody);
virtual ~Ragdoll() = default; virtual ~Ragdoll() = default;
/// Inserts the ragdoll into the physics simulation. /// Inserts the ragdoll into the physics simulation.
@@ -16,7 +16,6 @@
#include <AzCore/Serialization/EditContext.h> #include <AzCore/Serialization/EditContext.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h> #include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h> #include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationBus.h> #include <AzToolsFramework/UI/Prefab/PrefabIntegrationBus.h>
namespace AzToolsFramework namespace AzToolsFramework
@@ -21,9 +21,9 @@
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h> #include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
#include <AzToolsFramework/Prefab/PrefabDomUtils.h> #include <AzToolsFramework/Prefab/PrefabDomUtils.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h> #include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h> #include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/Prefab/Template/Template.h> #include <AzToolsFramework/Prefab/Template/Template.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
namespace AzToolsFramework namespace AzToolsFramework
{ {
@@ -90,17 +90,13 @@ namespace AzToolsFramework
if (instanceCountToUpdateInBatch > 0) if (instanceCountToUpdateInBatch > 0)
{ {
// Notify Propagation has begun
PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationBegin);
EntityIdList selectedEntityIds; EntityIdList selectedEntityIds;
ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities); ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &ToolsApplicationRequests::GetSelectedEntities);
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, EntityIdList()); ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, EntityIdList());
// Disable the Outliner to avoid showing the propagation steps
EntityOutlinerWidgetInterface* entityOutlinerWidgetInterface = AZ::Interface<EntityOutlinerWidgetInterface>::Get();
if (entityOutlinerWidgetInterface)
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(false);
}
for (int i = 0; i < instanceCountToUpdateInBatch; ++i) for (int i = 0; i < instanceCountToUpdateInBatch; ++i)
{ {
Instance* instanceToUpdate = m_instancesUpdateQueue.front(); Instance* instanceToUpdate = m_instancesUpdateQueue.front();
@@ -168,18 +164,8 @@ namespace AzToolsFramework
} }
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds); ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
// Enable the Outliner // Notify Propagation has ended
if (entityOutlinerWidgetInterface) PrefabPublicNotificationBus::Broadcast(&PrefabPublicNotifications::OnPrefabInstancePropagationEnd);
{
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
auto prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
if (prefabPublicInterface)
{
AZ::EntityId rootEntityId = prefabPublicInterface->GetLevelInstanceContainerEntityId();
entityOutlinerWidgetInterface->ExpandEntityChildren(rootEntityId);
}
}
} }
m_updatingTemplateInstancesInQueue = false; m_updatingTemplateInstancesInQueue = false;
@@ -0,0 +1,34 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace AzToolsFramework
{
namespace Prefab
{
class PrefabPublicNotifications
: public AZ::EBusTraits
{
public:
virtual ~PrefabPublicNotifications() = default;
virtual void OnPrefabInstancePropagationBegin() {}
virtual void OnPrefabInstancePropagationEnd() {}
};
using PrefabPublicNotificationBus = AZ::EBus<PrefabPublicNotifications>;
} // namespace Prefab
} // namespace AzToolsFramework
@@ -286,12 +286,12 @@ namespace AzToolsFramework
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect( ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
GetEntityContextId()); GetEntityContextId());
EditorEntityInfoNotificationBus::Handler::BusConnect(); EditorEntityInfoNotificationBus::Handler::BusConnect();
AZ::Interface<EntityOutlinerWidgetInterface>::Register(this); Prefab::PrefabPublicNotificationBus::Handler::BusConnect();
} }
EntityOutlinerWidget::~EntityOutlinerWidget() EntityOutlinerWidget::~EntityOutlinerWidget()
{ {
AZ::Interface<EntityOutlinerWidgetInterface>::Unregister(this); Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect();
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect(); ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
EditorEntityInfoNotificationBus::Handler::BusDisconnect(); EditorEntityInfoNotificationBus::Handler::BusDisconnect();
EditorPickModeNotificationBus::Handler::BusDisconnect(); EditorPickModeNotificationBus::Handler::BusDisconnect();
@@ -1109,25 +1109,18 @@ namespace AzToolsFramework
setEnabled(true); setEnabled(true);
SetEntityOutlinerState(m_gui, true); SetEntityOutlinerState(m_gui, true);
} }
void EntityOutlinerWidget::SetUpdatesEnabled(bool enable) void EntityOutlinerWidget::OnPrefabInstancePropagationBegin()
{ {
if (enable) m_gui->m_objectTree->setUpdatesEnabled(false);
{
QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->setUpdatesEnabled(true);
});
}
else
{
m_gui->m_objectTree->setUpdatesEnabled(false);
}
} }
void EntityOutlinerWidget::ExpandEntityChildren(AZ::EntityId entityId) void EntityOutlinerWidget::OnPrefabInstancePropagationEnd()
{ {
QModelIndex index = GetIndexFromEntityId(entityId); QTimer::singleShot(1, this, [this]() {
m_gui->m_objectTree->expand(index); m_gui->m_objectTree->setUpdatesEnabled(true);
m_gui->m_objectTree->expand(m_proxyModel->index(0,0));
});
} }
void EntityOutlinerWidget::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId childId) void EntityOutlinerWidget::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId /*parentId*/, AZ::EntityId childId)
@@ -20,10 +20,10 @@
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h> #include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h> #include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h> #include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
#include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h> #include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerCacheBus.h> #include <AzToolsFramework/UI/Outliner/EntityOutlinerCacheBus.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerSearchWidget.h> #include <AzToolsFramework/UI/Outliner/EntityOutlinerSearchWidget.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
#include <AzToolsFramework/UI/SearchWidget/SearchWidgetTypes.hxx> #include <AzToolsFramework/UI/SearchWidget/SearchWidgetTypes.hxx>
#include <QIcon> #include <QIcon>
@@ -62,7 +62,7 @@ namespace AzToolsFramework
, private EditorEntityContextNotificationBus::Handler , private EditorEntityContextNotificationBus::Handler
, private EditorEntityInfoNotificationBus::Handler , private EditorEntityInfoNotificationBus::Handler
, private ComponentModeFramework::EditorComponentModeNotificationBus::Handler , private ComponentModeFramework::EditorComponentModeNotificationBus::Handler
, private EntityOutlinerWidgetInterface , private Prefab::PrefabPublicNotificationBus::Handler
{ {
Q_OBJECT; Q_OBJECT;
public: public:
@@ -106,9 +106,9 @@ namespace AzToolsFramework
void EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override; void EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
void LeftComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override; void LeftComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
// EntityOutlinerWidgetInterface // PrefabPublicNotificationBus
void SetUpdatesEnabled(bool enable) override; void OnPrefabInstancePropagationBegin() override;
void ExpandEntityChildren(AZ::EntityId entityId) override; void OnPrefabInstancePropagationEnd() override;
// Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored. // Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored.
template <class EntityIdCollection> template <class EntityIdCollection>
@@ -63,7 +63,7 @@ AZ_POP_DISABLE_WARNING
#include <UI/PropertyEditor/Model/AssetCompleterModel.h> #include <UI/PropertyEditor/Model/AssetCompleterModel.h>
#include <UI/PropertyEditor/View/AssetCompleterListView.h> #include <UI/PropertyEditor/View/AssetCompleterListView.h>
#include <UI/PropertyEditor/ThumbnailDropDown.h> #include <UI/PropertyEditor/ThumbnailPropertyCtrl.h>
namespace AzToolsFramework namespace AzToolsFramework
{ {
@@ -93,15 +93,11 @@ namespace AzToolsFramework
setAcceptDrops(true); setAcceptDrops(true);
m_thumbnail = new Thumbnailer::ThumbnailWidget(this); m_thumbnail = new ThumbnailPropertyCtrl(this);
m_thumbnail->setFixedSize(QSize(24, 24)); m_thumbnail->setFixedSize(QSize(40, 24));
m_thumbnail->setVisible(false); m_thumbnail->setVisible(false);
m_thumbnailDropDown = new ThumbnailDropDown(this); connect(m_thumbnail, &ThumbnailPropertyCtrl::clicked, this, &PropertyAssetCtrl::OnThumbnailClicked);
m_thumbnailDropDown->setFixedSize(QSize(40, 24));
m_thumbnailDropDown->setVisible(false);
connect(m_thumbnailDropDown, &ThumbnailDropDown::clicked, this, &PropertyAssetCtrl::OnEditButtonClicked);
m_editButton = new QToolButton(this); m_editButton = new QToolButton(this);
m_editButton->setAutoRaise(true); m_editButton->setAutoRaise(true);
@@ -112,7 +108,6 @@ namespace AzToolsFramework
connect(m_editButton, &QToolButton::clicked, this, &PropertyAssetCtrl::OnEditButtonClicked); connect(m_editButton, &QToolButton::clicked, this, &PropertyAssetCtrl::OnEditButtonClicked);
pLayout->addWidget(m_thumbnail); pLayout->addWidget(m_thumbnail);
pLayout->addWidget(m_thumbnailDropDown);
pLayout->addWidget(m_browseEdit); pLayout->addWidget(m_browseEdit);
pLayout->addWidget(m_editButton); pLayout->addWidget(m_editButton);
@@ -188,6 +183,17 @@ namespace AzToolsFramework
} }
} }
void PropertyAssetCtrl::OnThumbnailClicked()
{
const AZ::Data::AssetId assetID = GetCurrentAssetID();
if (m_thumbnailCallback)
{
AZ_Error("Asset Property", m_editNotifyTarget, "No notification target set for edit callback.");
m_thumbnailCallback->Invoke(m_editNotifyTarget, assetID, GetCurrentAssetType());
return;
}
}
void PropertyAssetCtrl::OnCompletionModelReset() void PropertyAssetCtrl::OnCompletionModelReset()
{ {
if (!m_completerIsActive) if (!m_completerIsActive)
@@ -674,6 +680,13 @@ namespace AzToolsFramework
AzQtComponents::BrowseEdit::removeDropTargetStyle(m_browseEdit); AzQtComponents::BrowseEdit::removeDropTargetStyle(m_browseEdit);
} }
AssetSelectionModel PropertyAssetCtrl::GetAssetSelectionModel()
{
auto selectionModel = AssetSelectionModel::AssetTypeSelection(GetCurrentAssetType());
selectionModel.SetTitle(m_title);
return selectionModel;
}
void PropertyAssetCtrl::UpdateTabOrder() void PropertyAssetCtrl::UpdateTabOrder()
{ {
setTabOrder(m_browseEdit, m_editButton); setTabOrder(m_browseEdit, m_editButton);
@@ -1052,6 +1065,11 @@ namespace AzToolsFramework
m_editButton->setIcon(icon); m_editButton->setIcon(icon);
} }
void PropertyAssetCtrl::SetTitle(const QString& title)
{
m_title = title;
}
void PropertyAssetCtrl::SetEditNotifyTarget(void* editNotifyTarget) void PropertyAssetCtrl::SetEditNotifyTarget(void* editNotifyTarget)
{ {
m_editNotifyTarget = editNotifyTarget; m_editNotifyTarget = editNotifyTarget;
@@ -1091,10 +1109,10 @@ namespace AzToolsFramework
void PropertyAssetCtrl::UpdateThumbnail() void PropertyAssetCtrl::UpdateThumbnail()
{ {
m_thumbnail->setVisible(m_showThumbnail); m_thumbnail->setVisible(m_showThumbnail);
m_thumbnailDropDown->setVisible(m_showThumbnailDropDown);
if (m_showThumbnail || m_showThumbnailDropDown) if (m_showThumbnail)
{ {
m_thumbnail->ShowDropDownArrow(m_showThumbnailDropDownButton);
const AZ::Data::AssetId assetID = GetCurrentAssetID(); const AZ::Data::AssetId assetID = GetCurrentAssetID();
if (assetID.IsValid()) if (assetID.IsValid())
{ {
@@ -1112,17 +1130,12 @@ namespace AzToolsFramework
{ {
m_thumbnail->SetThumbnailKey(thumbnailKey, Thumbnailer::ThumbnailContext::DefaultContext); m_thumbnail->SetThumbnailKey(thumbnailKey, Thumbnailer::ThumbnailContext::DefaultContext);
} }
if (m_showThumbnailDropDown)
{
m_thumbnailDropDown->SetThumbnailKey(thumbnailKey, Thumbnailer::ThumbnailContext::DefaultContext);
}
return; return;
} }
} }
} }
m_thumbnail->ClearThumbnail(); m_thumbnail->ClearThumbnail();
m_thumbnailDropDown->ClearThumbnail();
} }
void PropertyAssetCtrl::SetClearButtonEnabled(bool enable) void PropertyAssetCtrl::SetClearButtonEnabled(bool enable)
@@ -1156,14 +1169,19 @@ namespace AzToolsFramework
return m_showThumbnail; return m_showThumbnail;
} }
void PropertyAssetCtrl::SetShowThumbnailDropDown(bool enable) void PropertyAssetCtrl::SetShowThumbnailDropDownButton(bool enable)
{ {
m_showThumbnailDropDown = enable; m_showThumbnailDropDownButton = enable;
} }
bool PropertyAssetCtrl::GetShowThumbnailDropDown() const bool PropertyAssetCtrl::GetShowThumbnailDropDownButton() const
{ {
return m_showThumbnailDropDown; return m_showThumbnailDropDownButton;
}
void PropertyAssetCtrl::SetThumbnailCallback(EditCallbackType* editNotifyCallback)
{
m_thumbnailCallback = editNotifyCallback;
} }
const AZ::Uuid& AssetPropertyHandlerDefault::GetHandledType() const const AZ::Uuid& AssetPropertyHandlerDefault::GetHandledType() const
@@ -1187,7 +1205,16 @@ namespace AzToolsFramework
{ {
(void)debugName; (void)debugName;
if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1)) if (attrib == AZ_CRC_CE("AssetPickerTitle"))
{
AZStd::string title;
attrValue->Read<AZStd::string>(title);
if (!title.empty())
{
GUI->SetTitle(title.c_str());
}
}
else if (attrib == AZ_CRC("EditCallback", 0xb74f2ee1))
{ {
PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute()); PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute());
if (func) if (func)
@@ -1277,23 +1304,21 @@ namespace AzToolsFramework
} }
else if (attrib == AZ_CRC_CE("Thumbnail")) else if (attrib == AZ_CRC_CE("Thumbnail"))
{ {
bool showThumbnail = false; GUI->SetShowThumbnail(true);
if (attrValue->Read<bool>(showThumbnail))
{
GUI->SetShowThumbnail(showThumbnail);
}
} }
else if (attrib == AZ_CRC_CE("ThumbnailWithDropDown")) else if (attrib == AZ_CRC_CE("ThumbnailCallback"))
{ {
PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute()); PropertyAssetCtrl::EditCallbackType* func = azdynamic_cast<PropertyAssetCtrl::EditCallbackType*>(attrValue->GetAttribute());
if (func) if (func)
{ {
GUI->SetShowThumbnailDropDown(true); GUI->SetShowThumbnail(true);
GUI->SetEditNotifyCallback(func); GUI->SetShowThumbnailDropDownButton(true);
GUI->SetThumbnailCallback(func);
} }
else else
{ {
GUI->SetEditNotifyCallback(nullptr); GUI->SetShowThumbnailDropDownButton(false);
GUI->SetThumbnailCallback(nullptr);
} }
} }
} }
@@ -45,7 +45,7 @@ namespace AzToolsFramework
{ {
class AssetCompleterModel; class AssetCompleterModel;
class AssetCompleterListView; class AssetCompleterListView;
class ThumbnailDropDown; class ThumbnailPropertyCtrl;
namespace Thumbnailer namespace Thumbnailer
{ {
@@ -89,14 +89,14 @@ namespace AzToolsFramework
void dragLeaveEvent(QDragLeaveEvent* event) override; void dragLeaveEvent(QDragLeaveEvent* event) override;
void dropEvent(QDropEvent* event) override; void dropEvent(QDropEvent* event) override;
virtual AssetSelectionModel GetAssetSelectionModel() { return AssetSelectionModel::AssetTypeSelection(GetCurrentAssetType()); } virtual AssetSelectionModel GetAssetSelectionModel();
signals: signals:
void OnAssetIDChanged(AZ::Data::AssetId newAssetID); void OnAssetIDChanged(AZ::Data::AssetId newAssetID);
protected: protected:
ThumbnailDropDown* m_thumbnailDropDown = nullptr; QString m_title;
Thumbnailer::ThumbnailWidget* m_thumbnail = nullptr; ThumbnailPropertyCtrl* m_thumbnail = nullptr;
QPushButton* m_errorButton = nullptr; QPushButton* m_errorButton = nullptr;
QToolButton* m_editButton = nullptr; QToolButton* m_editButton = nullptr;
@@ -157,8 +157,8 @@ namespace AzToolsFramework
bool m_showProductAssetName = true; bool m_showProductAssetName = true;
bool m_showThumbnail = false; bool m_showThumbnail = false;
bool m_showThumbnailDropDownButton = false;
bool m_showThumbnailDropDown = false; EditCallbackType* m_thumbnailCallback = nullptr;
// ! Default suffix used in the field's placeholder text when a default value is set. // ! Default suffix used in the field's placeholder text when a default value is set.
const char* m_DefaultSuffix = " (default)"; const char* m_DefaultSuffix = " (default)";
@@ -192,6 +192,7 @@ namespace AzToolsFramework
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
public slots: public slots:
void SetTitle(const QString& title);
void SetEditNotifyTarget(void* editNotifyTarget); void SetEditNotifyTarget(void* editNotifyTarget);
void SetEditNotifyCallback(EditCallbackType* editNotifyCallback); // This is meant to be used with the "EditCallback" Attribute void SetEditNotifyCallback(EditCallbackType* editNotifyCallback); // This is meant to be used with the "EditCallback" Attribute
void SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback); // This is meant to be used with the "ClearNotify" Attribute void SetClearNotifyCallback(ClearCallbackType* clearNotifyCallback); // This is meant to be used with the "ClearNotify" Attribute
@@ -209,8 +210,9 @@ namespace AzToolsFramework
void SetShowThumbnail(bool enable); void SetShowThumbnail(bool enable);
bool GetShowThumbnail() const; bool GetShowThumbnail() const;
void SetShowThumbnailDropDown(bool enable); void SetShowThumbnailDropDownButton(bool enable);
bool GetShowThumbnailDropDown() const; bool GetShowThumbnailDropDownButton() const;
void SetThumbnailCallback(EditCallbackType* editNotifyCallback);
void SetSelectedAssetID(const AZ::Data::AssetId& newID); void SetSelectedAssetID(const AZ::Data::AssetId& newID);
void SetCurrentAssetType(const AZ::Data::AssetType& newType); void SetCurrentAssetType(const AZ::Data::AssetType& newType);
@@ -222,6 +224,7 @@ namespace AzToolsFramework
void UpdateAssetDisplay(); void UpdateAssetDisplay();
void OnLineEditFocus(bool focus); void OnLineEditFocus(bool focus);
virtual void OnEditButtonClicked(); virtual void OnEditButtonClicked();
void OnThumbnailClicked();
void OnCompletionModelReset(); void OnCompletionModelReset();
void OnAutocomplete(const QModelIndex& index); void OnAutocomplete(const QModelIndex& index);
void OnTextChange(const QString& text); void OnTextChange(const QString& text);
@@ -19,12 +19,14 @@ AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // 4251: 'QRawFon
#include <QPainter> #include <QPainter>
#include <UI/UICore/AspectRatioAwarePixmapWidget.hxx> #include <UI/UICore/AspectRatioAwarePixmapWidget.hxx>
#include <Thumbnails/ThumbnailWidget.h> #include <Thumbnails/ThumbnailWidget.h>
#include <QApplication>
AZ_POP_DISABLE_WARNING AZ_POP_DISABLE_WARNING
#include "ThumbnailDropDown.h" #include "ThumbnailPropertyCtrl.h"
namespace AzToolsFramework namespace AzToolsFramework
{ {
ThumbnailDropDown::ThumbnailDropDown(QWidget* parent)
ThumbnailPropertyCtrl::ThumbnailPropertyCtrl(QWidget* parent)
: QWidget(parent) : QWidget(parent)
{ {
QHBoxLayout* pLayout = new QHBoxLayout(); QHBoxLayout* pLayout = new QHBoxLayout();
@@ -37,6 +39,7 @@ namespace AzToolsFramework
m_dropDownArrow = new AspectRatioAwarePixmapWidget(this); m_dropDownArrow = new AspectRatioAwarePixmapWidget(this);
m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png")); m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png"));
m_dropDownArrow->setFixedSize(QSize(8, 24)); m_dropDownArrow->setFixedSize(QSize(8, 24));
ShowDropDownArrow(false);
m_emptyThumbnail = new QLabel(this); m_emptyThumbnail = new QLabel(this);
m_emptyThumbnail->setPixmap(QPixmap(":/stylesheet/img/line.png")); m_emptyThumbnail->setPixmap(QPixmap(":/stylesheet/img/line.png"));
@@ -51,19 +54,33 @@ namespace AzToolsFramework
setLayout(pLayout); setLayout(pLayout);
} }
void ThumbnailDropDown::SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName) void ThumbnailPropertyCtrl::SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName)
{ {
m_key = key;
m_emptyThumbnail->setVisible(false); m_emptyThumbnail->setVisible(false);
m_thumbnail->SetThumbnailKey(key, contextName); m_thumbnail->SetThumbnailKey(key, contextName);
} }
void ThumbnailDropDown::ClearThumbnail() void ThumbnailPropertyCtrl::ClearThumbnail()
{ {
m_emptyThumbnail->setVisible(true); m_emptyThumbnail->setVisible(true);
m_thumbnail->ClearThumbnail(); m_thumbnail->ClearThumbnail();
} }
bool ThumbnailDropDown::event(QEvent* e) void ThumbnailPropertyCtrl::ShowDropDownArrow(bool visible)
{
if (visible)
{
setFixedSize(QSize(40, 24));
}
else
{
setFixedSize(QSize(24, 24));
}
m_dropDownArrow->setVisible(visible);
}
bool ThumbnailPropertyCtrl::event(QEvent* e)
{ {
if (isEnabled()) if (isEnabled())
{ {
@@ -77,7 +94,7 @@ namespace AzToolsFramework
return QWidget::event(e); return QWidget::event(e);
} }
void ThumbnailDropDown::paintEvent(QPaintEvent* e) void ThumbnailPropertyCtrl::paintEvent(QPaintEvent* e)
{ {
QPainter p(this); QPainter p(this);
QRect targetRect(QPoint(), QSize(40, 24)); QRect targetRect(QPoint(), QSize(40, 24));
@@ -85,17 +102,32 @@ namespace AzToolsFramework
QWidget::paintEvent(e); QWidget::paintEvent(e);
} }
void ThumbnailDropDown::enterEvent(QEvent* e) void ThumbnailPropertyCtrl::enterEvent(QEvent* e)
{ {
m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0_highlighted.png")); m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0_highlighted.png"));
if (!m_thumbnailEnlarged && m_key)
{
QPoint position = mapToGlobal(pos() - QPoint(185, 0));
QSize size(180, 180);
m_thumbnailEnlarged.reset(new Thumbnailer::ThumbnailWidget());
m_thumbnailEnlarged->setFixedSize(size);
m_thumbnailEnlarged->move(position);
m_thumbnailEnlarged->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
m_thumbnailEnlarged->SetThumbnailKey(m_key);
m_thumbnailEnlarged->show();
}
QWidget::enterEvent(e); QWidget::enterEvent(e);
} }
void ThumbnailDropDown::leaveEvent(QEvent* e) void ThumbnailPropertyCtrl::leaveEvent(QEvent* e)
{ {
m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png")); m_dropDownArrow->setPixmap(QPixmap(":/stylesheet/img/triangle0.png"));
if (m_thumbnailEnlarged)
{
m_thumbnailEnlarged.reset();
}
QWidget::leaveEvent(e); QWidget::leaveEvent(e);
} }
} }
#include "UI/PropertyEditor/moc_ThumbnailDropDown.cpp" #include "UI/PropertyEditor/moc_ThumbnailPropertyCtrl.cpp"
@@ -30,17 +30,20 @@ namespace AzToolsFramework
class ThumbnailWidget; class ThumbnailWidget;
} }
class ThumbnailDropDown : public QWidget //! Used by PropertyAssetCtrl to display thumbnail preview of the asset as well as additional drop-down actions
class ThumbnailPropertyCtrl : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ThumbnailDropDown(QWidget* parent = nullptr); explicit ThumbnailPropertyCtrl(QWidget* parent = nullptr);
//! Call this to set what thumbnail widget will display //! Call this to set what thumbnail widget will display
void SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName = "Default"); void SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName = "Default");
//! Remove current thumbnail //! Remove current thumbnail
void ClearThumbnail(); void ClearThumbnail();
void ShowDropDownArrow(bool visible);
bool event(QEvent* e) override; bool event(QEvent* e) override;
Q_SIGNALS: Q_SIGNALS:
@@ -52,7 +55,9 @@ namespace AzToolsFramework
void leaveEvent(QEvent* e) override; void leaveEvent(QEvent* e) override;
private: private:
Thumbnailer::SharedThumbnailKey m_key;
Thumbnailer::ThumbnailWidget* m_thumbnail = nullptr; Thumbnailer::ThumbnailWidget* m_thumbnail = nullptr;
QScopedPointer<Thumbnailer::ThumbnailWidget> m_thumbnailEnlarged;
QLabel* m_emptyThumbnail = nullptr; QLabel* m_emptyThumbnail = nullptr;
AspectRatioAwarePixmapWidget* m_dropDownArrow = nullptr; AspectRatioAwarePixmapWidget* m_dropDownArrow = nullptr;
}; };
@@ -417,8 +417,8 @@ set(FILES
UI/PropertyEditor/GrowTextEdit.cpp UI/PropertyEditor/GrowTextEdit.cpp
UI/PropertyEditor/MultiLineTextEditHandler.h UI/PropertyEditor/MultiLineTextEditHandler.h
UI/PropertyEditor/MultiLineTextEditHandler.cpp UI/PropertyEditor/MultiLineTextEditHandler.cpp
UI/PropertyEditor/ThumbnailDropDown.h UI/PropertyEditor/ThumbnailPropertyCtrl.h
UI/PropertyEditor/ThumbnailDropDown.cpp UI/PropertyEditor/ThumbnailPropertyCtrl.cpp
UI/Slice/SlicePushWidget.cpp UI/Slice/SlicePushWidget.cpp
UI/Slice/SlicePushWidget.hxx UI/Slice/SlicePushWidget.hxx
UI/Slice/SliceOverridesNotificationWindow.cpp UI/Slice/SliceOverridesNotificationWindow.cpp
@@ -652,6 +652,7 @@ set(FILES
Prefab/PrefabPublicHandler.h Prefab/PrefabPublicHandler.h
Prefab/PrefabPublicHandler.cpp Prefab/PrefabPublicHandler.cpp
Prefab/PrefabPublicInterface.h Prefab/PrefabPublicInterface.h
Prefab/PrefabPublicNotificationBus.h
Prefab/PrefabUndo.h Prefab/PrefabUndo.h
Prefab/PrefabUndo.cpp Prefab/PrefabUndo.cpp
Prefab/PrefabUndoCache.cpp Prefab/PrefabUndoCache.cpp
@@ -687,7 +688,6 @@ set(FILES
UI/Outliner/EntityOutlinerDisplayOptionsMenu.cpp UI/Outliner/EntityOutlinerDisplayOptionsMenu.cpp
UI/Outliner/EntityOutlinerTreeView.hxx UI/Outliner/EntityOutlinerTreeView.hxx
UI/Outliner/EntityOutlinerTreeView.cpp UI/Outliner/EntityOutlinerTreeView.cpp
UI/Outliner/EntityOutlinerWidgetInterface.h
UI/Outliner/EntityOutlinerWidget.hxx UI/Outliner/EntityOutlinerWidget.hxx
UI/Outliner/EntityOutlinerWidget.cpp UI/Outliner/EntityOutlinerWidget.cpp
UI/Outliner/EntityOutlinerCacheBus.h UI/Outliner/EntityOutlinerCacheBus.h
@@ -1,187 +1,64 @@
/* /*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or
* a third party where indicated. * a third party where indicated.
* *
* For complete copyright and license terms please see the LICENSE at the root of this * For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License, * distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not * or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* *
*/ */
#include "EditorDefs.h" #include "EditorDefs.h"
#include "PropertyMotionCtrl.h" #include "PropertyMotionCtrl.h"
// Qt
#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>
// AzToolsFramework // AzToolsFramework
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h> #include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
QWidget* MotionPropertyWidgetHandler::CreateGUI(QWidget* pParent)
MotionPropertyCtrl::MotionPropertyCtrl(QWidget *pParent)
: QWidget(pParent)
{ {
m_motionLabel = new QLabel; AzToolsFramework::PropertyAssetCtrl* newCtrl = aznew AzToolsFramework::PropertyAssetCtrl(pParent);
connect(
m_pBrowseButton = new QToolButton; newCtrl, &AzToolsFramework::PropertyAssetCtrl::OnAssetIDChanged, this, [newCtrl]([[maybe_unused]] AZ::Data::AssetId newAssetId) {
m_pBrowseButton->setIcon(QIcon(":/reflectedPropertyCtrl/img/file_browse.png")); EBUS_EVENT(AzToolsFramework::PropertyEditorGUIMessages::Bus, RequestWrite, newCtrl);
m_pApplyButton = new QToolButton; AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(
m_pApplyButton->setIcon(QIcon(":/reflectedPropertyCtrl/img/apply.png")); &AzToolsFramework::PropertyEditorGUIMessages::Bus::Handler::OnEditingFinished, newCtrl);
});
m_pApplyButton->setFocusPolicy(Qt::StrongFocus);
m_pBrowseButton->setFocusPolicy(Qt::StrongFocus);
QHBoxLayout *pLayout = new QHBoxLayout(this);
pLayout->setContentsMargins(0, 0, 0, 0);
pLayout->addWidget(m_motionLabel, 1);
pLayout->addWidget(m_pBrowseButton);
pLayout->addWidget(m_pApplyButton);
connect(m_pBrowseButton, &QAbstractButton::clicked, this, &MotionPropertyCtrl::OnBrowseClicked);
connect(m_pApplyButton, &QAbstractButton::clicked, this, &MotionPropertyCtrl::OnApplyClicked);
};
MotionPropertyCtrl::~MotionPropertyCtrl()
{
}
void MotionPropertyCtrl::SetValue(const CReflectedVarMotion &motion)
{
m_motion = motion;
SetLabelText(motion.m_motion);
}
CReflectedVarMotion MotionPropertyCtrl::value() const
{
return m_motion;
}
void MotionPropertyCtrl::OnBrowseClicked()
{
static AZ::Data::AssetType emotionFXMotionAssetType("{00494B8E-7578-4BA2-8B28-272E90680787}"); // from MotionAsset.h in EMotionFX Gem
// Request the AssetBrowser Dialog and set a type filter
AssetSelectionModel selection = AssetSelectionModel::AssetTypeSelection(emotionFXMotionAssetType);
selection.SetSelectedAssetId(m_motion.m_assetId);
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
if (selection.IsValid())
{
auto product = azrtti_cast<const ProductAssetBrowserEntry*>(selection.GetResult());
if (product != nullptr)
{
m_motion.m_motion = product->GetRelativePath();
m_motion.m_assetId = product->GetAssetId();
SetLabelText(m_motion.m_motion);
emit ValueChanged(m_motion);
}
}
}
// TODO: Might be able to delete this function
void MotionPropertyCtrl::OnApplyClicked()
{
#if 0
CUIEnumerations &roGeneralProxy = CUIEnumerations::GetUIEnumerationsInstance();
QStringList cSelectedMotions;
size_t nTotalMotions(0);
size_t nCurrentMotion(0);
QString combinedString = GetIEditor()->GetResourceSelectorHost()->GetGlobalSelection("motion");
SplitString(combinedString, cSelectedMotions, ',');
nTotalMotions = cSelectedMotions.size();
for (nCurrentMotion = 0; nCurrentMotion < nTotalMotions; ++nCurrentMotion)
{
QString& rstrCurrentAnimAction = cSelectedMotions[nCurrentMotion];
if (!rstrCurrentAnimAction.isEmpty())
{
m_motion.m_motion = rstrCurrentAnimAction.toLatin1().data();
SetLabelText(m_motion.m_motion);
emit ValueChanged(m_motion);
}
}
#endif
}
QWidget* MotionPropertyCtrl::GetFirstInTabOrder()
{
return m_pBrowseButton;
}
QWidget* MotionPropertyCtrl::GetLastInTabOrder()
{
return m_pApplyButton;
}
void MotionPropertyCtrl::UpdateTabOrder()
{
setTabOrder(m_pBrowseButton, m_pApplyButton);
}
void MotionPropertyCtrl::SetLabelText(const AZStd::string& motion)
{
if (!motion.empty())
{
AZStd::string filename;
if (AzFramework::StringFunc::Path::GetFileName(motion.c_str(), filename))
{
m_motionLabel->setText(filename.c_str());
}
else
{
m_motionLabel->setText(motion.c_str());
}
}
else
{
m_motionLabel->setText("");
}
}
QWidget* MotionPropertyWidgetHandler::CreateGUI(QWidget *pParent)
{
MotionPropertyCtrl* newCtrl = aznew MotionPropertyCtrl(pParent);
connect(newCtrl, &MotionPropertyCtrl::ValueChanged, newCtrl, [newCtrl]()
{
EBUS_EVENT(AzToolsFramework::PropertyEditorGUIMessages::Bus, RequestWrite, newCtrl);
});
return newCtrl; return newCtrl;
} }
void MotionPropertyWidgetHandler::ConsumeAttribute(
void MotionPropertyWidgetHandler::ConsumeAttribute(MotionPropertyCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) [[maybe_unused]] AzToolsFramework::PropertyAssetCtrl* GUI, [[maybe_unused]] AZ::u32 attrib,
[[maybe_unused]] AzToolsFramework::PropertyAttributeReader* attrValue, [[maybe_unused]] const char* debugName)
{ {
Q_UNUSED(GUI);
Q_UNUSED(attrib);
Q_UNUSED(attrValue);
Q_UNUSED(debugName);
} }
void MotionPropertyWidgetHandler::WriteGUIValuesIntoProperty(size_t index, MotionPropertyCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) void MotionPropertyWidgetHandler::WriteGUIValuesIntoProperty(
[[maybe_unused]] size_t index, [[maybe_unused]] AzToolsFramework::PropertyAssetCtrl* GUI, property_t& instance,
[[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
{ {
Q_UNUSED(index); CReflectedVarMotion val;
Q_UNUSED(node); val.m_motion = GUI->GetCurrentAssetHint();
CReflectedVarMotion val = GUI->value(); val.m_assetId = GUI->GetSelectedAssetID();
instance = static_cast<property_t>(val); instance = static_cast<property_t>(val);
} }
bool MotionPropertyWidgetHandler::ReadValuesIntoGUI(size_t index, MotionPropertyCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) bool MotionPropertyWidgetHandler::ReadValuesIntoGUI(
[[maybe_unused]] size_t index, [[maybe_unused]] AzToolsFramework::PropertyAssetCtrl* GUI, const property_t& instance,
[[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
{ {
Q_UNUSED(index); static const AZ::Data::AssetType emotionFXMotionAssetType(
Q_UNUSED(node); "{00494B8E-7578-4BA2-8B28-272E90680787}"); // from MotionAsset.h in EMotionFX Gem
CReflectedVarMotion val = instance;
GUI->SetValue(val); GUI->blockSignals(true);
GUI->SetSelectedAssetID(instance.m_assetId);
GUI->SetCurrentAssetType(emotionFXMotionAssetType);
GUI->blockSignals(false);
return false; return false;
} }
#include <Controls/ReflectedPropertyControl/moc_PropertyMotionCtrl.cpp> #include <Controls/ReflectedPropertyControl/moc_PropertyMotionCtrl.cpp>
@@ -1,92 +1,67 @@
/* /*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors. * its licensors.
* *
* For complete copyright and license terms please see the LICENSE at the root of this * For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License, * distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not * or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* *
*/ */
#ifndef CRYINCLUDE_EDITOR_UTILS_PROPERTYMOTIONCTRL_H
#define CRYINCLUDE_EDITOR_UTILS_PROPERTYMOTIONCTRL_H
#pragma once #pragma once
#if !defined(Q_MOC_RUN) #if !defined(Q_MOC_RUN)
#include <AzCore/base.h>
#include <AzCore/Memory/SystemAllocator.h>
#include "ReflectedVar.h" #include "ReflectedVar.h"
#include <QWidget> #include <AzCore/Memory/SystemAllocator.h>
#include <QPointer> #include <AzCore/base.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx>
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h> #include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
#include <QPointer>
#include <QWidget>
#endif #endif
class QToolButton; class MotionPropertyWidgetHandler : QObject,
class QLabel; public AzToolsFramework::PropertyHandler<CReflectedVarMotion, AzToolsFramework::PropertyAssetCtrl>
class QHBoxLayout;
namespace AzToolsFramework
{
class PropertyAssetCtrl;
}
class MotionPropertyCtrl
: public QWidget
{ {
Q_OBJECT Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(MotionPropertyCtrl, AZ::SystemAllocator, 0);
MotionPropertyCtrl(QWidget* pParent = nullptr);
virtual ~MotionPropertyCtrl();
CReflectedVarMotion value() const;
QWidget* GetFirstInTabOrder();
QWidget* GetLastInTabOrder();
void UpdateTabOrder();
signals:
void ValueChanged(CReflectedVarMotion value);
public slots:
void SetValue(const CReflectedVarMotion& motion);
protected slots:
void OnBrowseClicked();
void OnApplyClicked();
private:
void SetLabelText(const AZStd::string& motion);
QToolButton* m_pBrowseButton;
QToolButton* m_pApplyButton;
QLabel* m_motionLabel;
CReflectedVarMotion m_motion;
};
class MotionPropertyWidgetHandler
: QObject
, public AzToolsFramework::PropertyHandler < CReflectedVarMotion, MotionPropertyCtrl >
{
public: public:
AZ_CLASS_ALLOCATOR(MotionPropertyWidgetHandler, AZ::SystemAllocator, 0); AZ_CLASS_ALLOCATOR(MotionPropertyWidgetHandler, AZ::SystemAllocator, 0);
virtual AZ::u32 GetHandlerName(void) const override { return AZ_CRC("Motion", 0xf5fea1e8); } virtual AZ::u32 GetHandlerName(void) const override
virtual bool IsDefaultHandler() const override { return true; } {
virtual QWidget* GetFirstInTabOrder(MotionPropertyCtrl* widget) override { return widget->GetFirstInTabOrder(); } return AZ_CRC("Motion", 0xf5fea1e8);
virtual QWidget* GetLastInTabOrder(MotionPropertyCtrl* widget) override { return widget->GetLastInTabOrder(); } }
virtual void UpdateWidgetInternalTabbing(MotionPropertyCtrl* widget) override { widget->UpdateTabOrder(); }
virtual bool IsDefaultHandler() const override
{
return true;
}
virtual QWidget* GetFirstInTabOrder(AzToolsFramework::PropertyAssetCtrl* widget) override
{
return widget->GetFirstInTabOrder();
}
virtual QWidget* GetLastInTabOrder(AzToolsFramework::PropertyAssetCtrl* widget) override
{
return widget->GetLastInTabOrder();
}
virtual void UpdateWidgetInternalTabbing(AzToolsFramework::PropertyAssetCtrl* widget) override
{
widget->UpdateTabOrder();
}
virtual QWidget* CreateGUI(QWidget* pParent) override; virtual QWidget* CreateGUI(QWidget* pParent) override;
virtual void ConsumeAttribute(MotionPropertyCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override; virtual void ConsumeAttribute(
virtual void WriteGUIValuesIntoProperty(size_t index, MotionPropertyCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override; AzToolsFramework::PropertyAssetCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue,
virtual bool ReadValuesIntoGUI(size_t index, MotionPropertyCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) override; const char* debugName) override;
virtual void WriteGUIValuesIntoProperty(
size_t index, AzToolsFramework::PropertyAssetCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override;
virtual bool ReadValuesIntoGUI(
size_t index, AzToolsFramework::PropertyAssetCtrl* GUI, const property_t& instance,
AzToolsFramework::InstanceDataNode* node) override;
}; };
#endif // CRYINCLUDE_EDITOR_UTILS_PROPERTYMOTIONCTRL_H
+4 -1
View File
@@ -2428,7 +2428,10 @@ void EditorViewportWidget::SetDefaultCamera()
return; return;
} }
ResetToViewSourceType(ViewSourceType::None); ResetToViewSourceType(ViewSourceType::None);
gEnv->p3DEngine->GetPostEffectBaseGroup()->SetParam("Dof_Active", 0.0f); if (gEnv->p3DEngine)
{
gEnv->p3DEngine->GetPostEffectBaseGroup()->SetParam("Dof_Active", 0.0f);
}
GetViewManager()->SetCameraObjectId(m_cameraObjectId); GetViewManager()->SetCameraObjectId(m_cameraObjectId);
SetName(m_defaultViewName); SetName(m_defaultViewName);
SetViewTM(m_defaultViewTM); SetViewTM(m_defaultViewTM);
-11
View File
@@ -33,7 +33,6 @@
#include "Util/CryMemFile.h" #include "Util/CryMemFile.h"
#include "Objects/ObjectManager.h" #include "Objects/ObjectManager.h"
#include "Objects/ObjectPhysicsManager.h"
#include "Objects/EntityObject.h" #include "Objects/EntityObject.h"
#include "LensFlareEditor/LensFlareManager.h" #include "LensFlareEditor/LensFlareManager.h"
#include "LensFlareEditor/LensFlareLibrary.h" #include "LensFlareEditor/LensFlareLibrary.h"
@@ -192,14 +191,6 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
} }
} }
////////////////////////////////////////////////////////////////////////
// Inform all objects that an export is about to begin
////////////////////////////////////////////////////////////////////////
if (exportSuccessful)
{
GetIEditor()->GetObjectManager()->GetPhysicsManager()->PrepareForExport();
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Export all data to the game // Export all data to the game
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -519,8 +510,6 @@ void CGameExporter::ExportMapInfo(XmlNodeRef& node)
CXmlArchive xmlAr; CXmlArchive xmlAr;
xmlAr.bLoading = false; xmlAr.bLoading = false;
xmlAr.root = node; xmlAr.root = node;
GetIEditor()->GetObjectManager()->GetPhysicsManager()->SerializeCollisionClasses(xmlAr);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -24,7 +24,6 @@ class CUsedResources;
class CSelectionGroup; class CSelectionGroup;
class CObjectClassDesc; class CObjectClassDesc;
class CObjectArchive; class CObjectArchive;
class CObjectPhysicsManager;
class CViewport; class CViewport;
struct HitContext; struct HitContext;
enum class ImageRotationDegrees; enum class ImageRotationDegrees;
@@ -247,10 +246,6 @@ public:
virtual IGizmoManager* GetGizmoManager() = 0; virtual IGizmoManager* GetGizmoManager() = 0;
//////////////////////////////////////////////////////////////////////////
//! Get acess to object physics manager
virtual CObjectPhysicsManager* GetPhysicsManager() = 0;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//! Invalidate visibily settings of objects. //! Invalidate visibily settings of objects.
virtual void InvalidateVisibleList() = 0; virtual void InvalidateVisibleList() = 0;
@@ -25,7 +25,6 @@
#include "Viewport.h" #include "Viewport.h"
#include "GizmoManager.h" #include "GizmoManager.h"
#include "AxisGizmo.h" #include "AxisGizmo.h"
#include "ObjectPhysicsManager.h"
#include "GameEngine.h" #include "GameEngine.h"
#include "WaitProgress.h" #include "WaitProgress.h"
#include "Util/Image.h" #include "Util/Image.h"
@@ -109,7 +108,6 @@ CObjectManager::CObjectManager()
, m_pLoadProgress(nullptr) , m_pLoadProgress(nullptr)
, m_loadedObjects(0) , m_loadedObjects(0)
, m_totalObjectsToLoad(0) , m_totalObjectsToLoad(0)
, m_pPhysicsManager(new CObjectPhysicsManager())
, m_bExiting(false) , m_bExiting(false)
, m_isUpdateVisibilityList(false) , m_isUpdateVisibilityList(false)
, m_currentHideCount(CBaseObject::s_invalidHiddenID) , m_currentHideCount(CBaseObject::s_invalidHiddenID)
@@ -138,7 +136,6 @@ CObjectManager::~CObjectManager()
DeleteAllObjects(); DeleteAllObjects();
delete m_gizmoManager; delete m_gizmoManager;
delete m_pPhysicsManager;
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -841,8 +838,6 @@ void CObjectManager::Update()
{ {
prevActiveWindow->setFocus(); prevActiveWindow->setFocus();
} }
m_pPhysicsManager->Update();
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -334,9 +334,6 @@ public:
virtual void FindAndRenameProperty2(const char* property2Name, const QString& oldValue, const QString& newValue); virtual void FindAndRenameProperty2(const char* property2Name, const QString& oldValue, const QString& newValue);
virtual void FindAndRenameProperty2If(const char* property2Name, const QString& oldValue, const QString& newValue, const char* otherProperty2Name, const QString& otherValue); virtual void FindAndRenameProperty2If(const char* property2Name, const QString& oldValue, const QString& newValue, const char* otherProperty2Name, const QString& otherValue);
class CObjectPhysicsManager* GetPhysicsManager()
{ return m_pPhysicsManager; }
bool IsReloading() const { return m_bInReloading; } bool IsReloading() const { return m_bInReloading; }
void SetSkipUpdate(bool bSkipUpdate) override { m_bSkipObjectUpdate = bSkipUpdate; } void SetSkipUpdate(bool bSkipUpdate) override { m_bSkipObjectUpdate = bSkipUpdate; }
@@ -433,8 +430,6 @@ private:
int m_totalObjectsToLoad; int m_totalObjectsToLoad;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
class CObjectPhysicsManager* m_pPhysicsManager;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Numbering for names. // Numbering for names.
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -1,191 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "ObjectPhysicsManager.h"
// Editor
#include "GameEngine.h"
#include "Commands/CommandManager.h"
#include "Objects/SelectionGroup.h"
#include "Include/IObjectManager.h"
#include "CryPhysicsDeprecation.h"
#define MAX_OBJECTS_PHYS_SIMULATION_TIME (5)
//////////////////////////////////////////////////////////////////////////
CObjectPhysicsManager::CObjectPhysicsManager()
{
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "simulate_objects", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_SimulateObjects, this));
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "reset_objects_state", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_ResetPhysicsState, this));
CommandManagerHelper::RegisterCommand(GetIEditor()->GetCommandManager(),
"physics", "get_objects_state", "", "",
AZStd::bind(&CObjectPhysicsManager::Command_GetPhysicsState, this));
m_fStartObjectSimulationTime = 0;
m_bSimulatingObjects = false;
m_wasSimObjects = 0;
}
//////////////////////////////////////////////////////////////////////////
CObjectPhysicsManager::~CObjectPhysicsManager()
{
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_SimulateObjects()
{
SimulateSelectedObjectsPositions();
}
/////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_ResetPhysicsState()
{
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
for (int i = 0; i < pSelection->GetCount(); i++)
{
pSelection->GetObject(i)->OnEvent(EVENT_PHYSICS_RESETSTATE);
}
}
/////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Command_GetPhysicsState()
{
CSelectionGroup* pSelection = GetIEditor()->GetSelection();
for (int i = 0; i < pSelection->GetCount(); i++)
{
pSelection->GetObject(i)->OnEvent(EVENT_PHYSICS_GETSTATE);
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::Update()
{
if (m_bSimulatingObjects)
{
UpdateSimulatingObjects();
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::SimulateSelectedObjectsPositions()
{
CSelectionGroup* pSel = GetIEditor()->GetObjectManager()->GetSelection();
if (pSel->IsEmpty())
{
return;
}
if (GetIEditor()->GetGameEngine()->GetSimulationMode())
{
return;
}
GetIEditor()->GetGameEngine()->SetSimulationMode(true, true);
m_simObjects.clear();
CRY_PHYSICS_REPLACEMENT_ASSERT();
m_wasSimObjects = m_simObjects.size();
m_fStartObjectSimulationTime = GetISystem()->GetITimer()->GetAsyncCurTime();
m_bSimulatingObjects = true;
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::UpdateSimulatingObjects()
{
{
CUndo undo("Simulate");
CRY_PHYSICS_REPLACEMENT_ASSERT();
}
float curTime = GetISystem()->GetITimer()->GetAsyncCurTime();
float runningTime = (curTime - m_fStartObjectSimulationTime);
if (m_simObjects.empty() || (runningTime > MAX_OBJECTS_PHYS_SIMULATION_TIME))
{
m_fStartObjectSimulationTime = 0;
m_bSimulatingObjects = false;
GetIEditor()->GetGameEngine()->SetSimulationMode(false, true);
}
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::PrepareForExport()
{
// Clear the collision class set, ready for objects to register
// their collision classes
m_collisionClasses.clear();
m_collisionClassExportId = 0;
// First collision-class IS always the default one
RegisterCollisionClass(SCollisionClass(0, 0));
}
//////////////////////////////////////////////////////////////////////////
bool operator == (const SCollisionClass& lhs, const SCollisionClass& rhs)
{
return lhs.type == rhs.type && lhs.ignore == rhs.ignore;
}
//////////////////////////////////////////////////////////////////////////
int CObjectPhysicsManager::RegisterCollisionClass(const SCollisionClass& collclass)
{
TCollisionClassVector::iterator it = std::find(m_collisionClasses.begin(), m_collisionClasses.end(), collclass);
if (it == m_collisionClasses.end())
{
m_collisionClasses.push_back(collclass);
return m_collisionClasses.size() - 1;
}
return it - m_collisionClasses.begin();
}
//////////////////////////////////////////////////////////////////////////
int CObjectPhysicsManager::GetCollisionClassId(const SCollisionClass& collclass)
{
TCollisionClassVector::iterator it = std::find(m_collisionClasses.begin(), m_collisionClasses.end(), collclass);
if (it == m_collisionClasses.end())
{
return 0;
}
return it - m_collisionClasses.begin();
}
//////////////////////////////////////////////////////////////////////////
void CObjectPhysicsManager::SerializeCollisionClasses(CXmlArchive& xmlAr)
{
if (!xmlAr.bLoading)
{
// Storing
CLogFile::WriteLine("Storing Collision Classes ...");
XmlNodeRef root = xmlAr.root->newChild("CollisionClasses");
int count = m_collisionClasses.size();
for (int i = 0; i < count; i++)
{
SCollisionClass& cc = m_collisionClasses[i];
XmlNodeRef xmlCC = root->newChild("CollisionClass");
xmlCC->setAttr("type", cc.type);
xmlCC->setAttr("ignore", cc.ignore);
}
}
}
@@ -1,56 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
#define CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
#pragma once
//////////////////////////////////////////////////////////////////////////
class CObjectPhysicsManager
{
public:
CObjectPhysicsManager();
~CObjectPhysicsManager();
void SimulateSelectedObjectsPositions();
void Update();
//////////////////////////////////////////////////////////////////////////
/// Collision Classes
//////////////////////////////////////////////////////////////////////////
int RegisterCollisionClass(const SCollisionClass& collclass);
int GetCollisionClassId(const SCollisionClass& collclass);
void SerializeCollisionClasses(CXmlArchive& xmlAr);
void PrepareForExport();
private:
void Command_SimulateObjects();
void Command_GetPhysicsState();
void Command_ResetPhysicsState();
void UpdateSimulatingObjects();
bool m_bSimulatingObjects;
float m_fStartObjectSimulationTime;
int m_wasSimObjects;
std::vector<_smart_ptr<CBaseObject> > m_simObjects;
typedef std::vector<SCollisionClass> TCollisionClassVector;
int m_collisionClassExportId;
TCollisionClassVector m_collisionClasses;
};
#endif // CRYINCLUDE_EDITOR_OBJECTS_OBJECTPHYSICSMANAGER_H
@@ -638,8 +638,6 @@ set(FILES
Objects/ObjectManager.h Objects/ObjectManager.h
Objects/ObjectManagerLegacyUndo.cpp Objects/ObjectManagerLegacyUndo.cpp
Objects/ObjectManagerLegacyUndo.h Objects/ObjectManagerLegacyUndo.h
Objects/ObjectPhysicsManager.cpp
Objects/ObjectPhysicsManager.h
Objects/DisplayContext.cpp Objects/DisplayContext.cpp
Objects/DisplayContext.h Objects/DisplayContext.h
Objects/EntityObject.cpp Objects/EntityObject.cpp
+1 -1
View File
@@ -13,6 +13,7 @@ add_subdirectory(SceneAPI) # Needs to go before AssetProcessor since it provides
add_subdirectory(AssetProcessor) add_subdirectory(AssetProcessor)
add_subdirectory(AWSNativeSDKInit) add_subdirectory(AWSNativeSDKInit)
add_subdirectory(AzTestRunner) add_subdirectory(AzTestRunner)
add_subdirectory(CrashHandler)
add_subdirectory(CryCommonTools) add_subdirectory(CryCommonTools)
add_subdirectory(CryXML) add_subdirectory(CryXML)
add_subdirectory(HLSLCrossCompiler) add_subdirectory(HLSLCrossCompiler)
@@ -21,7 +22,6 @@ add_subdirectory(News)
add_subdirectory(PythonBindingsExample) add_subdirectory(PythonBindingsExample)
add_subdirectory(RC) add_subdirectory(RC)
add_subdirectory(RemoteConsole) add_subdirectory(RemoteConsole)
add_subdirectory(CrashHandler)
add_subdirectory(ShaderCacheGen) add_subdirectory(ShaderCacheGen)
add_subdirectory(DeltaCataloger) add_subdirectory(DeltaCataloger)
add_subdirectory(SerializeContextTools) add_subdirectory(SerializeContextTools)
+3 -5
View File
@@ -32,11 +32,11 @@ ly_add_target(
PRIVATE PRIVATE
${pal_dir} ${pal_dir}
BUILD_DEPENDENCIES BUILD_DEPENDENCIES
PUBLIC
AZ::CrashSupport
PRIVATE PRIVATE
3rdParty::Crashpad 3rdParty::Crashpad
AZ::AzCore
AZ::AzFramework AZ::AzFramework
AZ::CrashSupport
) )
string(REPLACE "." ";" version_list "${LY_VERSION_STRING}") string(REPLACE "." ";" version_list "${LY_VERSION_STRING}")
@@ -67,11 +67,9 @@ ly_add_target(
PRIVATE PRIVATE
Uploader/include/Uploader Uploader/include/Uploader
BUILD_DEPENDENCIES BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::CrashSupport
PUBLIC PUBLIC
3rdParty::Crashpad::Handler 3rdParty::Crashpad::Handler
AZ::CrashSupport
) )
add_subdirectory(Tools) add_subdirectory(Tools)
@@ -19,6 +19,6 @@ ly_add_target(
PUBLIC PUBLIC
include include
BUILD_DEPENDENCIES BUILD_DEPENDENCIES
PRIVATE PUBLIC
AZ::AzCore AZ::AzCore
) )
+3 -7
View File
@@ -21,13 +21,13 @@ ly_add_target(
tools_crash_handler_files.cmake tools_crash_handler_files.cmake
Platform/${PAL_PLATFORM_NAME}/tools_crash_handler_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake Platform/${PAL_PLATFORM_NAME}/tools_crash_handler_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES
PRIVATE PUBLIC
. .
BUILD_DEPENDENCIES BUILD_DEPENDENCIES
PUBLIC
AZ::CrashHandler
PRIVATE PRIVATE
3rdParty::Qt::Core 3rdParty::Qt::Core
AZ::CrashHandler
AZ::CrashSupport
AZ::AzToolsFramework AZ::AzToolsFramework
) )
@@ -41,18 +41,14 @@ ly_add_target(
Platform/${PAL_PLATFORM_NAME}/tools_crash_uploader_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake Platform/${PAL_PLATFORM_NAME}/tools_crash_uploader_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES
PRIVATE PRIVATE
.
Uploader Uploader
BUILD_DEPENDENCIES BUILD_DEPENDENCIES
PRIVATE PRIVATE
3rdParty::Qt::Core 3rdParty::Qt::Core
3rdParty::Qt::Gui 3rdParty::Qt::Gui
3rdParty::Qt::Widgets 3rdParty::Qt::Widgets
3rdParty::Crashpad
3rdParty::Crashpad::Handler
AZ::CrashUploaderSupport AZ::CrashUploaderSupport
AZ::AzQtComponents AZ::AzQtComponents
AZ::CrashSupport
TARGET_PROPERTIES TARGET_PROPERTIES
Qt5_NO_LINK_QTMAIN TRUE Qt5_NO_LINK_QTMAIN TRUE
) )
@@ -138,7 +138,7 @@ namespace O3de
if (!logFileReader->Open(thisFile)) if (!logFileReader->Open(thisFile))
{ {
#if defined(AZ_PLATFORM_WINDOWS) #if defined(AZ_PLATFORM_WINDOWS)
LOG(ERROR) << "Failed to open " << base::UTF16ToUTF8(thisFile.BaseName().value()); LOG(ERROR) << "Failed to open " << base::WideToUTF8(thisFile.BaseName().value());
#else #else
LOG(ERROR) << "Failed to open " << thisFile.BaseName().value(); LOG(ERROR) << "Failed to open " << thisFile.BaseName().value();
#endif #endif
@@ -149,7 +149,7 @@ namespace O3de
if (start_offset < 0) if (start_offset < 0)
{ {
#if defined(AZ_PLATFORM_WINDOWS) #if defined(AZ_PLATFORM_WINDOWS)
LOG(ERROR) << "Failed to get offset for " << base::UTF16ToUTF8(thisFile.BaseName().value()); LOG(ERROR) << "Failed to get offset for " << base::WideToUTF8(thisFile.BaseName().value());
#else #else
LOG(ERROR) << "Failed to get offset for " << thisFile.BaseName().value(); LOG(ERROR) << "Failed to get offset for " << thisFile.BaseName().value();
#endif #endif
@@ -162,7 +162,7 @@ namespace O3de
std::string fileNameKey{ "attachment_" }; std::string fileNameKey{ "attachment_" };
#if defined(AZ_PLATFORM_WINDOWS) #if defined(AZ_PLATFORM_WINDOWS)
fileNameKey += base::UTF16ToUTF8(thisFile.BaseName().value()); fileNameKey += base::WideToUTF8(thisFile.BaseName().value());
#else #else
fileNameKey += thisFile.BaseName().value(); fileNameKey += thisFile.BaseName().value();
#endif #endif
@@ -197,6 +197,7 @@ namespace AZ
AzFramework::InputDeviceKeyboard::Key::EditSpace, // ImGuiKey_Space AzFramework::InputDeviceKeyboard::Key::EditSpace, // ImGuiKey_Space
AzFramework::InputDeviceKeyboard::Key::EditEnter, // ImGuiKey_Enter AzFramework::InputDeviceKeyboard::Key::EditEnter, // ImGuiKey_Enter
AzFramework::InputDeviceKeyboard::Key::Escape, // ImGuiKey_Escape AzFramework::InputDeviceKeyboard::Key::Escape, // ImGuiKey_Escape
AzFramework::InputDeviceKeyboard::Key::NumPadEnter, // ImGuiKey_KeyPadEnter
AzFramework::InputDeviceKeyboard::Key::AlphanumericA, // ImGuiKey_A AzFramework::InputDeviceKeyboard::Key::AlphanumericA, // ImGuiKey_A
AzFramework::InputDeviceKeyboard::Key::AlphanumericC, // ImGuiKey_C AzFramework::InputDeviceKeyboard::Key::AlphanumericC, // ImGuiKey_C
AzFramework::InputDeviceKeyboard::Key::AlphanumericV, // ImGuiKey_V AzFramework::InputDeviceKeyboard::Key::AlphanumericV, // ImGuiKey_V
@@ -118,6 +118,7 @@ namespace AZ
// set initial transform // set initial transform
mesh.m_transform = m_transformServiceFeatureProcessor->GetTransformForId(objectId); mesh.m_transform = m_transformServiceFeatureProcessor->GetTransformForId(objectId);
mesh.m_nonUniformScale = m_transformServiceFeatureProcessor->GetNonUniformScaleForId(objectId);
m_revision++; m_revision++;
m_subMeshCount += aznumeric_cast<uint32_t>(subMeshes.size()); m_subMeshCount += aznumeric_cast<uint32_t>(subMeshes.size());
@@ -34,6 +34,7 @@ namespace AZ
constexpr uint32_t StreamCountMax = 12; constexpr uint32_t StreamCountMax = 12;
constexpr uint32_t StreamChannelCountMax = 16; constexpr uint32_t StreamChannelCountMax = 16;
constexpr uint32_t DrawListTagCountMax = 64; constexpr uint32_t DrawListTagCountMax = 64;
constexpr uint32_t DrawFilterTagCountMax = 32;
constexpr uint32_t MultiSampleCustomLocationsCountMax = 16; constexpr uint32_t MultiSampleCustomLocationsCountMax = 16;
constexpr uint32_t MultiSampleCustomLocationGridSize = 16; constexpr uint32_t MultiSampleCustomLocationGridSize = 16;
constexpr uint32_t SubpassCountMax = 10; constexpr uint32_t SubpassCountMax = 10;
@@ -9,22 +9,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* *
*/ */
#pragma once #pragma once
#include <AzCore/Interface/Interface.h> #include <Atom/RHI/DrawItem.h>
#include <AzCore/Serialization/SerializeContext.h> #include <Atom/RHI/TagRegistry.h>
namespace AzToolsFramework namespace AZ
{ {
class EntityOutlinerWidgetInterface namespace RHI
{ {
public: using DrawFilterTagRegistry = TagRegistry<DrawFilterTag, Limits::Pipeline::DrawFilterTagCountMax>;
AZ_RTTI(EntityOutlinerWidgetInterface, "{30C0F252-EC84-4196-BF59-EB9E73B8ADCB}"); }
}
virtual void SetUpdatesEnabled(bool enable) = 0;
virtual void ExpandEntityChildren(AZ::EntityId entityId) = 0;
};
} // namespace AzToolsFramework
+27 -9
View File
@@ -11,6 +11,7 @@
*/ */
#pragma once #pragma once
#include <Atom/RHI.Reflect/Handle.h>
#include <Atom/RHI.Reflect/Limits.h> #include <Atom/RHI.Reflect/Limits.h>
#include <Atom/RHI/StreamBufferView.h> #include <Atom/RHI/StreamBufferView.h>
#include <Atom/RHI/IndexBufferView.h> #include <Atom/RHI/IndexBufferView.h>
@@ -152,36 +153,53 @@ namespace AZ
}; };
using DrawItemSortKey = int64_t; using DrawItemSortKey = int64_t;
struct DrawItemKeyPair // A filter associate to a DrawItem which can be used to filter the DrawItem when submitting to command list
using DrawFilterTag = Handle<uint8_t>;
using DrawFilterMask = uint32_t; // AZStd::bitset's impelmentation is too expensive.
constexpr uint32_t DrawFilterMaskDefaultValue = uint32_t(-1); // Default all bit to 1.
static_assert(sizeof(DrawFilterMask) * 8 >= Limits::Pipeline::DrawFilterTagCountMax, "DrawFilterMask doesn't have enough bits for maximum tag count");
struct DrawItemProperties
{ {
DrawItemKeyPair() = default; DrawItemProperties() = default;
DrawItemKeyPair(const DrawItem* item, DrawItemSortKey sortKey) DrawItemProperties(const DrawItem* item, DrawItemSortKey sortKey = 0, DrawFilterMask filterMask = DrawFilterMaskDefaultValue)
: m_item{item} : m_item{item}
, m_sortKey{sortKey} , m_sortKey{sortKey}
{} , m_drawFilterMask{filterMask}
{
}
bool operator == (const DrawItemKeyPair& rhs) const bool operator==(const DrawItemProperties& rhs) const
{ {
return m_item == rhs.m_item && return m_item == rhs.m_item &&
m_sortKey == rhs.m_sortKey && m_sortKey == rhs.m_sortKey &&
m_depth == rhs.m_depth; m_depth == rhs.m_depth &&
m_drawFilterMask == rhs.m_drawFilterMask
;
} }
bool operator != (const DrawItemKeyPair& rhs) const bool operator!=(const DrawItemProperties& rhs) const
{ {
return !(*this == rhs); return !(*this == rhs);
} }
bool operator < (const DrawItemKeyPair& rhs) const bool operator<(const DrawItemProperties& rhs) const
{ {
return m_sortKey < rhs.m_sortKey; return m_sortKey < rhs.m_sortKey;
} }
//! A pointer to the draw item
const DrawItem* m_item = nullptr; const DrawItem* m_item = nullptr;
//! A sorting key of this draw item which is used for sorting draw items in DrawList
// Check RHI::SortDrawList() function for detail
DrawItemSortKey m_sortKey = 0; DrawItemSortKey m_sortKey = 0;
//! A depth value this draw item which is used for sorting draw items in DrawList
//! Check RHI::SortDrawList() function for detail
float m_depth = 0.0f; float m_depth = 0.0f;
//! A filter mask which helps decide whether to submit this draw item to a Scope's command list or not
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
}; };
} }
@@ -39,8 +39,8 @@ namespace AZ
using DrawListTag = Handle<uint8_t>; using DrawListTag = Handle<uint8_t>;
using DrawListMask = AZStd::bitset<RHI::Limits::Pipeline::DrawListTagCountMax>; using DrawListMask = AZStd::bitset<RHI::Limits::Pipeline::DrawListTagCountMax>;
using DrawList = AZStd::vector<RHI::DrawItemKeyPair>; using DrawList = AZStd::vector<RHI::DrawItemProperties>;
using DrawListView = AZStd::array_view<RHI::DrawItemKeyPair>; using DrawListView = AZStd::array_view<RHI::DrawItemProperties>;
/// Contains a table of draw lists, indexed by the tag. /// Contains a table of draw lists, indexed by the tag.
using DrawListsByTag = AZStd::array<DrawList, RHI::Limits::Pipeline::DrawListTagCountMax>; using DrawListsByTag = AZStd::array<DrawList, RHI::Limits::Pipeline::DrawListTagCountMax>;
@@ -53,7 +53,7 @@ namespace AZ
/// Adds an individual draw item to the draw list associated with the provided tag. This will /// Adds an individual draw item to the draw list associated with the provided tag. This will
/// no-op if the tag is not present in the internal draw list mask. /// no-op if the tag is not present in the internal draw list mask.
void AddDrawItem(DrawListTag drawListTag, DrawItemKeyPair drawItemKeyPair); void AddDrawItem(DrawListTag drawListTag, DrawItemProperties drawItemProperties);
/// Coalesces the draw lists in preparation for access via GetList. This should /// Coalesces the draw lists in preparation for access via GetList. This should
/// be called from a single thread as a sync point between the append / consume phases. /// be called from a single thread as a sync point between the append / consume phases.
@@ -12,83 +12,12 @@
#pragma once #pragma once
#include <Atom/RHI/DrawList.h> #include <Atom/RHI/DrawList.h>
#include <AzCore/Name/Name.h> #include <Atom/RHI/TagRegistry.h>
#include <AzCore/std/smart_ptr/intrusive_base.h>
#include <AzCore/std/parallel/shared_mutex.h>
namespace AZ namespace AZ
{ {
namespace RHI namespace RHI
{ {
/** using DrawListTagRegistry = TagRegistry<DrawListTag, Limits::Pipeline::DrawListTagCountMax>;
* Allocates and registers draw list tags by name, allowing the user to acquire and find tags from names.
* The class is designed to map user-friendly tag names defined through content or higher level code to
* low-level tags, which are simple handles.
*
* Some notes about usage and design:
* - DrawListTag values represent indexes into a bitmask, which allows for fast comparison when filtering
* draw items into draw lists (see View::HasDrawListTag()).
* - Tags are reference counted, which means multiple calls to 'Acquire' with the same name will increment
* the internal reference count on the tag. This allows shared ownership between systems, if necessary.
* - FindTag is provided to search for a tag reference without taking ownership.
* - Names are case sensitive.
*/
class DrawListTagRegistry final
: public AZStd::intrusive_base
{
public:
AZ_CLASS_ALLOCATOR(DrawListTagRegistry, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(DrawListTagRegistry);
static Ptr<DrawListTagRegistry> Create();
/**
* Resets the registry back to an empty state. All references are released.
*/
void Reset();
/**
* Acquires a draw list tag from the provided name (case sensitive). If the tag already existed, it is ref-counted.
* Returns a valid tag on success; returns a null tag if the registry is at full capacity. You must
* call ReleaseTag() if successful.
*/
DrawListTag AcquireTag(const Name& drawListName);
/**
* Releases a reference to a tag. Tags are ref-counted, so it's necessary to maintain ownership of the
* tag and release when its no longer needed.
*/
void ReleaseTag(DrawListTag drawListTag);
/**
* Finds the tag associated with the provided name (case sensitive). If a tag exists with that name, the tag
* is returned. The reference count is NOT incremented on success; ownership is not passed to the user. If
* the tag does not exist, a null tag is returned.
*/
DrawListTag FindTag(const Name& drawListName) const;
/**
* Returns the name of the given DrawListTag, or empty string if the tag is not registered.
*/
Name GetName(DrawListTag tag) const;
/**
* Returns the number of allocated tags in the registry.
*/
size_t GetAllocatedTagCount() const;
private:
DrawListTagRegistry() = default;
struct Entry
{
Name m_name;
size_t m_refCount = 0;
};
mutable AZStd::shared_mutex m_mutex;
AZStd::array<Entry, Limits::Pipeline::DrawListTagCountMax> m_entriesByTag;
size_t m_allocatedTagCount = 0;
};
} }
} }
@@ -21,45 +21,48 @@ namespace AZ
namespace RHI namespace RHI
{ {
/** //!
* DrawPacket is a packed data structure (one contiguous allocation) containing a collection of //! DrawPacket is a packed data structure (one contiguous allocation) containing a collection of
* DrawItems and their associated array data. Each draw item in the packet is associated //! DrawItems and their associated array data. Each draw item in the packet is associated
* with a DrawListTag. All draw items in the packet share the same set of shader resource //! with a DrawListTag. All draw items in the packet share the same set of shader resource
* groups, index buffer, and draw arguments. //! groups, index buffer, one DrawFilterMask, and draw arguments.
* //!
* Some notes about design and usage: //! Some notes about design and usage:
* - Draw packets should be used to 'broadcast' variations of the same 'object' to multiple passes. //! - Draw packets should be used to 'broadcast' variations of the same 'object' to multiple passes.
* For example: 'Shadow', 'Depth', 'Forward'. //! For example: 'Shadow', 'Depth', 'Forward'.
* //!
* - Draw packets can be re-used between different views, scenes, or passes. The embedded shader resource groups //! - Draw packets can be re-used between different views, scenes, or passes. The embedded shader resource groups
* should represent only the local data necessary to describe the 'object', not the full context including //! should represent only the local data necessary to describe the 'object', not the full context including
* scene / view / pass specific state. They serve as a 'template'. //! scene / view / pass specific state. They serve as a 'template'.
* //!
* - The packet is self-contained and does not reference external memory. Use DrawPacketBuilder to construct //! - The packet is self-contained and does not reference external memory. Use DrawPacketBuilder to construct
* an instance and either store in an RHI::Ptr or call 'delete' to release. //! an instance and either store in an RHI::Ptr or call 'delete' to release.
*/ //!
class DrawPacket final : public AZStd::intrusive_base class DrawPacket final : public AZStd::intrusive_base
{ {
friend class DrawPacketBuilder; friend class DrawPacketBuilder;
public: public:
using DrawItemVisitor = AZStd::function<void(DrawListTag, DrawItemKeyPair)>; using DrawItemVisitor = AZStd::function<void(DrawListTag, DrawItemProperties)>;
/// Draw packets cannot be move constructed or copied, as they contain an additional memory payload. //! Draw packets cannot be move constructed or copied, as they contain an additional memory payload.
AZ_DISABLE_COPY_MOVE(DrawPacket); AZ_DISABLE_COPY_MOVE(DrawPacket);
/// Returns the mask representing all the draw lists affected by the packet. //! Returns the mask representing all the draw lists affected by the packet.
DrawListMask GetDrawListMask() const; DrawListMask GetDrawListMask() const;
/// Returns the number of draw items stored in the packet. //! Returns the number of draw items stored in the packet.
size_t GetDrawItemCount() const; size_t GetDrawItemCount() const;
/// Returns the draw item / sort key associated with the provided index. //! Returns the draw item and its properties associated with the provided index.
DrawItemKeyPair GetDrawItem(size_t index) const; DrawItemProperties GetDrawItem(size_t index) const;
/// Returns the draw list tag associated with the provided index. //! Returns the draw list tag associated with the provided index.
DrawListTag GetDrawListTag(size_t index) const; DrawListTag GetDrawListTag(size_t index) const;
/// Overloaded operator delete for freeing a draw packet. //! Returns the draw filter mask which applied to all the draw items.
DrawFilterMask GetDrawFilterMask() const;
//! Overloaded operator delete for freeing a draw packet.
void operator delete(void* p, size_t size); void operator delete(void* p, size_t size);
private: private:
@@ -72,6 +75,9 @@ namespace AZ
// The bit-mask of all active filter tags. // The bit-mask of all active filter tags.
DrawListMask m_drawListMask = 0; DrawListMask m_drawListMask = 0;
// The draw filter applies to each draw item
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
// The index buffer view used when the draw call is indexed. // The index buffer view used when the draw call is indexed.
IndexBufferView m_indexBufferView; IndexBufferView m_indexBufferView;
@@ -29,23 +29,26 @@ namespace AZ
{ {
DrawRequest() = default; DrawRequest() = default;
/// The filter tag used to direct the draw item. //! The filter tag used to direct the draw item.
DrawListTag m_listTag; DrawListTag m_listTag;
/// The stencil ref value used for this draw item. //! The stencil ref value used for this draw item.
uint8_t m_stencilRef = 0; uint8_t m_stencilRef = 0;
/// The array of stream buffers to bind for this draw item. //! The array of stream buffers to bind for this draw item.
AZStd::array_view<StreamBufferView> m_streamBufferViews; AZStd::array_view<StreamBufferView> m_streamBufferViews;
/// Shader resource group unique for this draw request //! Shader resource group unique for this draw request
const ShaderResourceGroup* m_uniqueShaderResourceGroup = nullptr; const ShaderResourceGroup* m_uniqueShaderResourceGroup = nullptr;
/// The pipeline state assigned to this draw item. //! The pipeline state assigned to this draw item.
const PipelineState* m_pipelineState = nullptr; const PipelineState* m_pipelineState = nullptr;
/// The sort key assigned to this draw item. //! The sort key assigned to this draw item.
DrawItemSortKey m_sortKey = 0; DrawItemSortKey m_sortKey = 0;
//! The filter associated to this draw item.
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
}; };
// NOTE: This is configurable; just used to control the amount of memory held by the builder. // NOTE: This is configurable; just used to control the amount of memory held by the builder.
@@ -69,6 +72,8 @@ namespace AZ
void AddShaderResourceGroup(const ShaderResourceGroup* shaderResourceGroup); void AddShaderResourceGroup(const ShaderResourceGroup* shaderResourceGroup);
void SetDrawFilterMask(DrawFilterMask filterMask);
void AddDrawItem(const DrawRequest& request); void AddDrawItem(const DrawRequest& request);
const DrawPacket* End(); const DrawPacket* End();
@@ -79,6 +84,7 @@ namespace AZ
IAllocatorAllocate* m_allocator = nullptr; IAllocatorAllocate* m_allocator = nullptr;
DrawArguments m_drawArguments; DrawArguments m_drawArguments;
DrawListMask m_drawListMask = 0; DrawListMask m_drawListMask = 0;
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
size_t m_streamBufferViewCount = 0; size_t m_streamBufferViewCount = 0;
IndexBufferView m_indexBufferView; IndexBufferView m_indexBufferView;
AZStd::fixed_vector<DrawRequest, DrawItemCountMax> m_drawRequests; AZStd::fixed_vector<DrawRequest, DrawItemCountMax> m_drawRequests;
@@ -15,13 +15,13 @@
#include <AzCore/Name/Name.h> #include <AzCore/Name/Name.h>
#include <AzCore/EBus/EBus.h> #include <AzCore/EBus/EBus.h>
#include <Atom/RHI.Reflect/FrameSchedulerEnums.h> #include <Atom/RHI.Reflect/FrameSchedulerEnums.h>
#include <Atom/RHI/DrawListTagRegistry.h>
namespace AZ namespace AZ
{ {
namespace RHI namespace RHI
{ {
class Device; class Device;
class DrawListTagRegistry;
class FrameGraphBuilder; class FrameGraphBuilder;
class PipelineState; class PipelineState;
class PipelineStateCache; class PipelineStateCache;
@@ -0,0 +1,188 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Name/Name.h>
#include <AzCore/std/smart_ptr/intrusive_base.h>
#include <AzCore/std/parallel/shared_mutex.h>
namespace AZ
{
namespace RHI
{
//!
//! Allocates and registers tags by name, allowing the user to acquire and find tags from names.
//! The class is designed to map user-friendly tag names defined through content or higher level code to
//! low-level tags, which are simple handles.
//!
//! Some notes about usage and design:
//! - TagType need to be a Handle<Integer> type.
//! - Tags are reference counted, which means multiple calls to 'Acquire' with the same name will increment
//! the internal reference count on the tag. This allows shared ownership between systems, if necessary.
//! - FindTag is provided to search for a tag reference without taking ownership.
//! - Names are case sensitive.
//!
template<typename TagType, size_t MaxTagCount>
class TagRegistry final
: public AZStd::intrusive_base
{
public:
AZ_CLASS_ALLOCATOR(TagRegistry, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(TagRegistry);
static Ptr<TagRegistry> Create();
//! Resets the registry back to an empty state. All references are released.
void Reset();
//! Acquires a tag from the provided name (case sensitive). If the tag already existed, it is ref-counted.
//! Returns a valid tag on success; returns a null tag if the registry is at full capacity. You must
//! call ReleaseTag() if successful.
TagType AcquireTag(const Name& tagName);
//! Releases a reference to a tag. Tags are ref-counted, so it's necessary to maintain ownership of the
//! tag and release when its no longer needed.
void ReleaseTag(TagType tagName);
//! Finds the tag associated with the provided name (case sensitive). If a tag exists with that name, the tag
//! is returned. The reference count is NOT incremented on success; ownership is not passed to the user. If
//! the tag does not exist, a null tag is returned.
TagType FindTag(const Name& tagName) const;
//! Returns the name of the given tag, or empty string if the tag is not registered.
Name GetName(TagType tag) const;
//! Returns the number of allocated tags in the registry.
size_t GetAllocatedTagCount() const;
private:
TagRegistry() = default;
struct Entry
{
Name m_name;
size_t m_refCount = 0;
};
mutable AZStd::shared_mutex m_mutex;
AZStd::array<Entry, MaxTagCount> m_entriesByTag;
size_t m_allocatedTagCount = 0;
};
template<typename TagType, size_t MaxTagCount>
Ptr<TagRegistry<TagType, MaxTagCount>> TagRegistry<TagType, MaxTagCount>::Create()
{
return aznew TagRegistry<TagType, MaxTagCount>();
}
template<typename TagType, size_t MaxTagCount>
void TagRegistry<TagType, MaxTagCount>::Reset()
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
m_entriesByTag.fill({});
m_allocatedTagCount = 0;
}
template<typename TagType, size_t MaxTagCount>
TagType TagRegistry<TagType, MaxTagCount>::AcquireTag(const Name& tagName)
{
if (tagName.IsEmpty())
{
return {};
}
TagType tag;
Entry* foundEmptyEntry = nullptr;
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
Entry& entry = m_entriesByTag[i];
// Found an empty entry. Cache off the tag and pointer, but keep searching to find if
// another entry holds the same name.
if (entry.m_refCount == 0 && !foundEmptyEntry)
{
foundEmptyEntry = &entry;
tag = TagType(i);
}
else if (entry.m_name == tagName)
{
entry.m_refCount++;
return TagType(i);
}
}
// No other entry holds the name, so allocate the empty entry.
if (foundEmptyEntry)
{
foundEmptyEntry->m_refCount = 1;
foundEmptyEntry->m_name = tagName;
++m_allocatedTagCount;
}
return tag;
}
template<typename TagType, size_t MaxTagCount>
void TagRegistry<TagType, MaxTagCount>::ReleaseTag(TagType tag)
{
if (tag.IsValid())
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
Entry& entry = m_entriesByTag[tag.GetIndex()];
const size_t refCount = --entry.m_refCount;
AZ_Assert(
refCount != static_cast<size_t>(-1), "Attempted to forfeit a tag that is not valid. Tag{%d},Name{'%s'}", tag,
entry.m_name.GetCStr());
if (refCount == 0)
{
entry.m_name = Name();
--m_allocatedTagCount;
}
}
}
template<typename TagType, size_t MaxTagCount>
TagType TagRegistry<TagType, MaxTagCount>::FindTag(const Name& tagName) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
if (m_entriesByTag[i].m_name == tagName)
{
return TagType(i);
}
}
return {};
}
template<typename TagType, size_t MaxTagCount>
Name TagRegistry<TagType, MaxTagCount>::GetName(TagType tag) const
{
if (tag.GetIndex() < m_entriesByTag.size())
{
return m_entriesByTag[tag.GetIndex()].m_name;
}
else
{
return Name();
}
}
template<typename TagType, size_t MaxTagCount>
size_t TagRegistry<TagType, MaxTagCount>::GetAllocatedTagCount() const
{
return m_allocatedTagCount;
}
}
}
+4 -8
View File
@@ -35,8 +35,7 @@ namespace AZ
switch (sortType) switch (sortType)
{ {
case DrawListSortType::KeyThenDepth: case DrawListSortType::KeyThenDepth:
AZStd::sort(drawList.begin(), drawList.end(), AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
{ {
if (a.m_sortKey != b.m_sortKey) if (a.m_sortKey != b.m_sortKey)
{ {
@@ -48,8 +47,7 @@ namespace AZ
break; break;
case DrawListSortType::KeyThenReverseDepth: case DrawListSortType::KeyThenReverseDepth:
AZStd::sort(drawList.begin(), drawList.end(), AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
{ {
if (a.m_sortKey != b.m_sortKey) if (a.m_sortKey != b.m_sortKey)
{ {
@@ -61,8 +59,7 @@ namespace AZ
break; break;
case DrawListSortType::DepthThenKey: case DrawListSortType::DepthThenKey:
AZStd::sort(drawList.begin(), drawList.end(), AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
{ {
if (a.m_depth != b.m_depth) if (a.m_depth != b.m_depth)
{ {
@@ -74,8 +71,7 @@ namespace AZ
break; break;
case DrawListSortType::ReverseDepthThenKey: case DrawListSortType::ReverseDepthThenKey:
AZStd::sort(drawList.begin(), drawList.end(), AZStd::sort(drawList.begin(), drawList.end(), [](const DrawItemProperties& a, const DrawItemProperties& b)
[](const DrawItemKeyPair& a, const DrawItemKeyPair& b)
{ {
if (a.m_depth != b.m_depth) if (a.m_depth != b.m_depth)
{ {
@@ -63,14 +63,14 @@ namespace AZ
if (m_drawListMask[drawListTag.GetIndex()]) if (m_drawListMask[drawListTag.GetIndex()])
{ {
DrawItemKeyPair drawItem = drawPacket->GetDrawItem(i); DrawItemProperties drawItem = drawPacket->GetDrawItem(i);
drawItem.m_depth = depth; drawItem.m_depth = depth;
threadListsByTag[drawListTag.GetIndex()].push_back(drawItem); threadListsByTag[drawListTag.GetIndex()].push_back(drawItem);
} }
} }
} }
void DrawListContext::AddDrawItem(DrawListTag drawListTag, DrawItemKeyPair drawItemKeyPair) void DrawListContext::AddDrawItem(DrawListTag drawListTag, DrawItemProperties drawItemProperties)
{ {
if (Validation::IsEnabled()) if (Validation::IsEnabled())
{ {
@@ -84,7 +84,7 @@ namespace AZ
if (m_drawListMask[drawListTag.GetIndex()]) if (m_drawListMask[drawListTag.GetIndex()])
{ {
DrawListsByTag& drawListsByTag = m_threadListsByTag.GetStorage(); DrawListsByTag& drawListsByTag = m_threadListsByTag.GetStorage();
drawListsByTag[drawListTag.GetIndex()].push_back(drawItemKeyPair); drawListsByTag[drawListTag.GetIndex()].push_back(drawItemProperties);
} }
} }
@@ -1,117 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Atom/RHI/DrawListTagRegistry.h>
namespace AZ
{
namespace RHI
{
Ptr<DrawListTagRegistry> DrawListTagRegistry::Create()
{
return aznew DrawListTagRegistry;
}
void DrawListTagRegistry::Reset()
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
m_entriesByTag.fill({});
m_allocatedTagCount = 0;
}
DrawListTag DrawListTagRegistry::AcquireTag(const Name& drawListName)
{
if (drawListName.IsEmpty())
{
return {};
}
DrawListTag drawListTag;
Entry* foundEmptyEntry = nullptr;
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
Entry& entry = m_entriesByTag[i];
// Found an empty entry. Cache off the tag and pointer, but keep searching to find if
// another entry holds the same name.
if (entry.m_refCount == 0 && !foundEmptyEntry)
{
foundEmptyEntry = &entry;
drawListTag = DrawListTag(i);
}
else if (entry.m_name == drawListName)
{
entry.m_refCount++;
return DrawListTag(i);
}
}
// No other entry holds the name, so allocate the empty entry.
if (foundEmptyEntry)
{
foundEmptyEntry->m_refCount = 1;
foundEmptyEntry->m_name = drawListName;
++m_allocatedTagCount;
}
return drawListTag;
}
void DrawListTagRegistry::ReleaseTag(DrawListTag drawListTag)
{
if (drawListTag.IsValid())
{
AZStd::unique_lock<AZStd::shared_mutex> lock(m_mutex);
Entry& entry = m_entriesByTag[drawListTag.GetIndex()];
const size_t refCount = --entry.m_refCount;
AZ_Assert(refCount != static_cast<size_t>(-1), "Attempted to forfeit a tag that is not valid. Tag{%d},Name{'%s'}", drawListTag, entry.m_name.GetCStr());
if (refCount == 0)
{
entry.m_name = Name();
--m_allocatedTagCount;
}
}
}
DrawListTag DrawListTagRegistry::FindTag(const Name& drawListName) const
{
AZStd::shared_lock<AZStd::shared_mutex> lock(m_mutex);
for (size_t i = 0; i < m_entriesByTag.size(); ++i)
{
if (m_entriesByTag[i].m_name == drawListName)
{
return DrawListTag(i);
}
}
return {};
}
Name DrawListTagRegistry::GetName(DrawListTag tag) const
{
if (tag.GetIndex() < m_entriesByTag.size())
{
return m_entriesByTag[tag.GetIndex()].m_name;
}
else
{
return Name();
}
}
size_t DrawListTagRegistry::GetAllocatedTagCount() const
{
return m_allocatedTagCount;
}
}
}
+7 -2
View File
@@ -24,10 +24,10 @@ namespace AZ
return m_drawItemCount; return m_drawItemCount;
} }
DrawItemKeyPair DrawPacket::GetDrawItem(size_t index) const DrawItemProperties DrawPacket::GetDrawItem(size_t index) const
{ {
AZ_Assert(index < GetDrawItemCount(), "Out of bounds array access!"); AZ_Assert(index < GetDrawItemCount(), "Out of bounds array access!");
return DrawItemKeyPair(&m_drawItems[index], m_drawItemSortKeys[index]); return DrawItemProperties(&m_drawItems[index], m_drawItemSortKeys[index], m_drawFilterMask);
} }
DrawListTag DrawPacket::GetDrawListTag(size_t index) const DrawListTag DrawPacket::GetDrawListTag(size_t index) const
@@ -36,6 +36,11 @@ namespace AZ
return m_drawListTags[index]; return m_drawListTags[index];
} }
DrawFilterMask DrawPacket::GetDrawFilterMask() const
{
return m_drawFilterMask;
}
DrawListMask DrawPacket::GetDrawListMask() const DrawListMask DrawPacket::GetDrawListMask() const
{ {
return m_drawListMask; return m_drawListMask;
@@ -82,6 +82,11 @@ namespace AZ
} }
} }
void DrawPacketBuilder::SetDrawFilterMask(DrawFilterMask filterMask)
{
m_drawFilterMask = filterMask;
}
void DrawPacketBuilder::AddDrawItem(const DrawRequest& request) void DrawPacketBuilder::AddDrawItem(const DrawRequest& request)
{ {
if (request.m_listTag.IsValid()) if (request.m_listTag.IsValid())
@@ -165,6 +170,7 @@ namespace AZ
drawPacket->m_allocator = m_allocator; drawPacket->m_allocator = m_allocator;
drawPacket->m_indexBufferView = m_indexBufferView; drawPacket->m_indexBufferView = m_indexBufferView;
drawPacket->m_drawListMask = m_drawListMask; drawPacket->m_drawListMask = m_drawListMask;
drawPacket->m_drawFilterMask = m_drawFilterMask;
if (shaderResourceGroupsOffset.IsValid()) if (shaderResourceGroupsOffset.IsValid())
{ {
@@ -288,6 +294,7 @@ namespace AZ
m_rootConstants = {}; m_rootConstants = {};
m_scissors.clear(); m_scissors.clear();
m_viewports.clear(); m_viewports.clear();
m_drawFilterMask = DrawFilterMaskDefaultValue;
} }
} }
} }
+1 -2
View File
@@ -60,7 +60,7 @@ namespace AZ
AZ_Assert(false, "RHISystem", "Unable to initialize RHI! \n"); AZ_Assert(false, "RHISystem", "Unable to initialize RHI! \n");
return; return;
} }
m_drawListTagRegistry = RHI::DrawListTagRegistry::Create(); m_drawListTagRegistry = RHI::DrawListTagRegistry::Create();
m_pipelineStateCache = RHI::PipelineStateCache::Create(*m_device); m_pipelineStateCache = RHI::PipelineStateCache::Create(*m_device);
@@ -199,7 +199,6 @@ namespace AZ
m_frameScheduler.Shutdown(); m_frameScheduler.Shutdown();
m_platformLimitsDescriptor = nullptr; m_platformLimitsDescriptor = nullptr;
m_drawListTagRegistry = nullptr;
m_pipelineStateCache = nullptr; m_pipelineStateCache = nullptr;
m_device->PreShutdown(); m_device->PreShutdown();
AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count()); AZ_Assert(m_device->use_count()==1, "The ref count for Device is %i but it should be 1 here to ensure all the resources are released", m_device->use_count());
+3 -3
View File
@@ -80,11 +80,11 @@ namespace UnitTest
m_indexBufferView = RHI::IndexBufferView(*m_bufferEmpty, random.GetRandom(), random.GetRandom(), RHI::IndexFormat::Uint16); m_indexBufferView = RHI::IndexBufferView(*m_bufferEmpty, random.GetRandom(), random.GetRandom(), RHI::IndexFormat::Uint16);
} }
void ValidateDrawItem(const DrawItemData& drawItemData, RHI::DrawItemKeyPair itemKeyPair) const void ValidateDrawItem(const DrawItemData& drawItemData, RHI::DrawItemProperties itemProperties) const
{ {
const RHI::DrawItem* drawItem = itemKeyPair.m_item; const RHI::DrawItem* drawItem = itemProperties.m_item;
EXPECT_EQ(itemKeyPair.m_sortKey, drawItemData.m_sortKey); EXPECT_EQ(itemProperties.m_sortKey, drawItemData.m_sortKey);
EXPECT_EQ(drawItem->m_stencilRef, drawItemData.m_stencilRef); EXPECT_EQ(drawItem->m_stencilRef, drawItemData.m_stencilRef);
EXPECT_EQ(drawItem->m_pipelineState, drawItemData.m_pipelineState); EXPECT_EQ(drawItem->m_pipelineState, drawItemData.m_pipelineState);
@@ -36,6 +36,7 @@ set(FILES
Include/Atom/RHI/CopyItem.h Include/Atom/RHI/CopyItem.h
Include/Atom/RHI/ConstantsData.h Include/Atom/RHI/ConstantsData.h
Include/Atom/RHI/DispatchItem.h Include/Atom/RHI/DispatchItem.h
Include/Atom/RHI/DrawFilterTagRegistry.h
Include/Atom/RHI/DrawItem.h Include/Atom/RHI/DrawItem.h
Include/Atom/RHI/DrawList.h Include/Atom/RHI/DrawList.h
Include/Atom/RHI/DrawListTagRegistry.h Include/Atom/RHI/DrawListTagRegistry.h
@@ -48,7 +49,6 @@ set(FILES
Source/RHI/ConstantsData.cpp Source/RHI/ConstantsData.cpp
Source/RHI/DrawList.cpp Source/RHI/DrawList.cpp
Source/RHI/DrawListContext.cpp Source/RHI/DrawListContext.cpp
Source/RHI/DrawListTagRegistry.cpp
Source/RHI/DrawPacket.cpp Source/RHI/DrawPacket.cpp
Source/RHI/DrawPacketBuilder.cpp Source/RHI/DrawPacketBuilder.cpp
Include/Atom/RHI/Device.h Include/Atom/RHI/Device.h
@@ -201,4 +201,5 @@ set(FILES
Include/Atom/RHI/CpuProfiler.h Include/Atom/RHI/CpuProfiler.h
Include/Atom/RHI/CpuProfilerImpl.h Include/Atom/RHI/CpuProfilerImpl.h
Source/RHI/CpuProfilerImpl.cpp Source/RHI/CpuProfilerImpl.cpp
Include/Atom/RHI/TagRegistry.h
) )
@@ -214,6 +214,10 @@ namespace AZ
Scene* m_scene = nullptr; Scene* m_scene = nullptr;
RHI::DrawListTag m_drawListTag; RHI::DrawListTag m_drawListTag;
// All draw items use this filter when submit them to views
// It's set to RenderPipeline's draw filter mask if the DynamicDrawContext was created for a render pipeline.
RHI::DrawFilterMask m_drawFilter = RHI::DrawFilterMaskDefaultValue;
// Cached draw data // Cached draw data
AZStd::vector<RHI::StreamBufferView> m_cachedStreamBufferViews; AZStd::vector<RHI::StreamBufferView> m_cachedStreamBufferViews;
AZStd::vector<RHI::IndexBufferView> m_cachedIndexBufferViews; AZStd::vector<RHI::IndexBufferView> m_cachedIndexBufferViews;
@@ -56,9 +56,11 @@ namespace AZ
//! Draw calls which are made to this DynamicDrawContext will only be submitted for this scene. //! Draw calls which are made to this DynamicDrawContext will only be submitted for this scene.
//! The created DynamicDrawContext is managed by dynamic draw system. //! The created DynamicDrawContext is managed by dynamic draw system.
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) = 0; virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) = 0;
//! Create a DynamicDrawContext for specified pass //! Create a DynamicDrawContext for specified render pipeline
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Pass* pass = nullptr) = 0; //! Draw calls submitted through the context created by this function are only submitted
//! to the supplied render pipeline (viewport)
virtual RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(RenderPipeline* pipeline) = 0;
//! Get a DynamicBuffer from DynamicDrawSystem. //! Get a DynamicBuffer from DynamicDrawSystem.
//! The returned buffer will be invalidated every time the RPISystem's RenderTick is called //! The returned buffer will be invalidated every time the RPISystem's RenderTick is called
@@ -36,7 +36,7 @@ namespace AZ
// DynamicDrawInterface overrides... // DynamicDrawInterface overrides...
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) override; RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Scene* scene) override;
RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(Pass* pass) override; RHI::Ptr<DynamicDrawContext> CreateDynamicDrawContext(RenderPipeline* pipeline) override;
RHI::Ptr<DynamicBuffer> GetDynamicBuffer(uint32_t size, uint32_t alignment = 1) override; RHI::Ptr<DynamicBuffer> GetDynamicBuffer(uint32_t size, uint32_t alignment = 1) override;
void DrawGeometry(Data::Instance<Material> material, const GeometryData& geometry, ScenePtr scene) override; void DrawGeometry(Data::Instance<Material> material, const GeometryData& geometry, ScenePtr scene) override;
void AddDrawPacket(Scene* scene, AZStd::unique_ptr<const RHI::DrawPacket> drawPacket) override; void AddDrawPacket(Scene* scene, AZStd::unique_ptr<const RHI::DrawPacket> drawPacket) override;
@@ -184,6 +184,12 @@ namespace AZ
//! Get current render mode //! Get current render mode
RenderMode GetRenderMode() const; RenderMode GetRenderMode() const;
//! Get draw filter tag
RHI::DrawFilterTag GetDrawFilterTag() const;
//! Get draw filter mask
RHI::DrawFilterMask GetDrawFilterMask() const;
private: private:
RenderPipeline() = default; RenderPipeline() = default;
@@ -211,6 +217,8 @@ namespace AZ
// if the view already exists in map, its DrawListMask will be combined to the existing one's // if the view already exists in map, its DrawListMask will be combined to the existing one's
void CollectPersistentViews(AZStd::map<ViewPtr, RHI::DrawListMask>& outViewMasks) const; void CollectPersistentViews(AZStd::map<ViewPtr, RHI::DrawListMask>& outViewMasks) const;
void SetDrawFilterTag(RHI::DrawFilterTag);
// End of functions accessed by Scene class // End of functions accessed by Scene class
////////////////////////////////////////////////// //////////////////////////////////////////////////
@@ -250,6 +258,13 @@ namespace AZ
// Original settings from RenderPipelineDescriptor, used to revert active render settings to original settings from RenderPipelineDescriptor // Original settings from RenderPipelineDescriptor, used to revert active render settings to original settings from RenderPipelineDescriptor
PipelineRenderSettings m_originalRenderSettings; PipelineRenderSettings m_originalRenderSettings;
// A tag to filter draw items submitted by passes of this render pipeline.
// This tag is allocated when it's added to a scene. It's set to invalid when it's removed to the scene.
RHI::DrawFilterTag m_drawFilterTag;
// A mask to filter draw items submitted by passes of this render pipeline.
// This mask is created from the value of m_drawFilterTag.
RHI::DrawFilterMask m_drawFilterMask = 0;
}; };
} // namespace RPI } // namespace RPI
@@ -14,6 +14,7 @@
#include <Atom/RHI/DrawList.h> #include <Atom/RHI/DrawList.h>
#include <Atom/RHI/PipelineStateDescriptor.h> #include <Atom/RHI/PipelineStateDescriptor.h>
#include <Atom/RHI/DrawFilterTagRegistry.h>
#include <Atom/RHI.Reflect/FrameSchedulerEnums.h> #include <Atom/RHI.Reflect/FrameSchedulerEnums.h>
#include <Atom/RHI.Reflect/ShaderResourceGroupLayoutDescriptor.h> #include <Atom/RHI.Reflect/ShaderResourceGroupLayoutDescriptor.h>
#include <Atom/RPI.Reflect/System/SceneDescriptor.h> #include <Atom/RPI.Reflect/System/SceneDescriptor.h>
@@ -234,6 +235,9 @@ namespace AZ
// reference of dynamic draw system (from RPISystem) // reference of dynamic draw system (from RPISystem)
DynamicDrawSystem* m_dynamicDrawSystem = nullptr; DynamicDrawSystem* m_dynamicDrawSystem = nullptr;
// Registry which allocates draw filter tag for RenderPipeline
RHI::Ptr<RHI::DrawFilterTagRegistry> m_drawFilterTagRegistry;
}; };
// --- Template functions --- // --- Template functions ---
@@ -75,7 +75,7 @@ namespace AZ
void AddDrawPacket(const RHI::DrawPacket* drawPacket, Vector3 worldPosition); void AddDrawPacket(const RHI::DrawPacket* drawPacket, Vector3 worldPosition);
//! Add a draw item to this view with its associated draw list tag //! Add a draw item to this view with its associated draw list tag
void AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemKeyPair& drawItemKeyPair); void AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemProperties& drawItemProperties);
//! Sets the worldToView matrix and recalculates the other matrices. //! Sets the worldToView matrix and recalculates the other matrices.
void SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView); void SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView);
@@ -17,6 +17,7 @@
#include <Atom/RPI.Public/DynamicDraw/DynamicBuffer.h> #include <Atom/RPI.Public/DynamicDraw/DynamicBuffer.h>
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h> #include <Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h>
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h> #include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
#include <Atom/RPI.Public/RenderPipeline.h>
#include <Atom/RPI.Public/View.h> #include <Atom/RPI.Public/View.h>
@@ -601,10 +602,11 @@ namespace AZ
drawItemInfo.m_drawItem.m_streamBufferViews = &m_cachedStreamBufferViews[drawItemInfo.m_vertexBufferViewIndex]; drawItemInfo.m_drawItem.m_streamBufferViews = &m_cachedStreamBufferViews[drawItemInfo.m_vertexBufferViewIndex];
} }
RHI::DrawItemKeyPair drawItemKeyPair; RHI::DrawItemProperties drawItemProperties;
drawItemKeyPair.m_sortKey = sortKey; drawItemProperties.m_sortKey = sortKey;
drawItemKeyPair.m_item = &drawItemInfo.m_drawItem; drawItemProperties.m_item = &drawItemInfo.m_drawItem;
view->AddDrawItem(m_drawListTag, drawItemKeyPair); drawItemProperties.m_drawFilterMask = m_drawFilter;
view->AddDrawItem(m_drawListTag, drawItemProperties);
sortKey++; sortKey++;
} }
} }
@@ -59,6 +59,11 @@ namespace AZ
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(Scene* scene) RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(Scene* scene)
{ {
if (!scene)
{
AZ_Error("RPI", false, "Failed to create a DynamicDrawContext: the input scene is invalid");
return nullptr;
}
RHI::Ptr<DynamicDrawContext> drawContext = aznew DynamicDrawContext(); RHI::Ptr<DynamicDrawContext> drawContext = aznew DynamicDrawContext();
drawContext->m_scene = scene; drawContext->m_scene = scene;
@@ -67,11 +72,17 @@ namespace AZ
return drawContext; return drawContext;
} }
// [GFX TODO][ATOM-13185] Add support for creating DynamicDrawContext for Pass RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext(RenderPipeline* pipeline)
RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext([[maybe_unused]] Pass* pass)
{ {
AZ_Error("RPI", false, "Unimplemented function"); if (!pipeline || !pipeline->GetScene())
return nullptr; {
AZ_Error("RPI", false, "Failed to create a DynamicDrawContext: the input RenderPipeline is invalid or wasn't added to a Scene");
return nullptr;
}
auto context = CreateDynamicDrawContext(pipeline->GetScene());
context->m_drawFilter = pipeline->GetDrawFilterMask();
return context;
} }
// [GFX TODO][ATOM-13184] Add support of draw geometry with material for DynamicDrawSystemInterface // [GFX TODO][ATOM-13184] Add support of draw geometry with material for DynamicDrawSystemInterface
@@ -195,9 +195,12 @@ namespace AZ
SetSrgsForDraw(commandList); SetSrgsForDraw(commandList);
} }
for (const RHI::DrawItemKeyPair& drawItemKeyPair : drawListViewPartition) for (const RHI::DrawItemProperties& drawItemProperties : drawListViewPartition)
{ {
commandList->Submit(*drawItemKeyPair.m_item); if (drawItemProperties.m_drawFilterMask & m_pipeline->GetDrawFilterMask())
{
commandList->Submit(*drawItemProperties.m_item);
}
} }
} }
@@ -300,6 +300,9 @@ namespace AZ
m_scene = nullptr; m_scene = nullptr;
m_rootPass->SetEnabled(false); m_rootPass->SetEnabled(false);
m_rootPass->QueueForRemoval(); m_rootPass->QueueForRemoval();
m_drawFilterTag.Reset();
m_drawFilterMask = 0;
} }
void RenderPipeline::OnPassModified() void RenderPipeline::OnPassModified()
@@ -506,5 +509,28 @@ namespace AZ
{ {
return m_renderMode != RenderMode::NoRender; return m_renderMode != RenderMode::NoRender;
} }
RHI::DrawFilterTag RenderPipeline::GetDrawFilterTag() const
{
return m_drawFilterTag;
}
RHI::DrawFilterMask RenderPipeline::GetDrawFilterMask() const
{
return m_drawFilterMask;
}
void RenderPipeline::SetDrawFilterTag(RHI::DrawFilterTag tag)
{
m_drawFilterTag = tag;
if (m_drawFilterTag.IsValid())
{
m_drawFilterMask = 1 << tag.GetIndex();
}
else
{
m_drawFilterMask = 0;
}
}
} }
} }
@@ -87,6 +87,7 @@ namespace AZ
m_id = Uuid::CreateRandom(); m_id = Uuid::CreateRandom();
m_cullingScene = aznew CullingScene(); m_cullingScene = aznew CullingScene();
SceneRequestBus::Handler::BusConnect(m_id); SceneRequestBus::Handler::BusConnect(m_id);
m_drawFilterTagRegistry = RHI::DrawFilterTagRegistry::Create();
} }
Scene::~Scene() Scene::~Scene()
@@ -269,6 +270,8 @@ namespace AZ
return; return;
} }
pipeline->SetDrawFilterTag(m_drawFilterTagRegistry->AcquireTag(pipelineId));
m_pipelines.push_back(pipeline); m_pipelines.push_back(pipeline);
// Set this pipeline as default if the default pipeline was empty. This pipeline should be the first pipeline be added to the scene // Set this pipeline as default if the default pipeline was empty. This pipeline should be the first pipeline be added to the scene
@@ -303,6 +306,8 @@ namespace AZ
m_defaultPipeline = nullptr; m_defaultPipeline = nullptr;
} }
m_drawFilterTagRegistry->ReleaseTag(pipelineToRemove->GetDrawFilterTag());
pipelineToRemove->OnRemovedFromScene(this); pipelineToRemove->OnRemovedFromScene(this);
m_pipelines.erase(it); m_pipelines.erase(it);
@@ -90,9 +90,9 @@ namespace AZ
AddDrawPacket(drawPacket, depth); AddDrawPacket(drawPacket, depth);
} }
void View::AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemKeyPair& drawItemKeyPair) void View::AddDrawItem(RHI::DrawListTag drawListTag, const RHI::DrawItemProperties& drawItemProperties)
{ {
m_drawListContext.AddDrawItem(drawListTag, drawItemKeyPair); m_drawListContext.AddDrawItem(drawListTag, drawItemProperties);
} }
void View::SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView) void View::SetWorldToViewMatrix(const AZ::Matrix4x4& worldToView)
@@ -49,6 +49,7 @@ namespace AtomToolsFramework
AZ::Name m_id; AZ::Name m_id;
AZStd::string m_nameId; AZStd::string m_nameId;
AZStd::string m_displayName; AZStd::string m_displayName;
AZStd::string m_groupName;
AZStd::string m_description; AZStd::string m_description;
AZStd::any m_defaultValue; AZStd::any m_defaultValue;
AZStd::any m_parentValue; AZStd::any m_parentValue;
@@ -108,6 +109,8 @@ namespace AtomToolsFramework
private: private:
// Functions used to configure edit data attributes. // Functions used to configure edit data attributes.
AZStd::string GetDisplayName() const; AZStd::string GetDisplayName() const;
AZStd::string GetGroupName() const;
AZStd::string GetAssetPickerTitle() const;
AZStd::string GetDescription() const; AZStd::string GetDescription() const;
AZStd::vector<AZ::Edit::EnumConstant<uint32_t>> GetEnumValues() const; AZStd::vector<AZ::Edit::EnumConstant<uint32_t>> GetEnumValues() const;
@@ -135,6 +135,7 @@ namespace AtomToolsFramework
m_editData.m_elementId = AZ::Edit::UIHandlers::Default; m_editData.m_elementId = AZ::Edit::UIHandlers::Default;
AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::NameLabelOverride, &DynamicProperty::GetDisplayName); AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::NameLabelOverride, &DynamicProperty::GetDisplayName);
AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::AssetPickerTitle, &DynamicProperty::GetAssetPickerTitle);
AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::DescriptionTextOverride, &DynamicProperty::GetDescription); AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::DescriptionTextOverride, &DynamicProperty::GetDescription);
AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::ReadOnly, &DynamicProperty::IsReadOnly); AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::ReadOnly, &DynamicProperty::IsReadOnly);
AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::EnumValues, &DynamicProperty::GetEnumValues); AddEditDataAttributeMemberFunction(AZ::Edit::Attributes::EnumValues, &DynamicProperty::GetEnumValues);
@@ -197,6 +198,16 @@ namespace AtomToolsFramework
return !m_config.m_displayName.empty() ? m_config.m_displayName : m_config.m_nameId; return !m_config.m_displayName.empty() ? m_config.m_displayName : m_config.m_nameId;
} }
AZStd::string DynamicProperty::GetGroupName() const
{
return m_config.m_groupName;
}
AZStd::string DynamicProperty::GetAssetPickerTitle() const
{
return GetGroupName().empty() ? GetDisplayName() : GetGroupName() + " " + GetDisplayName();
}
AZStd::string DynamicProperty::GetDescription() const AZStd::string DynamicProperty::GetDescription() const
{ {
return AZStd::string::format("%s%s(Script Name = '%s')", return AZStd::string::format("%s%s(Script Name = '%s')",
@@ -773,6 +773,7 @@ namespace MaterialEditor
AtomToolsFramework::ConvertToPropertyConfig(propertyConfig, propertyDefinition); AtomToolsFramework::ConvertToPropertyConfig(propertyConfig, propertyDefinition);
propertyConfig.m_originalValue = AtomToolsFramework::ConvertToEditableType(m_materialAsset->GetPropertyValues()[propertyIndex.GetIndex()]); propertyConfig.m_originalValue = AtomToolsFramework::ConvertToEditableType(m_materialAsset->GetPropertyValues()[propertyIndex.GetIndex()]);
propertyConfig.m_parentValue = AtomToolsFramework::ConvertToEditableType(parentPropertyValues[propertyIndex.GetIndex()]); propertyConfig.m_parentValue = AtomToolsFramework::ConvertToEditableType(parentPropertyValues[propertyIndex.GetIndex()]);
propertyConfig.m_groupName = m_materialTypeSourceData.FindGroup(groupNameId)->m_displayName;
m_properties[propertyConfig.m_id] = AtomToolsFramework::DynamicProperty(propertyConfig); m_properties[propertyConfig.m_id] = AtomToolsFramework::DynamicProperty(propertyConfig);
} }
return true; return true;
@@ -789,6 +790,7 @@ namespace MaterialEditor
propertyConfig.m_id = "details.materialType"; propertyConfig.m_id = "details.materialType";
propertyConfig.m_nameId = "materialType"; propertyConfig.m_nameId = "materialType";
propertyConfig.m_displayName = "Material Type"; propertyConfig.m_displayName = "Material Type";
propertyConfig.m_groupName = "Details";
propertyConfig.m_description = propertyConfig.m_displayName; propertyConfig.m_description = propertyConfig.m_displayName;
propertyConfig.m_defaultValue = AZStd::any(materialTypeAsset); propertyConfig.m_defaultValue = AZStd::any(materialTypeAsset);
propertyConfig.m_originalValue = propertyConfig.m_defaultValue; propertyConfig.m_originalValue = propertyConfig.m_defaultValue;
@@ -802,6 +804,7 @@ namespace MaterialEditor
propertyConfig.m_id = "details.parentMaterial"; propertyConfig.m_id = "details.parentMaterial";
propertyConfig.m_nameId = "parentMaterial"; propertyConfig.m_nameId = "parentMaterial";
propertyConfig.m_displayName = "Parent Material"; propertyConfig.m_displayName = "Parent Material";
propertyConfig.m_groupName = "Details";
propertyConfig.m_description = propertyConfig.m_displayName; propertyConfig.m_description = propertyConfig.m_displayName;
propertyConfig.m_defaultValue = AZStd::any(parentMaterialAsset); propertyConfig.m_defaultValue = AZStd::any(parentMaterialAsset);
propertyConfig.m_originalValue = propertyConfig.m_defaultValue; propertyConfig.m_originalValue = propertyConfig.m_defaultValue;
@@ -822,6 +825,7 @@ namespace MaterialEditor
propertyConfig.m_id = MaterialPropertyId(UvGroupName, shaderInput).GetCStr(); propertyConfig.m_id = MaterialPropertyId(UvGroupName, shaderInput).GetCStr();
propertyConfig.m_nameId = shaderInput; propertyConfig.m_nameId = shaderInput;
propertyConfig.m_displayName = shaderInput; propertyConfig.m_displayName = shaderInput;
propertyConfig.m_groupName = "UV Names";
propertyConfig.m_description = shaderInput; propertyConfig.m_description = shaderInput;
propertyConfig.m_defaultValue = uvName; propertyConfig.m_defaultValue = uvName;
propertyConfig.m_originalValue = uvName; propertyConfig.m_originalValue = uvName;
@@ -41,7 +41,6 @@ namespace AZ
BuilderComponent::~BuilderComponent() BuilderComponent::~BuilderComponent()
{ {
AZ::Component::~Component();
AZ::Interface<AzFramework::AtomActiveInterface>::Unregister(this); AZ::Interface<AzFramework::AtomActiveInterface>::Unregister(this);
} }
@@ -203,6 +203,7 @@ namespace AZ
propertyConfig.m_id = AZ::RPI::MaterialPropertyId(groupNameId, shaderInputStr).GetCStr(); propertyConfig.m_id = AZ::RPI::MaterialPropertyId(groupNameId, shaderInputStr).GetCStr();
propertyConfig.m_nameId = shaderInputStr; propertyConfig.m_nameId = shaderInputStr;
propertyConfig.m_displayName = shaderInputStr; propertyConfig.m_displayName = shaderInputStr;
propertyConfig.m_groupName = groupDisplayName;
propertyConfig.m_description = shaderInputStr; propertyConfig.m_description = shaderInputStr;
propertyConfig.m_defaultValue = uvName; propertyConfig.m_defaultValue = uvName;
propertyConfig.m_originalValue = uvName; propertyConfig.m_originalValue = uvName;
@@ -247,6 +248,7 @@ namespace AZ
AtomToolsFramework::ConvertToPropertyConfig(propertyConfig, propertyDefinition); AtomToolsFramework::ConvertToPropertyConfig(propertyConfig, propertyDefinition);
propertyConfig.m_id = AZ::RPI::MaterialPropertyId(groupNameId, propertyDefinition.m_nameId).GetFullName(); propertyConfig.m_id = AZ::RPI::MaterialPropertyId(groupNameId, propertyDefinition.m_nameId).GetFullName();
propertyConfig.m_groupName = groupDisplayName;
const auto& propertyIndex = m_editData.m_materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(propertyConfig.m_id); const auto& propertyIndex = m_editData.m_materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(propertyConfig.m_id);
propertyConfig.m_defaultValue = AtomToolsFramework::ConvertToEditableType(m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]); propertyConfig.m_defaultValue = AtomToolsFramework::ConvertToEditableType(m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]);
propertyConfig.m_parentValue = AtomToolsFramework::ConvertToEditableType(m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]); propertyConfig.m_parentValue = AtomToolsFramework::ConvertToEditableType(m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]);
@@ -98,7 +98,7 @@ namespace AZ
->Attribute(AZ::Edit::Attributes::DefaultAsset, &EditorMaterialComponentSlot::GetDefaultAssetId) ->Attribute(AZ::Edit::Attributes::DefaultAsset, &EditorMaterialComponentSlot::GetDefaultAssetId)
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &EditorMaterialComponentSlot::GetLabel) ->Attribute(AZ::Edit::Attributes::NameLabelOverride, &EditorMaterialComponentSlot::GetLabel)
->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true) ->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true)
->Attribute("ThumbnailWithDropDown", &EditorMaterialComponentSlot::OpenPopupMenu) ->Attribute("ThumbnailCallback", &EditorMaterialComponentSlot::OpenPopupMenu)
; ;
} }
} }
@@ -95,14 +95,14 @@ namespace AZ
{ {
#if defined(IMGUI_ENABLED) #if defined(IMGUI_ENABLED)
InitializeViewportSizeIfNeeded(); InitializeViewportSizeIfNeeded();
ImGui::ImGuiManagerListenerBus::Broadcast(&ImGui::IImGuiManagerListener::Render); ImGui::ImGuiManagerBus::Broadcast(&ImGui::IImGuiManager::Render);
#endif #endif
} }
void ImguiAtomSystemComponent::OnViewportSizeChanged(AzFramework::WindowSize size) void ImguiAtomSystemComponent::OnViewportSizeChanged(AzFramework::WindowSize size)
{ {
#if defined(IMGUI_ENABLED) #if defined(IMGUI_ENABLED)
ImGui::ImGuiManagerListenerBus::Broadcast([this, size](ImGui::ImGuiManagerListenerBus::Events* imgui) ImGui::ImGuiManagerBus::Broadcast([this, size](ImGui::ImGuiManagerBus::Events* imgui)
{ {
imgui->OverrideRenderWindowSize(size.m_width, size.m_height); imgui->OverrideRenderWindowSize(size.m_width, size.m_height);
// ImGuiManagerListenerBus may not have been connected when this system component is activated // ImGuiManagerListenerBus may not have been connected when this system component is activated
@@ -57,7 +57,6 @@ namespace AZ
void OnRenderTick() override; void OnRenderTick() override;
void OnViewportSizeChanged(AzFramework::WindowSize size) override; void OnViewportSizeChanged(AzFramework::WindowSize size) override;
DebugConsole m_debugConsole;
bool m_initialized = false; bool m_initialized = false;
}; };
} // namespace LYIntegration } // namespace LYIntegration
-7
View File
@@ -30,9 +30,7 @@ ly_add_target(
Include Include
BUILD_DEPENDENCIES BUILD_DEPENDENCIES
PRIVATE PRIVATE
AZ::AzCore
AZ::CrashHandler AZ::CrashHandler
AZ::CrashSupport
) )
ly_add_target( ly_add_target(
@@ -46,10 +44,5 @@ ly_add_target(
Include Include
BUILD_DEPENDENCIES BUILD_DEPENDENCIES
PRIVATE PRIVATE
#3rdParty::Crashpad
#3rdParty::Crashpad::Handler
AZ::AzCore
AZ::CrashUploaderSupport AZ::CrashUploaderSupport
#AZ::CrashHandler
AZ::CrashSupport
) )
@@ -443,9 +443,12 @@ namespace DebugDraw
AZ::TransformBus::EventResult(sphereElement.m_worldLocation, sphereElement.m_targetEntityId, &AZ::TransformBus::Events::GetWorldTranslation); AZ::TransformBus::EventResult(sphereElement.m_worldLocation, sphereElement.m_targetEntityId, &AZ::TransformBus::Events::GetWorldTranslation);
} }
ColorB lyColor(sphereElement.m_color.ToU32()); if (gEnv->pRenderer)
Vec3 worldLocation(AZVec3ToLYVec3(sphereElement.m_worldLocation)); {
gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(worldLocation, sphereElement.m_radius, lyColor, true); ColorB lyColor(sphereElement.m_color.ToU32());
Vec3 worldLocation(AZVec3ToLYVec3(sphereElement.m_worldLocation));
gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(worldLocation, sphereElement.m_radius, lyColor, true);
}
} }
removeExpiredDebugElementsFromVector(m_activeSpheres); removeExpiredDebugElementsFromVector(m_activeSpheres);
@@ -303,7 +303,8 @@ namespace EMotionFX
if (GetFinalNode() == nodeToRemove) if (GetFinalNode() == nodeToRemove)
{ {
SetFinalNodeId(AnimGraphNodeId::InvalidId); m_finalNodeId = AnimGraphNodeId::InvalidId;
m_finalNode = nullptr;
} }
// call it for all children // call it for all children
+1 -1
View File
@@ -26,7 +26,7 @@ ly_add_target(
PRIVATE PRIVATE
Source Source
INTERFACE INTERFACE
../External/ImGui/v1.70 ../External/ImGui/v1.82
PUBLIC PUBLIC
Include Include
COMPILE_DEFINITIONS COMPILE_DEFINITIONS
+4 -4
View File
@@ -45,7 +45,7 @@ ImGuiViewportWidget::ImGuiViewportWidget(QWidget* parent)
ImGuiViewportWidget::~ImGuiViewportWidget() ImGuiViewportWidget::~ImGuiViewportWidget()
{ {
DestroyRenderContext(); DestroyRenderContext();
ImGuiManagerListenerBus::Broadcast(&IImGuiManagerListener::SetEditorWindowState, ImGuiManagerBus::Broadcast(&IImGuiManager::SetEditorWindowState,
DisplayState::Hidden); DisplayState::Hidden);
} }
@@ -68,7 +68,7 @@ bool ImGuiViewportWidget::CreateRenderContext()
editor->GetEnv()->pRenderer->CreateContext(window); editor->GetEnv()->pRenderer->CreateContext(window);
RestorePreviousContext(); RestorePreviousContext();
ImGuiManagerListenerBus::Broadcast(&IImGuiManagerListener::SetEditorWindowState, ImGuiManagerBus::Broadcast(&IImGuiManager::SetEditorWindowState,
DisplayState::Visible); DisplayState::Visible);
m_creatingRenderContext = false; m_creatingRenderContext = false;
@@ -154,8 +154,8 @@ void ImGuiViewportWidget::Render()
ColorF stateMessageColor(Col_Gray); ColorF stateMessageColor(Col_Gray);
AZStd::string stateMessage = "No State"; AZStd::string stateMessage = "No State";
DisplayState visibilityState = DisplayState::Hidden; DisplayState visibilityState = DisplayState::Hidden;
ImGuiManagerListenerBus::BroadcastResult(visibilityState, ImGuiManagerBus::BroadcastResult(visibilityState,
&IImGuiManagerListener::GetEditorWindowState); &IImGuiManager::GetEditorWindowState);
switch (visibilityState) switch (visibilityState)
{ {
case ImGui::DisplayState::Hidden: case ImGui::DisplayState::Hidden:
+14 -6
View File
@@ -68,13 +68,12 @@ namespace ImGui
typedef AZ::EBus<IImGuiUpdateListener> ImGuiUpdateListenerBus; typedef AZ::EBus<IImGuiUpdateListener> ImGuiUpdateListenerBus;
// Bus for sending events and getting state from the ImGui manager // Bus for sending events and getting state from the ImGui manager
class IImGuiManagerListener : public AZ::EBusTraits class IImGuiManager
{ {
public: public:
static const char* GetUniqueName() { return "IImGuiManagerListener"; } AZ_RTTI(IImGuiManager, "{F5A0F08B-F2DA-43B7-8CD2-C6FC71E1A712}");
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; static const char* GetUniqueName() { return "IImGuiManager"; }
using Bus = AZ::EBus<IImGuiManagerListener>;
virtual DisplayState GetEditorWindowState() const = 0; virtual DisplayState GetEditorWindowState() const = 0;
virtual void SetEditorWindowState(DisplayState state) = 0; virtual void SetEditorWindowState(DisplayState state) = 0;
@@ -94,7 +93,16 @@ namespace ImGui
virtual void RestoreRenderWindowSizeToDefault() = 0; virtual void RestoreRenderWindowSizeToDefault() = 0;
virtual void Render() = 0; virtual void Render() = 0;
}; };
typedef AZ::EBus<IImGuiManagerListener> ImGuiManagerListenerBus;
class IImGuiManagerRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
using Bus = AZ::EBus<IImGuiManager>;
};
using ImGuiManagerBus = AZ::EBus<IImGuiManager, IImGuiManagerRequests>;
// Bus for getting notifications from the IMGUI Entity Outliner // Bus for getting notifications from the IMGUI Entity Outliner
class IImGuiEntityOutlinerNotifcations : public AZ::EBusTraits class IImGuiEntityOutlinerNotifcations : public AZ::EBusTraits

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