diff --git a/Assets/Editor/Prefabs/Default_Level.prefab b/Assets/Editor/Prefabs/Default_Level.prefab index 64656e1e2f..d02d669f53 100644 --- a/Assets/Editor/Prefabs/Default_Level.prefab +++ b/Assets/Editor/Prefabs/Default_Level.prefab @@ -212,10 +212,10 @@ "Configuration": { "ModelAsset": { "assetId": { - "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}", - "subId": 277333723 + "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}", + "subId": 277889906 }, - "assetHint": "objects/groudplane/groundplane_521x521m.azmodel" + "assetHint": "objects/groudplane/groundplane_512x512m.azmodel" } } } diff --git a/Assets/Editor/Translation/scriptcanvas_en_us.ts b/Assets/Editor/Translation/scriptcanvas_en_us.ts index f057ba2f30..937f6a4d96 100644 --- a/Assets/Editor/Translation/scriptcanvas_en_us.ts +++ b/Assets/Editor/Translation/scriptcanvas_en_us.ts @@ -2771,6 +2771,80 @@ VECTOR2_CREATEONE_OUTPUT0_TOOLTIP + + VECTOR2_DIRECTIONTO_NAME + Class/Bus: Vector2 Event/Method: DirectionTo + Get Direction Vector + + + VECTOR2_DIRECTIONTO_TOOLTIP + Returns a direction vector between two points and the distance between them, by default the direction will be normalized, it may be optionally scaled using the Scale parameter if different from 1.0 + + + VECTOR2_DIRECTIONTO_CATEGORY + + + + VECTOR2_DIRECTIONTO_OUT_NAME + + + + VECTOR2_DIRECTIONTO_OUT_TOOLTIP + + + + VECTOR2_DIRECTIONTOL_IN_NAME + + + + VECTOR2_DIRECTIONTO_IN_TOOLTIP + + + + VECTOR2_DIRECTIONTO_OUTPUT0_NAME + C++ Type: const Vector2 + Direction + + + VECTOR2_DIRECTIONTO_OUTPUT0_TOOLTIP + The direction between To and From normalized and optionally scaled + + + VECTOR2_DIRECTIONTO_OUTPUT1_NAME + C++ Type: float + Distance + + + VECTOR2_DIRECTIONTO_OUTPUT1_TOOLTIP + The distance between To and From + + + VECTOR2_DIRECTIONTO_PARAM0_NAME + Simple Type: Vector2 C++ Type: Vector2* + From + + + VECTOR2_DIRECTIONTO_PARAM0_TOOLTIP + + + + VECTOR2_DIRECTIONTO_PARAM1_NAME + Simple Type: Vector2 C++ Type: Vector2* + To + + + VECTOR2_DIRECTIONTO_PARAM1_TOOLTIP + + + + VECTOR2_DIRECTIONTO_PARAM2_NAME + Simple Type: Vector2 C++ Type: Vector2* + Scale + + + VECTOR2_DIRECTIONTO_PARAM2_TOOLTIP + + VECTOR2_GETPROJECTED_NAME Class/Bus: Vector2 Event/Method: GetProjected @@ -32262,6 +32336,80 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro VECTOR4_GETRECIPROCAL_PARAM0_TOOLTIP + + VECTOR4_DIRECTIONTO_NAME + Class/Bus: Vector4 Event/Method: DirectionTo + Get Direction Vector + + + VECTOR4_DIRECTIONTO_TOOLTIP + Returns a direction vector between two points and the distance between them, by default the direction will be normalized, it may be optionally scaled using the Scale parameter if different from 1.0 + + + VECTOR4_DIRECTIONTO_CATEGORY + + + + VECTOR4_DIRECTIONTO_OUT_NAME + + + + VECTOR4_DIRECTIONTO_OUT_TOOLTIP + + + + VECTOR4_DIRECTIONTOL_IN_NAME + + + + VECTOR4_DIRECTIONTO_IN_TOOLTIP + + + + VECTOR4_DIRECTIONTO_OUTPUT0_NAME + C++ Type: const Vector4 + Direction + + + VECTOR4_DIRECTIONTO_OUTPUT0_TOOLTIP + The direction between To and From normalized and optionally scaled + + + VECTOR4_DIRECTIONTO_OUTPUT1_NAME + C++ Type: float + Distance + + + VECTOR4_DIRECTIONTO_OUTPUT1_TOOLTIP + The distance between To and From + + + VECTOR4_DIRECTIONTO_PARAM0_NAME + Simple Type: Vector4 C++ Type: Vector4* + From + + + VECTOR4_DIRECTIONTO_PARAM0_TOOLTIP + + + + VECTOR4_DIRECTIONTO_PARAM1_NAME + Simple Type: Vector4 C++ Type: Vector4* + To + + + VECTOR4_DIRECTIONTO_PARAM1_TOOLTIP + + + + VECTOR4_DIRECTIONTO_PARAM2_NAME + Simple Type: Vector4 C++ Type: Vector4* + Scale + + + VECTOR4_DIRECTIONTO_PARAM2_TOOLTIP + + VECTOR4_AXISX_NAME Class/Bus: Vector4 Event/Method: CreateAxisX @@ -37469,6 +37617,80 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro VECTOR3_GETRECIPROCAL_PARAM0_TOOLTIP + + VECTOR3_DIRECTIONTO_NAME + Class/Bus: Vector3 Event/Method: DirectionTo + Get Direction Vector + + + VECTOR3_DIRECTIONTO_TOOLTIP + Returns a direction vector between two points and the distance between them, by default the direction will be normalized, it may be optionally scaled using the Scale parameter if different from 1.0 + + + VECTOR3_DIRECTIONTO_CATEGORY + + + + VECTOR3_DIRECTIONTO_OUT_NAME + + + + VECTOR3_DIRECTIONTO_OUT_TOOLTIP + + + + VECTOR3_DIRECTIONTOL_IN_NAME + + + + VECTOR3_DIRECTIONTO_IN_TOOLTIP + + + + VECTOR3_DIRECTIONTO_OUTPUT0_NAME + C++ Type: const Vector3 + Direction + + + VECTOR3_DIRECTIONTO_OUTPUT0_TOOLTIP + The direction between To and From normalized and optionally scaled + + + VECTOR3_DIRECTIONTO_OUTPUT1_NAME + C++ Type: float + Distance + + + VECTOR3_DIRECTIONTO_OUTPUT1_TOOLTIP + The distance between To and From + + + VECTOR3_DIRECTIONTO_PARAM0_NAME + Simple Type: Vector3 C++ Type: Vector3* + From + + + VECTOR3_DIRECTIONTO_PARAM0_TOOLTIP + + + + VECTOR3_DIRECTIONTO_PARAM1_NAME + Simple Type: Vector3 C++ Type: Vector3* + To + + + VECTOR3_DIRECTIONTO_PARAM1_TOOLTIP + + + + VECTOR3_DIRECTIONTO_PARAM2_NAME + Simple Type: Vector3 C++ Type: Vector3* + Scale + + + VECTOR3_DIRECTIONTO_PARAM2_TOOLTIP + + VECTOR3_PROJECT_NAME Class/Bus: Vector3 Event/Method: Project diff --git a/AutomatedTesting/surfacetypemateriallibrary.physmaterial b/AutomatedTesting/Assets/Physics/SurfaceTypeMaterialLibrary.physmaterial similarity index 100% rename from AutomatedTesting/surfacetypemateriallibrary.physmaterial rename to AutomatedTesting/Assets/Physics/SurfaceTypeMaterialLibrary.physmaterial diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt index 8b9de91906..0170d73af0 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt @@ -97,7 +97,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py EXCLUDE_TEST_RUN_TARGET_FROM_IDE TEST_SERIAL - TIMEOUT 1500 + TIMEOUT 2400 TEST_SUITE periodic RUNTIME_DEPENDENCIES AZ::AssetProcessor diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py index 13b899dfdd..2c805f0291 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py @@ -113,7 +113,7 @@ class TestsAssetBuilder_WindowsAndMac(object): if listening_port: corrupted_slice_command.append(f'-port={listening_port}') if workspace.project: - corrupted_slice_command.append(f'-gamename={workspace.project}') + corrupted_slice_command.append(f'--project-path={workspace.project}') corrupted_slice_output = utils.safe_subprocess(corrupted_slice_command) # Verify corrupted slice produced error diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py index 768dd985fd..7f85e5e317 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py @@ -902,7 +902,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): second_input_arg = asset_lists_to_string(second_asset_list) # --secondAssetList output_arg = asset_lists_to_string(output_file) # --output - def generate_compare_command(platform_arg: str) -> object: + def generate_compare_command(platform_arg: str, project_name : str) -> object: """Creates a string containing a full Compare command. This string can be executed as-is.""" cmd = [helper["bundler_batch"], "compare", f"--firstassetFile={first_input_arg}", f"--output={output_arg}"] if platform_arg is not None: @@ -918,6 +918,8 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): if comp_type == "4": # Extra arguments for pattern comparison cmd.extend([f"--filePatternType={pattern_type}", f"--filePattern={pattern}"]) + if workspace.project: + cmd.append(f'--project-path={project_name}') return cmd # End generate_compare_command() @@ -936,6 +938,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): # End verify_asset_list_contents() def run_compare_command_and_verify(platform_arg: str, expect_pc_output: bool, expect_mac_output: bool) -> None: + # Expected asset list to equal result of comparison expected_pc_asset_list = None expected_mac_asset_list = None @@ -957,7 +960,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): output_mac_asset_list = helper.platform_file_name(last_output_arg, platform) # Build execution command - cmd = generate_compare_command(platform_arg) + cmd = generate_compare_command(platform_arg, workspace.project) # Execute command subprocess.check_call(cmd) @@ -992,10 +995,12 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): f"--comparisonRulesFile={rule_file}", f"--comparisonType={args[1]}", r"--addComparison", + f"--project-path={workspace.project}", ] if args[1] == "4": # If pattern comparison, append a few extra arguments cmd.extend(["--filePatternType=0", "--filePattern=*.dat"]) + subprocess.check_call(cmd) assert os.path.exists(rule_file), f"Rule file {args[0]} was not created at location: {rule_file}" diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt index a342d95d98..d4f036faeb 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt @@ -17,7 +17,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT TEST_SUITE main PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_MainSuite.py TEST_SERIAL - TIMEOUT 400 + TIMEOUT 600 RUNTIME_DEPENDENCIES AssetProcessor AutomatedTesting.Assets diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_LightComponent.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_LightComponent.py new file mode 100644 index 0000000000..ec8dc199ae --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_LightComponent.py @@ -0,0 +1,217 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT + +Hydra script that creates an entity, attaches the Light component to it for test verifications. +The test verifies that each light type option is available and can be selected without errors. +""" + +import os +import sys + +import azlmbr.bus as bus +import azlmbr.editor as editor +import azlmbr.math as math +import azlmbr.paths +import azlmbr.legacy.general as general + +sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests")) + +import editor_python_test_tools.hydra_editor_utils as hydra +from atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES + +LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type' +SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [ + ("Controller|Configuration|Shadows|Enable shadow", True), + ("Controller|Configuration|Shadows|Shadowmap size", 0), # 256 + ("Controller|Configuration|Shadows|Shadowmap size", 1), # 512 + ("Controller|Configuration|Shadows|Shadowmap size", 2), # 1024 + ("Controller|Configuration|Shadows|Shadowmap size", 3), # 2048 + ("Controller|Configuration|Shadows|Shadow filter method", 1), # PCF + ("Controller|Configuration|Shadows|Filtering sample count", 4.0), + ("Controller|Configuration|Shadows|Filtering sample count", 64.0), + ("Controller|Configuration|Shadows|PCF method", 0), # Bicubic + ("Controller|Configuration|Shadows|PCF method", 1), # Boundary search + ("Controller|Configuration|Shadows|Shadow filter method", 2), # ECM + ("Controller|Configuration|Shadows|ESM exponent", 50), + ("Controller|Configuration|Shadows|ESM exponent", 5000), + ("Controller|Configuration|Shadows|Shadow filter method", 3), # ESM+PCF +] +QUAD_LIGHT_PROPERTIES = [ + ("Controller|Configuration|Both directions", True), + ("Controller|Configuration|Fast approximation", True), +] +SIMPLE_POINT_LIGHT_PROPERTIES = [ + ("Controller|Configuration|Attenuation radius|Mode", 0), + ("Controller|Configuration|Attenuation radius|Radius", 100.0), +] +SIMPLE_SPOT_LIGHT_PROPERTIES = [ + ("Controller|Configuration|Shutters|Inner angle", 45.0), + ("Controller|Configuration|Shutters|Outer angle", 90.0), +] + + +def verify_required_component_property_value(entity_name, component, property_path, expected_property_value): + """ + Compares the property value of component against the expected_property_value. + :param entity_name: name of the entity to use (for test verification purposes). + :param component: component to check on a given entity for its current property value. + :param property_path: the path to the property inside the component. + :param expected_property_value: The value expected from the value inside property_path. + :return: None, but prints to general.log() which the test uses to verify against. + """ + property_value = editor.EditorComponentAPIBus( + bus.Broadcast, "GetComponentProperty", component, property_path).GetValue() + general.log(f"{entity_name}_test: Property value is {property_value} " + f"which matches {expected_property_value}") + + +def run(): + """ + Test Case - Light Component + 1. Creates a "light_entity" Entity and attaches a "Light" component to it. + 2. Updates the Light component to each light type option from the LIGHT_TYPES constant. + 3. The test will check the Editor log to ensure each light type was selected. + 4. Prints the string "Light component test (non-GPU) completed" after completion. + + Tests will fail immediately if any of these log lines are found: + 1. Trace::Assert + 2. Trace::Error + 3. Traceback (most recent call last): + + :return: None + """ + # Create a "light_entity" entity with "Light" component. + light_entity_name = "light_entity" + light_component = "Light" + light_entity = hydra.Entity(light_entity_name) + light_entity.create_entity(math.Vector3(-1.0, -2.0, 3.0), [light_component]) + general.log( + f"{light_entity_name}_test: Component added to the entity: " + f"{hydra.has_components(light_entity.id, [light_component])}") + + # Populate the light_component_id_pair value so that it can be used to select all Light component options. + light_component_id_pair = None + component_type_id_list = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', [light_component], 0) + if len(component_type_id_list) < 1: + general.log(f"ERROR: A component class with name {light_component} doesn't exist") + light_component_id_pair = None + elif len(component_type_id_list) > 1: + general.log(f"ERROR: Found more than one component classes with same name: {light_component}") + light_component_id_pair = None + entity_component_id_pair = azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, 'GetComponentOfType', light_entity.id, component_type_id_list[0]) + if entity_component_id_pair.IsSuccess(): + light_component_id_pair = entity_component_id_pair.GetValue() + + # Test each Light component option can be selected and it's properties updated. + # Point (sphere) light type checks. + light_type_property_test( + light_type=LIGHT_TYPES['sphere'], + light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES, + light_component_id_pair=light_component_id_pair, + light_entity_name=light_entity_name, + light_entity=light_entity + ) + + # Spot (disk) light type checks. + light_type_property_test( + light_type=LIGHT_TYPES['spot_disk'], + light_properties=SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES, + light_component_id_pair=light_component_id_pair, + light_entity_name=light_entity_name, + light_entity=light_entity + ) + + # Capsule light type checks. + azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + light_component_id_pair, + LIGHT_TYPE_PROPERTY, + LIGHT_TYPES['capsule'] + ) + verify_required_component_property_value( + entity_name=light_entity_name, + component=light_entity.components[0], + property_path=LIGHT_TYPE_PROPERTY, + expected_property_value=LIGHT_TYPES['capsule'] + ) + + # Quad light type checks. + light_type_property_test( + light_type=LIGHT_TYPES['quad'], + light_properties=QUAD_LIGHT_PROPERTIES, + light_component_id_pair=light_component_id_pair, + light_entity_name=light_entity_name, + light_entity=light_entity + ) + + # Polygon light type checks. + azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + light_component_id_pair, + LIGHT_TYPE_PROPERTY, + LIGHT_TYPES['polygon'] + ) + verify_required_component_property_value( + entity_name=light_entity_name, + component=light_entity.components[0], + property_path=LIGHT_TYPE_PROPERTY, + expected_property_value=LIGHT_TYPES['polygon'] + ) + + # Point (simple punctual) light type checks. + light_type_property_test( + light_type=LIGHT_TYPES['simple_point'], + light_properties=SIMPLE_POINT_LIGHT_PROPERTIES, + light_component_id_pair=light_component_id_pair, + light_entity_name=light_entity_name, + light_entity=light_entity + ) + + # Spot (simple punctual) light type checks. + light_type_property_test( + light_type=LIGHT_TYPES['simple_spot'], + light_properties=SIMPLE_SPOT_LIGHT_PROPERTIES, + light_component_id_pair=light_component_id_pair, + light_entity_name=light_entity_name, + light_entity=light_entity + ) + + general.log("Light component test (non-GPU) completed.") + + +def light_type_property_test(light_type, light_properties, light_component_id_pair, light_entity_name, light_entity): + """ + Updates the current light type and modifies its properties, then verifies they are accurate to what was set. + :param light_type: The type of light to update, must match a value in LIGHT_TYPES + :param light_properties: List of tuples detailing properties to modify with update values. + :param light_component_id_pair: Entity + component ID pair for updating the light component on a given entity. + :param light_entity_name: the name of the Entity holding the light component. + :param light_entity: the Entity object containing the light component. + :return: None + """ + azlmbr.editor.EditorComponentAPIBus( + azlmbr.bus.Broadcast, + 'SetComponentProperty', + light_component_id_pair, + LIGHT_TYPE_PROPERTY, + light_type + ) + verify_required_component_property_value( + entity_name=light_entity_name, + component=light_entity.components[0], + property_path=LIGHT_TYPE_PROPERTY, + expected_property_value=light_type + ) + + for light_property in light_properties: + light_entity.get_set_test(0, light_property[0], light_property[1]) + + +if __name__ == "__main__": + run() diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_component_helper.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_component_helper.py new file mode 100644 index 0000000000..de4e28bb36 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/atom_component_helper.py @@ -0,0 +1,19 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT + +File to assist with common hydra component functions or constants used across various Atom tests. +""" + +# Light type options for the Light component. +LIGHT_TYPES = { + 'unknown': 0, + 'sphere': 1, + 'spot_disk': 2, + 'capsule': 3, + 'quad': 4, + 'polygon': 5, + 'simple_point': 6, + 'simple_spot': 7, +} diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py index ed5d057626..98d2ba0632 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py @@ -12,9 +12,10 @@ import os import pytest import editor_python_test_tools.hydra_test_utils as hydra +from atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES logger = logging.getLogger(__name__) -EDITOR_TIMEOUT = 300 +EDITOR_TIMEOUT = 120 TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") @@ -180,3 +181,64 @@ class TestAtomEditorComponentsMain(object): null_renderer=True, cfg_args=cfg_args, ) + + def test_AtomEditorComponents_LightComponent( + self, request, editor, workspace, project, launcher_platform, level): + """ + Please review the hydra script run by this test for more specific test info. + Tests that the Light component has the expected property options available to it. + """ + cfg_args = [level] + + expected_lines = [ + "light_entity Entity successfully created", + "Entity has a Light component", + "light_entity_test: Component added to the entity: True", + f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}", + "Controller|Configuration|Shadows|Enable shadow set to True", + "light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS", + "Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF + "Controller|Configuration|Shadows|Filtering sample count set to 4", + "Controller|Configuration|Shadows|Filtering sample count set to 64", + "Controller|Configuration|Shadows|PCF method set to 0", + "Controller|Configuration|Shadows|PCF method set to 1", + "Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM + "Controller|Configuration|Shadows|ESM exponent set to 50.0", + "Controller|Configuration|Shadows|ESM exponent set to 5000.0", + "Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF + f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}", + f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}", + f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}", + "light_entity Controller|Configuration|Fast approximation: SUCCESS", + "light_entity Controller|Configuration|Both directions: SUCCESS", + f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}", + f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} " + f"which matches {LIGHT_TYPES['simple_point']}", + "Controller|Configuration|Attenuation radius|Mode set to 0", + "Controller|Configuration|Attenuation radius|Radius set to 100.0", + f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} " + f"which matches {LIGHT_TYPES['simple_spot']}", + "Controller|Configuration|Shutters|Outer angle set to 45.0", + "Controller|Configuration|Shutters|Outer angle set to 90.0", + "light_entity_test: Component added to the entity: True", + "Light component test (non-GPU) completed.", + ] + + unexpected_lines = [ + "Trace::Assert", + "Trace::Error", + "Traceback (most recent call last):", + ] + + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "hydra_AtomEditorComponents_LightComponent.py", + timeout=EDITOR_TIMEOUT, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + null_renderer=True, + cfg_args=cfg_args, + ) diff --git a/AutomatedTesting/Gem/PythonTests/physics/C15096740_Material_LibraryUpdatedCorrectly.py b/AutomatedTesting/Gem/PythonTests/physics/C15096740_Material_LibraryUpdatedCorrectly.py index 060779082c..341597e36a 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C15096740_Material_LibraryUpdatedCorrectly.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C15096740_Material_LibraryUpdatedCorrectly.py @@ -64,7 +64,8 @@ def C15096740_Material_LibraryUpdatedCorrectly(): # Constants library_property_path = "Configuration|Physics Material|Library" - default_material_path = "surfacetypemateriallibrary.physmaterial" + + default_material_path = os.path.join("assets", "physics", "surfacetypemateriallibrary.physmaterial") new_material_path = os.path.join("physicssurfaces", "default_phys_materials.physmaterial") helper.init_idle() @@ -82,7 +83,7 @@ def C15096740_Material_LibraryUpdatedCorrectly(): default_asset = Asset.find_asset_by_path(default_material_path) test_component.set_component_property_value(library_property_path, default_asset.id) default_asset.id = test_component.get_component_property_value(library_property_path) - Report.result(Tests.override_default_library, default_asset.get_path() == default_material_path) + Report.result(Tests.override_default_library, default_asset.get_path() == default_material_path.replace(os.sep, '/')) # 4) Switch it back again to the default material library. test_component.set_component_property_value(library_property_path, azasset.AssetId()) diff --git a/AutomatedTesting/Gem/PythonTests/physics/Physmaterial_Editor.py b/AutomatedTesting/Gem/PythonTests/physics/Physmaterial_Editor.py index 54ea3c7f15..cff8ae8377 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/Physmaterial_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/physics/Physmaterial_Editor.py @@ -133,7 +133,7 @@ class Physmaterial_Editor: def _set_path(self): # type: (str) -> str if self.document_filename == None: - self.document_filename = os.path.join(self.project_folder, "surfacetypemateriallibrary.physmaterial") + self.document_filename = os.path.join(self.project_folder, "assets", "physics", "surfacetypemateriallibrary.physmaterial") else: for (root, directories, root_files) in os.walk(self.project_folder): for root_file in root_files: diff --git a/AutomatedTesting/Passes/MainPipeline.pass b/AutomatedTesting/Passes/MainPipeline.pass new file mode 100644 index 0000000000..aa9f3757c4 --- /dev/null +++ b/AutomatedTesting/Passes/MainPipeline.pass @@ -0,0 +1,483 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "PassAsset", + "ClassData": { + "PassTemplate": { + "Name": "MainPipeline", + "PassClass": "ParentPass", + "Slots": [ + { + "Name": "SwapChainOutput", + "SlotType": "InputOutput", + "ScopeAttachmentUsage": "RenderTarget" + } + ], + "PassRequests": [ + { + "Name": "MorphTargetPass", + "TemplateName": "MorphTargetPassTemplate" + }, + { + "Name": "SkinningPass", + "TemplateName": "SkinningPassTemplate", + "Connections": [ + { + "LocalSlot": "SkinnedMeshOutputStream", + "AttachmentRef": { + "Pass": "MorphTargetPass", + "Attachment": "MorphTargetDeltaOutput" + } + } + ] + }, + { + "Name": "RayTracingAccelerationStructurePass", + "TemplateName": "RayTracingAccelerationStructurePassTemplate" + }, + { + "Name": "DiffuseProbeGridUpdatePass", + "TemplateName": "DiffuseProbeGridUpdatePassTemplate", + "ExecuteAfter": [ + "RayTracingAccelerationStructurePass" + ] + }, + { + "Name": "DepthPrePass", + "TemplateName": "DepthMSAAParentTemplate", + "Connections": [ + { + "LocalSlot": "SkinnedMeshes", + "AttachmentRef": { + "Pass": "SkinningPass", + "Attachment": "SkinnedMeshOutputStream" + } + }, + { + "LocalSlot": "SwapChainOutput", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "SwapChainOutput" + } + } + ] + }, + { + "Name": "MotionVectorPass", + "TemplateName": "MotionVectorParentTemplate", + "Connections": [ + { + "LocalSlot": "SkinnedMeshes", + "AttachmentRef": { + "Pass": "SkinningPass", + "Attachment": "SkinnedMeshOutputStream" + } + }, + { + "LocalSlot": "Depth", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + }, + { + "LocalSlot": "SwapChainOutput", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "SwapChainOutput" + } + } + ] + }, + { + "Name": "LightCullingPass", + "TemplateName": "LightCullingParentTemplate", + "Connections": [ + { + "LocalSlot": "SkinnedMeshes", + "AttachmentRef": { + "Pass": "SkinningPass", + "Attachment": "SkinnedMeshOutputStream" + } + }, + { + "LocalSlot": "DepthMSAA", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "DepthMSAA" + } + }, + { + "LocalSlot": "SwapChainOutput", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "SwapChainOutput" + } + } + ] + }, + { + "Name": "ShadowPass", + "TemplateName": "ShadowParentTemplate", + "Connections": [ + { + "LocalSlot": "SkinnedMeshes", + "AttachmentRef": { + "Pass": "SkinningPass", + "Attachment": "SkinnedMeshOutputStream" + } + }, + { + "LocalSlot": "SwapChainOutput", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "SwapChainOutput" + } + } + ] + }, + { + "Name": "OpaquePass", + "TemplateName": "OpaqueParentTemplate", + "Connections": [ + { + "LocalSlot": "DirectionalShadowmap", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "DirectionalShadowmap" + } + }, + { + "LocalSlot": "DirectionalESM", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "DirectionalESM" + } + }, + { + "LocalSlot": "ProjectedShadowmap", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "ProjectedShadowmap" + } + }, + { + "LocalSlot": "ProjectedESM", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "ProjectedESM" + } + }, + { + "LocalSlot": "TileLightData", + "AttachmentRef": { + "Pass": "LightCullingPass", + "Attachment": "TileLightData" + } + }, + { + "LocalSlot": "LightListRemapped", + "AttachmentRef": { + "Pass": "LightCullingPass", + "Attachment": "LightListRemapped" + } + }, + { + "LocalSlot": "DepthLinear", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "DepthLinear" + } + }, + { + "LocalSlot": "DepthStencil", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "DepthMSAA" + } + }, + { + "LocalSlot": "SwapChainOutput", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "SwapChainOutput" + } + } + ] + }, + { + "Name": "TransparentPass", + "TemplateName": "TransparentParentTemplate", + "Connections": [ + { + "LocalSlot": "DirectionalShadowmap", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "DirectionalShadowmap" + } + }, + { + "LocalSlot": "DirectionalESM", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "DirectionalESM" + } + }, + { + "LocalSlot": "ProjectedShadowmap", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "ProjectedShadowmap" + } + }, + { + "LocalSlot": "ProjectedESM", + "AttachmentRef": { + "Pass": "ShadowPass", + "Attachment": "ProjectedESM" + } + }, + { + "LocalSlot": "TileLightData", + "AttachmentRef": { + "Pass": "LightCullingPass", + "Attachment": "TileLightData" + } + }, + { + "LocalSlot": "LightListRemapped", + "AttachmentRef": { + "Pass": "LightCullingPass", + "Attachment": "LightListRemapped" + } + }, + { + "LocalSlot": "InputLinearDepth", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "DepthLinear" + } + }, + { + "LocalSlot": "DepthStencil", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + }, + { + "LocalSlot": "InputOutput", + "AttachmentRef": { + "Pass": "OpaquePass", + "Attachment": "Output" + } + } + ] + }, + { + "Name": "DeferredFogPass", + "TemplateName": "DeferredFogPassTemplate", + "Enabled": false, + "Connections": [ + { + "LocalSlot": "InputLinearDepth", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "DepthLinear" + } + }, + { + "LocalSlot": "InputDepthStencil", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + }, + { + "LocalSlot": "RenderTargetInputOutput", + "AttachmentRef": { + "Pass": "TransparentPass", + "Attachment": "InputOutput" + } + } + ], + "PassData": { + "$type": "FullscreenTrianglePassData", + "ShaderAsset": { + "FilePath": "Shaders/ScreenSpace/DeferredFog.shader" + }, + "PipelineViewTag": "MainCamera" + } + }, + { + "Name": "ReflectionCopyFrameBufferPass", + "TemplateName": "ReflectionCopyFrameBufferPassTemplate", + "Enabled": false, + "Connections": [ + { + "LocalSlot": "Input", + "AttachmentRef": { + "Pass": "DeferredFogPass", + "Attachment": "RenderTargetInputOutput" + } + } + ] + }, + { + "Name": "PostProcessPass", + "TemplateName": "PostProcessParentTemplate", + "Connections": [ + { + "LocalSlot": "LightingInput", + "AttachmentRef": { + "Pass": "DeferredFogPass", + "Attachment": "RenderTargetInputOutput" + } + }, + { + "LocalSlot": "Depth", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + }, + { + "LocalSlot": "MotionVectors", + "AttachmentRef": { + "Pass": "MotionVectorPass", + "Attachment": "MotionVectorOutput" + } + }, + { + "LocalSlot": "SwapChainOutput", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "SwapChainOutput" + } + } + ] + }, + { + "Name": "AuxGeomPass", + "TemplateName": "AuxGeomPassTemplate", + "Enabled": true, + "Connections": [ + { + "LocalSlot": "ColorInputOutput", + "AttachmentRef": { + "Pass": "PostProcessPass", + "Attachment": "Output" + } + }, + { + "LocalSlot": "DepthInputOutput", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + } + ], + "PassData": { + "$type": "RasterPassData", + "DrawListTag": "auxgeom", + "PipelineViewTag": "MainCamera" + } + }, + { + "Name": "DebugOverlayPass", + "TemplateName": "DebugOverlayParentTemplate", + "Connections": [ + { + "LocalSlot": "TileLightData", + "AttachmentRef": { + "Pass": "LightCullingPass", + "Attachment": "TileLightData" + } + }, + { + "LocalSlot": "RawLightingInput", + "AttachmentRef": { + "Pass": "PostProcessPass", + "Attachment": "RawLightingOutput" + } + }, + { + "LocalSlot": "LuminanceMipChainInput", + "AttachmentRef": { + "Pass": "PostProcessPass", + "Attachment": "LuminanceMipChainOutput" + } + }, + { + "LocalSlot": "InputOutput", + "AttachmentRef": { + "Pass": "AuxGeomPass", + "Attachment": "ColorInputOutput" + } + } + ] + }, + { + "Name": "LyShinePass", + "TemplateName": "LyShineParentTemplate", + "Connections": [ + { + "LocalSlot": "ColorInputOutput", + "AttachmentRef": { + "Pass": "DebugOverlayPass", + "Attachment": "InputOutput" + } + }, + { + "LocalSlot": "DepthInputOutput", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + } + ] + }, + { + "Name": "UIPass", + "TemplateName": "UIParentTemplate", + "Connections": [ + { + "LocalSlot": "InputOutput", + "AttachmentRef": { + "Pass": "LyShinePass", + "Attachment": "ColorInputOutput" + } + }, + { + "LocalSlot": "DepthInputOutput", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + } + ] + }, + { + "Name": "CopyToSwapChain", + "TemplateName": "FullscreenCopyTemplate", + "Connections": [ + { + "LocalSlot": "Input", + "AttachmentRef": { + "Pass": "UIPass", + "Attachment": "InputOutput" + } + }, + { + "LocalSlot": "Output", + "AttachmentRef": { + "Pass": "Parent", + "Attachment": "SwapChainOutput" + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override b/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override index 9fa5e26768..e4ea71f652 100644 --- a/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override +++ b/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override @@ -121,9 +121,10 @@ }, "MaterialLibrary": { "assetId": { - "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" + "guid": "{62446378-67F8-5E49-AC31-761DD5942695}" }, - "assetHint": "surfacetypemateriallibrary.physmaterial" + "loadBehavior": "QueueLoad", + "assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial" } } } diff --git a/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override b/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override index afbe6a9d38..e53d3893f8 100644 --- a/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override +++ b/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override @@ -109,9 +109,10 @@ }, "MaterialLibrary": { "assetId": { - "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" + "guid": "{62446378-67F8-5E49-AC31-761DD5942695}" }, - "assetHint": "surfacetypemateriallibrary.physmaterial" + "loadBehavior": "QueueLoad", + "assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial" } } } diff --git a/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override b/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override index 9fa5e26768..e4ea71f652 100644 --- a/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override +++ b/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override @@ -121,9 +121,10 @@ }, "MaterialLibrary": { "assetId": { - "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" + "guid": "{62446378-67F8-5E49-AC31-761DD5942695}" }, - "assetHint": "surfacetypemateriallibrary.physmaterial" + "loadBehavior": "QueueLoad", + "assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial" } } } diff --git a/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override b/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override index 9fa5e26768..e4ea71f652 100644 --- a/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override +++ b/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override @@ -121,9 +121,10 @@ }, "MaterialLibrary": { "assetId": { - "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" + "guid": "{62446378-67F8-5E49-AC31-761DD5942695}" }, - "assetHint": "surfacetypemateriallibrary.physmaterial" + "loadBehavior": "QueueLoad", + "assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial" } } } diff --git a/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override b/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override index 9fa5e26768..e4ea71f652 100644 --- a/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override +++ b/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override @@ -121,9 +121,10 @@ }, "MaterialLibrary": { "assetId": { - "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" + "guid": "{62446378-67F8-5E49-AC31-761DD5942695}" }, - "assetHint": "surfacetypemateriallibrary.physmaterial" + "loadBehavior": "QueueLoad", + "assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial" } } } diff --git a/AutomatedTesting/Registry/physxsystemconfiguration.setreg b/AutomatedTesting/Registry/physxsystemconfiguration.setreg index 02f65b685b..83aad307a6 100644 --- a/AutomatedTesting/Registry/physxsystemconfiguration.setreg +++ b/AutomatedTesting/Registry/physxsystemconfiguration.setreg @@ -103,9 +103,10 @@ }, "MaterialLibrary": { "assetId": { - "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" + "guid": "{62446378-67F8-5E49-AC31-761DD5942695}" }, - "assetHint": "surfacetypemateriallibrary.physmaterial" + "loadBehavior": "QueueLoad", + "assetHint": "assets/physics/surfacetypemateriallibrary.physmaterial" } } } diff --git a/Code/Editor/Controls/ConsoleSCB.cpp b/Code/Editor/Controls/ConsoleSCB.cpp index 9c13aa7328..01f6d24c6e 100644 --- a/Code/Editor/Controls/ConsoleSCB.cpp +++ b/Code/Editor/Controls/ConsoleSCB.cpp @@ -338,6 +338,8 @@ CConsoleSCB::CConsoleSCB(QWidget* parent) connect(findPreviousAction, &QAction::triggered, this, &CConsoleSCB::findPrevious); ui->findPrevButton->addAction(findPreviousAction); + GetIEditor()->RegisterNotifyListener(this); + connect(ui->button, &QPushButton::clicked, this, &CConsoleSCB::showVariableEditor); connect(ui->findButton, &QPushButton::clicked, this, &CConsoleSCB::toggleConsoleSearch); connect(ui->textEdit, &ConsoleTextEdit::searchBarRequested, this, [this] @@ -376,6 +378,8 @@ CConsoleSCB::~CConsoleSCB() { AzToolsFramework::EditorPreferencesNotificationBus::Handler::BusDisconnect(); + GetIEditor()->UnregisterNotifyListener(this); + s_consoleSCB = nullptr; CLogFile::AttachEditBox(nullptr); } @@ -1352,4 +1356,19 @@ CConsoleSCB* CConsoleSCB::GetCreatedInstance() return s_consoleSCB; } +void CConsoleSCB::OnEditorNotifyEvent(EEditorNotifyEvent event) +{ + switch (event) + { + case eNotify_OnBeginGameMode: + if (gSettings.clearConsoleOnGameModeStart) + { + ui->textEdit->clear(); + } + break; + default: + break; + } +} + #include diff --git a/Code/Editor/Controls/ConsoleSCB.h b/Code/Editor/Controls/ConsoleSCB.h index 98bf4b391d..f51786e2a5 100644 --- a/Code/Editor/Controls/ConsoleSCB.h +++ b/Code/Editor/Controls/ConsoleSCB.h @@ -159,6 +159,7 @@ private: class CConsoleSCB : public QWidget , private AzToolsFramework::EditorPreferencesNotificationBus::Handler + , public IEditorNotifyListener { Q_OBJECT public: @@ -187,6 +188,8 @@ private Q_SLOTS: void findNext(); private: + void OnEditorNotifyEvent(EEditorNotifyEvent event) override; + QScopedPointer ui; int m_richEditTextLength; diff --git a/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.h b/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.h index 0abf7d295c..9bd34f3f7c 100644 --- a/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.h +++ b/Code/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.h @@ -122,7 +122,7 @@ protected: public: //! Get number of child nodes. - int GetChildCount() const { return m_childs.size(); }; + int GetChildCount() const { return static_cast(m_childs.size()); }; //! Get Child by id. ReflectedPropertyItem* GetChild(int index) const { return m_childs[index]; } PropertyType GetType() const { return m_type; } diff --git a/Code/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Editor/Core/LevelEditorMenuHandler.cpp index 3c27c25c9a..70ff51c3d6 100644 --- a/Code/Editor/Core/LevelEditorMenuHandler.cpp +++ b/Code/Editor/Core/LevelEditorMenuHandler.cpp @@ -544,12 +544,12 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe auto snapMenu = modifyMenu.AddMenu(tr("Snap")); - snapMenu.AddAction(ID_SNAPANGLE); + snapMenu.AddAction(AzToolsFramework::SnapAngle); auto transformModeMenu = modifyMenu.AddMenu(tr("Transform Mode")); - transformModeMenu.AddAction(ID_EDITMODE_MOVE); - transformModeMenu.AddAction(ID_EDITMODE_ROTATE); - transformModeMenu.AddAction(ID_EDITMODE_SCALE); + transformModeMenu.AddAction(AzToolsFramework::EditModeMove); + transformModeMenu.AddAction(AzToolsFramework::EditModeRotate); + transformModeMenu.AddAction(AzToolsFramework::EditModeScale); editMenu.AddSeparator(); diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 3673367c12..63f6908fdb 100644 --- a/Code/Editor/CryEdit.cpp +++ b/Code/Editor/CryEdit.cpp @@ -375,9 +375,6 @@ void CCryEditApp::RegisterActionHandlers() }); ON_COMMAND(ID_MOVE_OBJECT, OnMoveObject) ON_COMMAND(ID_RENAME_OBJ, OnRenameObj) - ON_COMMAND(ID_EDITMODE_MOVE, OnEditmodeMove) - ON_COMMAND(ID_EDITMODE_ROTATE, OnEditmodeRotate) - ON_COMMAND(ID_EDITMODE_SCALE, OnEditmodeScale) ON_COMMAND(ID_UNDO, OnUndo) ON_COMMAND(ID_TOOLBAR_WIDGET_REDO, OnUndo) // Can't use the same ID, because for the menu we can't have a QWidgetAction, while for the toolbar we want one ON_COMMAND(ID_IMPORT_ASSET, OnOpenAssetImporter) @@ -2574,75 +2571,6 @@ void CCryEditApp::OnRenameObj() { } -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnEditmodeMove() -{ - using namespace AzToolsFramework; - EditorTransformComponentSelectionRequestBus::Event( - GetEntityContextId(), - &EditorTransformComponentSelectionRequests::SetTransformMode, - EditorTransformComponentSelectionRequests::Mode::Translation); -} - -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnEditmodeRotate() -{ - using namespace AzToolsFramework; - EditorTransformComponentSelectionRequestBus::Event( - GetEntityContextId(), - &EditorTransformComponentSelectionRequests::SetTransformMode, - EditorTransformComponentSelectionRequests::Mode::Rotation); -} - -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnEditmodeScale() -{ - using namespace AzToolsFramework; - EditorTransformComponentSelectionRequestBus::Event( - GetEntityContextId(), - &EditorTransformComponentSelectionRequests::SetTransformMode, - EditorTransformComponentSelectionRequests::Mode::Scale); -} - -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnUpdateEditmodeMove(QAction* action) -{ - Q_ASSERT(action->isCheckable()); - - AzToolsFramework::EditorTransformComponentSelectionRequests::Mode mode; - AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult( - mode, AzToolsFramework::GetEntityContextId(), - &AzToolsFramework::EditorTransformComponentSelectionRequests::GetTransformMode); - - action->setChecked(mode == AzToolsFramework::EditorTransformComponentSelectionRequests::Mode::Translation); -} - -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnUpdateEditmodeRotate(QAction* action) -{ - Q_ASSERT(action->isCheckable()); - - AzToolsFramework::EditorTransformComponentSelectionRequests::Mode mode; - AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult( - mode, AzToolsFramework::GetEntityContextId(), - &AzToolsFramework::EditorTransformComponentSelectionRequests::GetTransformMode); - - action->setChecked(mode == AzToolsFramework::EditorTransformComponentSelectionRequests::Mode::Rotation); -} - -////////////////////////////////////////////////////////////////////////// -void CCryEditApp::OnUpdateEditmodeScale(QAction* action) -{ - Q_ASSERT(action->isCheckable()); - - AzToolsFramework::EditorTransformComponentSelectionRequests::Mode mode; - AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult( - mode, AzToolsFramework::GetEntityContextId(), - &AzToolsFramework::EditorTransformComponentSelectionRequests::GetTransformMode); - - action->setChecked(mode == AzToolsFramework::EditorTransformComponentSelectionRequests::Mode::Scale); -} - void CCryEditApp::OnViewSwitchToGame() { if (IsInPreviewMode()) @@ -2896,7 +2824,14 @@ void CCryEditApp::OpenProjectManager(const AZStd::string& screen) { // provide the current project path for in case we want to update the project AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath(); - const AZStd::string commandLineOptions = AZStd::string::format(" --screen %s --project-path %s", screen.c_str(), projectPath.c_str()); +#if !AZ_TRAIT_OS_PLATFORM_APPLE && !AZ_TRAIT_OS_USE_WINDOWS_FILE_PATHS + const char* argumentQuoteString = R"(")"; +#else + const char* argumentQuoteString = R"(\")"; +#endif + const AZStd::string commandLineOptions = AZStd::string::format(R"( --screen %s --project-path %s%s%s)", + screen.c_str(), + argumentQuoteString, projectPath.c_str(), argumentQuoteString); bool launchSuccess = AzFramework::ProjectManager::LaunchProjectManager(commandLineOptions); if (!launchSuccess) { diff --git a/Code/Editor/CryEdit.h b/Code/Editor/CryEdit.h index 431a9cb817..5bb9326782 100644 --- a/Code/Editor/CryEdit.h +++ b/Code/Editor/CryEdit.h @@ -208,12 +208,6 @@ public: void DeleteSelectedEntities(bool includeDescendants); void OnMoveObject(); void OnRenameObj(); - void OnEditmodeMove(); - void OnEditmodeRotate(); - void OnEditmodeScale(); - void OnUpdateEditmodeMove(QAction* action); - void OnUpdateEditmodeRotate(QAction* action); - void OnUpdateEditmodeScale(QAction* action); void OnUndo(); void OnOpenAssetImporter(); void OnUpdateSelected(QAction* action); diff --git a/Code/Editor/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp index 5438f44f37..881a047320 100644 --- a/Code/Editor/CryEditDoc.cpp +++ b/Code/Editor/CryEditDoc.cpp @@ -108,21 +108,12 @@ namespace Internal // CCryEditDoc construction/destruction CCryEditDoc::CCryEditDoc() - : doc_validate_surface_types(0) + : doc_validate_surface_types(nullptr) , m_modifiedModuleFlags(eModifiedNothing) - // It assumes loaded levels have already been exported. Can be a big fat lie, though. - // The right way would require us to save to the level folder the export status of the - // level. - , m_boLevelExported(true) - , m_modified(false) - , m_envProbeHeight(200.0f) - , m_envProbeSliceRelativePath("EngineAssets/Slices/DefaultLevelSetup.slice") { //////////////////////////////////////////////////////////////////////// // Set member variables to initial values //////////////////////////////////////////////////////////////////////// - m_bLoadFailed = false; - m_waterColor = QColor(0, 0, 255); m_fogTemplate = GetIEditor()->FindTemplate("Fog"); m_environmentTemplate = GetIEditor()->FindTemplate("Environment"); @@ -136,7 +127,6 @@ CCryEditDoc::CCryEditDoc() m_environmentTemplate = XmlHelpers::CreateXmlNode("Environment"); } - m_bDocumentReady = false; GetIEditor()->SetDocument(this); CLogFile::WriteLine("Document created"); RegisterConsoleVariables(); @@ -195,7 +185,7 @@ CCryEditDoc::DocumentEditingMode CCryEditDoc::GetEditMode() const QString CCryEditDoc::GetActivePathName() const { - return DocumentEditingMode() == CCryEditDoc::DocumentEditingMode::SliceEdit ? GetSlicePathName() : GetLevelPathName(); + return GetEditMode() == CCryEditDoc::DocumentEditingMode::SliceEdit ? GetSlicePathName() : GetLevelPathName(); } QString CCryEditDoc::GetTitle() const @@ -260,9 +250,9 @@ void CCryEditDoc::DeleteContents() GetIEditor()->FlushUndo(); // Notify listeners. - for (std::list::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) + for (IDocListener* listener : m_listeners) { - (*it)->OnCloseDocument(); + listener->OnCloseDocument(); } GetIEditor()->ResetViews(); @@ -458,7 +448,7 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename) ////////////////////////////////////////////////////////////////////////// // Load water color. ////////////////////////////////////////////////////////////////////////// - (*arrXmlAr[DMAS_GENERAL]).root->getAttr("WaterColor", m_waterColor); + (*arrXmlAr[DMAS_GENERAL]).root->getAttr("WaterColor", m_waterColor); ////////////////////////////////////////////////////////////////////////// // Load View Settings @@ -507,9 +497,9 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename) CAutoLogTime logtime("Post Load"); // Notify listeners. - for (std::list::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) + for (IDocListener* listener : m_listeners) { - (*it)->OnLoadDocument(); + listener->OnLoadDocument(); } } @@ -708,7 +698,8 @@ bool CCryEditDoc::SaveModified() return true; } - auto button = QMessageBox::question(AzToolsFramework::GetActiveWindow(), QString(), tr("Save changes to %1?").arg(GetTitle()), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + auto button = QMessageBox::question(AzToolsFramework::GetActiveWindow(), QString(), tr("Save changes to %1?").arg(GetTitle()), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); switch (button) { case QMessageBox::Cancel: @@ -933,8 +924,7 @@ bool CCryEditDoc::OnSaveDocument(const QString& lpszPathName) } TSaveDocContext context; - if (shouldSaveLevel && - BeforeSaveDocument(lpszPathName, context)) + if (shouldSaveLevel && BeforeSaveDocument(lpszPathName, context)) { DoSaveDocument(lpszPathName, context); saveSuccess = AfterSaveDocument(lpszPathName, context); @@ -972,7 +962,7 @@ bool CCryEditDoc::BeforeSaveDocument(const QString& lpszPathName, TSaveDocContex return TRUE; } -bool CCryEditDoc::HasLayerNameConflicts() +bool CCryEditDoc::HasLayerNameConflicts() const { AZStd::vector editorEntities; AzToolsFramework::EditorEntityContextRequestBus::Broadcast( @@ -1004,43 +994,42 @@ bool CCryEditDoc::HasLayerNameConflicts() bool CCryEditDoc::DoSaveDocument(const QString& filename, TSaveDocContext& context) { bool& bSaved = context.bSaved; - if (bSaved) + if (!bSaved) { - // Paranoia - we shouldn't get this far into the save routine without a level loaded (empty levelPath) - // If nothing is loaded, we don't need to save anything - if (filename.isEmpty()) - { - bSaved = false; - } - else - { - // Save Tag Point locations to file if auto save of tag points disabled - if (!gSettings.bAutoSaveTagPoints) - { - CCryEditApp::instance()->SaveTagLocations(); - } - - QString normalizedPath = Path::ToUnixPath(filename); - if (IsSliceFile(normalizedPath)) - { - bSaved = SaveSlice(normalizedPath); - } - else - { - bSaved = SaveLevel(normalizedPath); - } - - // Changes filename for this document. - SetPathName(normalizedPath); - } + return false; + } + // Paranoia - we shouldn't get this far into the save routine without a level loaded (empty levelPath) + // If nothing is loaded, we don't need to save anything + if (filename.isEmpty()) + { + bSaved = false; + return false; } + // Save Tag Point locations to file if auto save of tag points disabled + if (!gSettings.bAutoSaveTagPoints) + { + CCryEditApp::instance()->SaveTagLocations(); + } + + QString normalizedPath = Path::ToUnixPath(filename); + if (IsSliceFile(normalizedPath)) + { + bSaved = SaveSlice(normalizedPath); + } + else + { + bSaved = SaveLevel(normalizedPath); + } + + // Changes filename for this document. + SetPathName(normalizedPath); return bSaved; } bool CCryEditDoc::AfterSaveDocument([[maybe_unused]] const QString& lpszPathName, TSaveDocContext& context, bool bShowPrompt) { - bool& bSaved = context.bSaved; + bool bSaved = context.bSaved; GetIEditor()->Notify(eNotify_OnEndSceneSave); @@ -1067,8 +1056,7 @@ bool CCryEditDoc::AfterSaveDocument([[maybe_unused]] const QString& lpszPathName static void GetUserSettingsFile(const QString& levelFolder, QString& userSettings) { const char* pUserName = GetISystem()->GetUserName(); - QString fileName; - fileName = QStringLiteral("%1_usersettings.editor_xml").arg(pUserName); + QString fileName = QStringLiteral("%1_usersettings.editor_xml").arg(pUserName); userSettings = Path::Make(levelFolder, fileName); } @@ -1182,9 +1170,9 @@ bool CCryEditDoc::SaveLevel(const QString& filename) } QString oldFilePath = QDir(oldLevelFolder).absoluteFilePath(sourceName); - QString newFilePath = QDir(newLevelFolder).absoluteFilePath(sourceName); + QString newFilePath = QDir(newLevelFolder).absoluteFilePath(destName); CFileUtil::CopyFile(oldFilePath, newFilePath); - } while (findHandle = pIPak->FindNext(findHandle)); + } while ((findHandle = pIPak->FindNext(findHandle))); pIPak->FindClose(findHandle); } @@ -1506,7 +1494,7 @@ bool CCryEditDoc::LoadEntitiesFromLevel(const QString& levelPakFile) { AZStd::vector fileBuffer; fileBuffer.resize(entitiesFile.GetLength()); - if (fileBuffer.size() > 0) + if (!fileBuffer.empty()) { if (fileBuffer.size() == entitiesFile.ReadRaw(fileBuffer.begin(), fileBuffer.size())) { @@ -1910,7 +1898,7 @@ void CCryEditDoc::UnregisterListener(IDocListener* listener) m_listeners.remove(listener); } -void CCryEditDoc::LogLoadTime(int time) +void CCryEditDoc::LogLoadTime(int time) const { QString appFilePath = QDir::toNativeSeparators(QCoreApplication::applicationFilePath()); QString exePath = Path::GetPath(appFilePath); @@ -1922,21 +1910,18 @@ void CCryEditDoc::LogLoadTime(int time) SetFileAttributesW(filename.toStdWString().c_str(), FILE_ATTRIBUTE_ARCHIVE); #endif - FILE* file = nullptr; - azfopen(&file, filename.toUtf8().data(), "at"); - - if (file) + QFile file(filename); + if (!file.open(QFile::Append | QFile::Text)) { - char version[50]; - GetIEditor()->GetFileVersion().ToShortString(version, AZ_ARRAY_SIZE(version)); - - QString text; - - time = time / 1000; - text = QStringLiteral("\n[%1] Level %2 loaded in %3 seconds").arg(version, level).arg(time); - fwrite(text.toUtf8().data(), text.toUtf8().length(), 1, file); - fclose(file); + return; } + + char version[50]; + GetIEditor()->GetFileVersion().ToShortString(version, AZ_ARRAY_SIZE(version)); + + time = time / 1000; + QString text = QStringLiteral("\n[%1] Level %2 loaded in %3 seconds").arg(version, level).arg(time); + file.write(text.toUtf8()); } void CCryEditDoc::SetDocumentReady(bool bReady) @@ -1944,7 +1929,7 @@ void CCryEditDoc::SetDocumentReady(bool bReady) m_bDocumentReady = bReady; } -void CCryEditDoc::GetMemoryUsage(ICrySizer* pSizer) +void CCryEditDoc::GetMemoryUsage(ICrySizer* pSizer) const { { SIZER_COMPONENT_NAME(pSizer, "UndoManager(estimate)"); @@ -2068,12 +2053,9 @@ void CCryEditDoc::InitEmptyLevel(int /*resolution*/, int /*unitSize*/, bool /*bU { // Notify listeners. std::list listeners = m_listeners; - std::list::iterator it, next; - for (it = listeners.begin(); it != listeners.end(); it = next) + for (IDocListener* listener : listeners) { - next = it; - next++; - (*it)->OnNewDocument(); + listener->OnNewDocument(); } } @@ -2134,25 +2116,23 @@ void CCryEditDoc::OnEnvironmentPropertyChanged(IVariable* pVar) { return; } + QString childValue; if (pVar->GetDataType() == IVariable::DT_COLOR) { Vec3 value; pVar->Get(value); - QString buff; QColor gammaColor = ColorLinearToGamma(ColorF(value.x, value.y, value.z)); - buff = QStringLiteral("%1,%2,%3").arg(gammaColor.red()).arg(gammaColor.green()).arg(gammaColor.blue()); - childNode->setAttr("value", buff.toUtf8().data()); + childValue = QStringLiteral("%1,%2,%3").arg(gammaColor.red()).arg(gammaColor.green()).arg(gammaColor.blue()); } else { - QString value; - pVar->Get(value); - childNode->setAttr("value", value.toUtf8().data()); + pVar->Get(childValue); } + childNode->setAttr("value", childValue.toUtf8().data()); } -QString CCryEditDoc::GetCryIndexPath(const char* levelFilePath) +QString CCryEditDoc::GetCryIndexPath(const char* levelFilePath) const { QString levelPath = Path::GetPath(levelFilePath); QString levelName = Path::GetFileName(levelFilePath); @@ -2183,8 +2163,7 @@ BOOL CCryEditDoc::LoadXmlArchiveArray(TDocMultiArchive& arrXmlAr, const QString& } CPakFile pakFile; - bool loadFromPakSuccess; - loadFromPakSuccess = xmlAr.LoadFromPak(levelPath, pakFile); + bool loadFromPakSuccess = xmlAr.LoadFromPak(levelPath, pakFile); pIPak->ClosePack(absoluteLevelPath.toUtf8().data()); if (!loadFromPakSuccess) { diff --git a/Code/Editor/CryEditDoc.h b/Code/Editor/CryEditDoc.h index 9d86f62489..2ae2948b0d 100644 --- a/Code/Editor/CryEditDoc.h +++ b/Code/Editor/CryEditDoc.h @@ -91,7 +91,7 @@ public: // Create from serialization only // ClassWizard generated virtual function overrides virtual bool OnOpenDocument(const QString& lpszPathName); - const bool IsLevelLoadFailed() const { return m_bLoadFailed; } + bool IsLevelLoadFailed() const { return m_bLoadFailed; } //! Marks this document as having errors. void SetHasErrors() { m_hasErrors = true; } @@ -121,7 +121,7 @@ public: // Create from serialization only CClouds* GetClouds() { return m_pClouds; } void SetWaterColor(const QColor& col) { m_waterColor = col; } - QColor GetWaterColor() { return m_waterColor; } + QColor GetWaterColor() const { return m_waterColor; } XmlNodeRef& GetFogTemplate() { return m_fogTemplate; } XmlNodeRef& GetEnvironmentTemplate() { return m_environmentTemplate; } void OnEnvironmentPropertyChanged(IVariable* pVar); @@ -129,7 +129,7 @@ public: // Create from serialization only void RegisterListener(IDocListener* listener); void UnregisterListener(IDocListener* listener); - void GetMemoryUsage(ICrySizer* pSizer); + void GetMemoryUsage(ICrySizer* pSizer) const; static bool IsBackupOrTempLevelSubdirectory(const QString& folderName); protected: @@ -161,14 +161,14 @@ protected: void SerializeFogSettings(CXmlArchive& xmlAr); virtual void SerializeViewSettings(CXmlArchive& xmlAr); void SerializeNameSelection(CXmlArchive& xmlAr); - void LogLoadTime(int time); + void LogLoadTime(int time) const; struct TSaveDocContext { bool bSaved; }; bool BeforeSaveDocument(const QString& lpszPathName, TSaveDocContext& context); - bool HasLayerNameConflicts(); + bool HasLayerNameConflicts() const; bool DoSaveDocument(const QString& lpszPathName, TSaveDocContext& context); bool AfterSaveDocument(const QString& lpszPathName, TSaveDocContext& context, bool bShowPrompt = true); @@ -180,7 +180,7 @@ protected: void OnStartLevelResourceList(); static void OnValidateSurfaceTypesChanged(ICVar*); - QString GetCryIndexPath(const char* levelFilePath); + QString GetCryIndexPath(const char* levelFilePath) const; ////////////////////////////////////////////////////////////////////////// // SliceEditorEntityOwnershipServiceNotificationBus::Handler @@ -188,24 +188,26 @@ protected: void OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId, const AzFramework::SliceInstantiationTicket& /*ticket*/) override; ////////////////////////////////////////////////////////////////////////// - bool m_bLoadFailed; - QColor m_waterColor; + bool m_bLoadFailed = false; + QColor m_waterColor = QColor(0, 0, 255); XmlNodeRef m_fogTemplate; XmlNodeRef m_environmentTemplate; CClouds* m_pClouds; std::list m_listeners; - bool m_bDocumentReady; - ICVar* doc_validate_surface_types; + bool m_bDocumentReady = false; + ICVar* doc_validate_surface_types = nullptr; int m_modifiedModuleFlags; - bool m_boLevelExported; - bool m_modified; + // On construction, it assumes loaded levels have already been exported. Can be a big fat lie, though. + // The right way would require us to save to the level folder the export status of the level. + bool m_boLevelExported = true; + bool m_modified = false; QString m_pathName; QString m_slicePathName; QString m_title; AZ::Data::AssetId m_envProbeSliceAssetId; float m_terrainSize; - const char* m_envProbeSliceRelativePath; - const float m_envProbeHeight; + const char* m_envProbeSliceRelativePath = "EngineAssets/Slices/DefaultLevelSetup.slice"; + const float m_envProbeHeight = 200.0f; bool m_hasErrors = false; ///< This is used to warn the user that they may lose work when they go to save. }; diff --git a/Code/Editor/EditorPreferencesPageGeneral.cpp b/Code/Editor/EditorPreferencesPageGeneral.cpp index 70ac0fd46f..79ecfbdfc7 100644 --- a/Code/Editor/EditorPreferencesPageGeneral.cpp +++ b/Code/Editor/EditorPreferencesPageGeneral.cpp @@ -32,6 +32,7 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize) ->Field("PreviewPanel", &GeneralSettings::m_previewPanel) ->Field("ApplyConfigSpec", &GeneralSettings::m_applyConfigSpec) ->Field("EnableSourceControl", &GeneralSettings::m_enableSourceControl) + ->Field("ClearConsole", &GeneralSettings::m_clearConsoleOnGameModeStart) ->Field("ConsoleBackgroundColorTheme", &GeneralSettings::m_consoleBackgroundColorTheme) ->Field("AutoloadLastLevel", &GeneralSettings::m_autoLoadLastLevel) ->Field("ShowTimeInConsole", &GeneralSettings::m_bShowTimeInConsole) @@ -77,6 +78,8 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize) ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_previewPanel, "Show Geometry Preview Panel", "Show Geometry Preview Panel") ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_applyConfigSpec, "Hide objects by config spec", "Hide objects by config spec") ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_enableSourceControl, "Enable Source Control", "Enable Source Control") + ->DataElement( + AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_clearConsoleOnGameModeStart, "Clear Console at game startup", "Clear Console when game mode starts") ->DataElement(AZ::Edit::UIHandlers::ComboBox, &GeneralSettings::m_consoleBackgroundColorTheme, "Console Background", "Console Background") ->EnumAttribute(AzToolsFramework::ConsoleColorTheme::Light, "Light") ->EnumAttribute(AzToolsFramework::ConsoleColorTheme::Dark, "Dark") @@ -142,6 +145,7 @@ void CEditorPreferencesPage_General::OnApply() gSettings.bPreviewGeometryWindow = m_generalSettings.m_previewPanel; gSettings.bApplyConfigSpecInEditor = m_generalSettings.m_applyConfigSpec; gSettings.enableSourceControl = m_generalSettings.m_enableSourceControl; + gSettings.clearConsoleOnGameModeStart = m_generalSettings.m_clearConsoleOnGameModeStart; gSettings.consoleBackgroundColorTheme = m_generalSettings.m_consoleBackgroundColorTheme; gSettings.bShowTimeInConsole = m_generalSettings.m_bShowTimeInConsole; gSettings.bShowDashboardAtStartup = m_messaging.m_showDashboard; @@ -176,6 +180,7 @@ void CEditorPreferencesPage_General::InitializeSettings() m_generalSettings.m_previewPanel = gSettings.bPreviewGeometryWindow; m_generalSettings.m_applyConfigSpec = gSettings.bApplyConfigSpecInEditor; m_generalSettings.m_enableSourceControl = gSettings.enableSourceControl; + m_generalSettings.m_clearConsoleOnGameModeStart = gSettings.clearConsoleOnGameModeStart; m_generalSettings.m_consoleBackgroundColorTheme = gSettings.consoleBackgroundColorTheme; m_generalSettings.m_bShowTimeInConsole = gSettings.bShowTimeInConsole; m_generalSettings.m_autoLoadLastLevel = gSettings.bAutoloadLastLevelAtStartup; diff --git a/Code/Editor/EditorPreferencesPageGeneral.h b/Code/Editor/EditorPreferencesPageGeneral.h index f22cfdd424..9a3a0f21e8 100644 --- a/Code/Editor/EditorPreferencesPageGeneral.h +++ b/Code/Editor/EditorPreferencesPageGeneral.h @@ -46,6 +46,7 @@ private: bool m_previewPanel; bool m_applyConfigSpec; bool m_enableSourceControl; + bool m_clearConsoleOnGameModeStart; AzToolsFramework::ConsoleColorTheme m_consoleBackgroundColorTheme; bool m_autoLoadLastLevel; bool m_bShowTimeInConsole; diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 357c27fd72..4c638e1f82 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -472,6 +472,12 @@ void EditorViewportWidget::Update() m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip); } + // Ensure the FOV matches our internally stored setting if we're using the Editor camera + if (!m_viewEntityId.IsValid() && !GetIEditor()->IsInGameMode()) + { + SetFOV(GetFOV()); + } + // Reset the camera update flag now that we're finished updating our viewport context m_updateCameraPositionNextTick = false; @@ -1234,6 +1240,13 @@ AZStd::shared_ptr CreateMod AzFramework::ViewportId viewportId) { auto controller = AZStd::make_shared(); + + controller->SetCameraPriorityBuilderCallback( + [](AtomToolsFramework::CameraControllerPriorityFn& cameraControllerPriorityFn) + { + cameraControllerPriorityFn = AtomToolsFramework::DefaultCameraControllerPriority; + }); + controller->SetCameraPropsBuilderCallback( [](AzFramework::CameraProps& cameraProps) { @@ -2624,8 +2637,6 @@ void EditorViewportWidget::DestroyRenderContext() ////////////////////////////////////////////////////////////////////////// void EditorViewportWidget::SetDefaultCamera() { - // Ensure the FOV matches our internally stored setting - SetFOV(GetFOV()); if (IsDefaultCamera()) { return; diff --git a/Code/Editor/EditorViewportWidget.h b/Code/Editor/EditorViewportWidget.h index 1829995d02..b682de1cc3 100644 --- a/Code/Editor/EditorViewportWidget.h +++ b/Code/Editor/EditorViewportWidget.h @@ -258,19 +258,19 @@ public: m_relCameraRotX = 0; m_relCameraRotZ = 0; - uint32 numSample6 = m_arrAnimatedCharacterPath.size(); + uint32 numSample6 = static_cast(m_arrAnimatedCharacterPath.size()); for (uint32 i = 0; i < numSample6; i++) { m_arrAnimatedCharacterPath[i] = Vec3(ZERO); } - numSample6 = m_arrSmoothEntityPath.size(); + numSample6 = static_cast(m_arrSmoothEntityPath.size()); for (uint32 i = 0; i < numSample6; i++) { m_arrSmoothEntityPath[i] = Vec3(ZERO); } - uint32 numSample7 = m_arrRunStrafeSmoothing.size(); + uint32 numSample7 = static_cast(m_arrRunStrafeSmoothing.size()); for (uint32 i = 0; i < numSample7; i++) { m_arrRunStrafeSmoothing[i] = 0; diff --git a/Code/Editor/ErrorReport.h b/Code/Editor/ErrorReport.h index dec5cd4fb8..2bef4105f8 100644 --- a/Code/Editor/ErrorReport.h +++ b/Code/Editor/ErrorReport.h @@ -105,7 +105,7 @@ public: bool IsEmpty() const; //! Get number of contained error records. - int GetErrorCount() const { return m_errors.size(); }; + int GetErrorCount() const { return static_cast(m_errors.size()); }; //! Get access to indexed error record. CErrorRecord& GetError(int i); //! Clear all error records. diff --git a/Code/Editor/GameEngine.cpp b/Code/Editor/GameEngine.cpp index dff6476ff9..173c13c235 100644 --- a/Code/Editor/GameEngine.cpp +++ b/Code/Editor/GameEngine.cpp @@ -566,7 +566,7 @@ void CGameEngine::SwitchToInGame() streamer->QueueRequest(flush); wait.acquire(); } - + GetIEditor()->Notify(eNotify_OnBeginGameMode); m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(true); diff --git a/Code/Editor/MainWindow.cpp b/Code/Editor/MainWindow.cpp index c5352cbc4c..7e66df3ab6 100644 --- a/Code/Editor/MainWindow.cpp +++ b/Code/Editor/MainWindow.cpp @@ -46,6 +46,7 @@ AZ_POP_DISABLE_WARNING #include #include #include +#include // AzQtComponents #include @@ -731,32 +732,84 @@ void MainWindow::InitActions() .SetStatusTip(tr("Restore saved state (Fetch)")); // Modify actions - am->AddAction(ID_EDITMODE_MOVE, tr("Move")) + am->AddAction(AzToolsFramework::EditModeMove, tr("Move")) .SetIcon(Style::icon("Move")) .SetApplyHoverEffect() .SetShortcut(tr("1")) .SetToolTip(tr("Move (1)")) .SetCheckable(true) .SetStatusTip(tr("Select and move selected object(s)")) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateEditmodeMove); - am->AddAction(ID_EDITMODE_ROTATE, tr("Rotate")) + .RegisterUpdateCallback([](QAction* action) + { + Q_ASSERT(action->isCheckable()); + + AzToolsFramework::EditorTransformComponentSelectionRequests::Mode mode; + AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult( + mode, AzToolsFramework::GetEntityContextId(), + &AzToolsFramework::EditorTransformComponentSelectionRequests::GetTransformMode); + + action->setChecked(mode == AzToolsFramework::EditorTransformComponentSelectionRequests::Mode::Translation); + }) + .Connect( + &QAction::triggered, + []() + { + EditorTransformComponentSelectionRequestBus::Event( + GetEntityContextId(), &EditorTransformComponentSelectionRequests::SetTransformMode, + EditorTransformComponentSelectionRequests::Mode::Translation); + }); + am->AddAction(AzToolsFramework::EditModeRotate, tr("Rotate")) .SetIcon(Style::icon("Translate")) .SetApplyHoverEffect() .SetShortcut(tr("2")) .SetToolTip(tr("Rotate (2)")) .SetCheckable(true) .SetStatusTip(tr("Select and rotate selected object(s)")) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateEditmodeRotate); - am->AddAction(ID_EDITMODE_SCALE, tr("Scale")) + .RegisterUpdateCallback([](QAction* action) + { + Q_ASSERT(action->isCheckable()); + + AzToolsFramework::EditorTransformComponentSelectionRequests::Mode mode; + AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult( + mode, AzToolsFramework::GetEntityContextId(), + &AzToolsFramework::EditorTransformComponentSelectionRequests::GetTransformMode); + + action->setChecked(mode == AzToolsFramework::EditorTransformComponentSelectionRequests::Mode::Rotation); + }) + .Connect( + &QAction::triggered, + []() + { + EditorTransformComponentSelectionRequestBus::Event( + GetEntityContextId(), &EditorTransformComponentSelectionRequests::SetTransformMode, + EditorTransformComponentSelectionRequests::Mode::Rotation); + }); + am->AddAction(AzToolsFramework::EditModeScale, tr("Scale")) .SetIcon(Style::icon("Scale")) .SetApplyHoverEffect() .SetShortcut(tr("3")) .SetToolTip(tr("Scale (3)")) .SetCheckable(true) .SetStatusTip(tr("Select and scale selected object(s)")) - .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateEditmodeScale); + .RegisterUpdateCallback([](QAction* action) + { + Q_ASSERT(action->isCheckable()); - am->AddAction(ID_SNAP_TO_GRID, tr("Snap to grid")) + AzToolsFramework::EditorTransformComponentSelectionRequests::Mode mode; + AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult( + mode, AzToolsFramework::GetEntityContextId(), + &AzToolsFramework::EditorTransformComponentSelectionRequests::GetTransformMode); + + action->setChecked(mode == AzToolsFramework::EditorTransformComponentSelectionRequests::Mode::Scale); + }) + .Connect( &QAction::triggered,[]() + { + EditorTransformComponentSelectionRequestBus::Event( + GetEntityContextId(), &EditorTransformComponentSelectionRequests::SetTransformMode, + EditorTransformComponentSelectionRequests::Mode::Scale); + }); + + am->AddAction(AzToolsFramework::SnapToGrid, tr("Snap to grid")) .SetIcon(Style::icon("Grid")) .SetApplyHoverEffect() .SetShortcut(tr("G")) @@ -769,7 +822,7 @@ void MainWindow::InitActions() }) .Connect(&QAction::triggered, []() { SandboxEditor::SetGridSnapping(!SandboxEditor::GridSnappingEnabled()); }); - am->AddAction(ID_SNAPANGLE, tr("Snap angle")) + am->AddAction(AzToolsFramework::SnapAngle, tr("Snap angle")) .SetIcon(Style::icon("Angle")) .SetApplyHoverEffect() .SetStatusTip(tr("Snap angle")) diff --git a/Code/Editor/MainWindow.h b/Code/Editor/MainWindow.h index e70355827c..1e375b08f2 100644 --- a/Code/Editor/MainWindow.h +++ b/Code/Editor/MainWindow.h @@ -59,11 +59,17 @@ namespace AzQtComponents namespace AzToolsFramework { class Ticker; -} - -namespace AzToolsFramework -{ class QtSourceControlNotificationHandler; + + //! @name Reverse URLs. + //! Used to identify common actions and override them when necessary. + //@{ + constexpr inline AZ::Crc32 EditModeMove = AZ_CRC_CE("com.o3de.action.editor.editmode.move"); + constexpr inline AZ::Crc32 EditModeRotate = AZ_CRC_CE("com.o3de.action.editor.editmode.rotate"); + constexpr inline AZ::Crc32 EditModeScale = AZ_CRC_CE("com.o3de.action.editor.editmode.scale"); + constexpr inline AZ::Crc32 SnapToGrid = AZ_CRC_CE("com.o3de.action.editor.snaptogrid"); + constexpr inline AZ::Crc32 SnapAngle = AZ_CRC_CE("com.o3de.action.editor.snapangle"); + //@} } #define MAINFRM_LAYOUT_NORMAL "NormalLayout" diff --git a/Code/Editor/Objects/DisplayContextShared.inl b/Code/Editor/Objects/DisplayContextShared.inl index 1791c22443..a602d8eca9 100644 --- a/Code/Editor/Objects/DisplayContextShared.inl +++ b/Code/Editor/Objects/DisplayContextShared.inl @@ -74,12 +74,12 @@ void DisplayContext::DrawTri(const Vec3& p1, const Vec3& p2, const Vec3& p3) void DisplayContext::DrawTriangles(const AZStd::vector& vertices, const ColorB& color) { - pRenderAuxGeom->DrawTriangles(vertices.begin(), vertices.size(), color); + pRenderAuxGeom->DrawTriangles(vertices.begin(), static_cast(vertices.size()), color); } void DisplayContext::DrawTrianglesIndexed(const AZStd::vector& vertices, const AZStd::vector& indices, const ColorB& color) { - pRenderAuxGeom->DrawTriangles(vertices.begin(), vertices.size(), indices.begin(), indices.size(), color); + pRenderAuxGeom->DrawTriangles(vertices.begin(), static_cast(vertices.size()), indices.begin(), static_cast(indices.size()), color); } ////////////////////////////////////////////////////////////////////////// @@ -862,7 +862,7 @@ void DisplayContext::DrawLine(const Vec3& p1, const Vec3& p2, const QColor& rgb1 ////////////////////////////////////////////////////////////////////////// void DisplayContext::DrawLines(const AZStd::vector& points, const ColorF& color) { - pRenderAuxGeom->DrawLines(points.begin(), points.size(), color, m_thickness); + pRenderAuxGeom->DrawLines(points.begin(), static_cast(points.size()), color, m_thickness); } ////////////////////////////////////////////////////////////////////////// @@ -1287,8 +1287,8 @@ void DisplayContext::Flush2D() uvs[3] = 0; uvt[3] = 0; - int nLabels = m_textureLabels.size(); - for (int i = 0; i < nLabels; i++) + const size_t nLabels = m_textureLabels.size(); + for (size_t i = 0; i < nLabels; i++) { STextureLabel& t = m_textureLabels[i]; float w2 = t.w * 0.5f; diff --git a/Code/Editor/Objects/EntityObject.h b/Code/Editor/Objects/EntityObject.h index 76bd71a1f1..34d3342ad4 100644 --- a/Code/Editor/Objects/EntityObject.h +++ b/Code/Editor/Objects/EntityObject.h @@ -163,7 +163,7 @@ public: ////////////////////////////////////////////////////////////////////////// //! Return number of event targets of Script. - int GetEventTargetCount() const { return m_eventTargets.size(); }; + int GetEventTargetCount() const { return static_cast(m_eventTargets.size()); }; CEntityEventTarget& GetEventTarget(int index) { return m_eventTargets[index]; }; //! Add new event target, returns index of created event target. //! Event targets are Always entities. @@ -176,7 +176,7 @@ public: // Entity Links. ////////////////////////////////////////////////////////////////////////// //! Return number of event targets of Script. - int GetEntityLinkCount() const { return m_links.size(); }; + int GetEntityLinkCount() const { return static_cast(m_links.size()); }; CEntityLink& GetEntityLink(int index) { return m_links[index]; }; virtual int AddEntityLink(const QString& name, GUID targetEntityId); virtual bool EntityLinkExists(const QString& name, GUID targetEntityId); diff --git a/Code/Editor/Objects/ObjectLoader.h b/Code/Editor/Objects/ObjectLoader.h index 350ffa10a9..ccfaeb78f0 100644 --- a/Code/Editor/Objects/ObjectLoader.h +++ b/Code/Editor/Objects/ObjectLoader.h @@ -70,7 +70,7 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING CBaseObject* LoadObject(const XmlNodeRef& objNode, CBaseObject* pPrevObject = NULL); ////////////////////////////////////////////////////////////////////////// - int GetLoadedObjectsCount() { return m_loadedObjects.size(); } + int GetLoadedObjectsCount() { return static_cast(m_loadedObjects.size()); } CBaseObject* GetLoadedObject(int nIndex) const { return m_loadedObjects[nIndex].pObject; } //! If true new loaded objects will be assigned new GUIDs. diff --git a/Code/Editor/Objects/ObjectManager.h b/Code/Editor/Objects/ObjectManager.h index f59f6c43b8..aa9faab0e4 100644 --- a/Code/Editor/Objects/ObjectManager.h +++ b/Code/Editor/Objects/ObjectManager.h @@ -58,7 +58,7 @@ public: class CBaseObjectsCache { public: - int GetObjectCount() const { return m_objects.size(); } + int GetObjectCount() const { return static_cast(m_objects.size()); } CBaseObject* GetObject(int nIndex) const { return m_objects[nIndex]; } void AddObject(CBaseObject* object); diff --git a/Code/Editor/Objects/SelectionGroup.h b/Code/Editor/Objects/SelectionGroup.h index 8f6feb32ad..600bce5f26 100644 --- a/Code/Editor/Objects/SelectionGroup.h +++ b/Code/Editor/Objects/SelectionGroup.h @@ -71,7 +71,7 @@ public: //! And save resulting objects to saveTo selection. void FilterParents(); //! Get number of child filtered objects. - int GetFilteredCount() const { return m_filtered.size(); } + int GetFilteredCount() const { return static_cast(m_filtered.size()); } CBaseObject* GetFilteredObject(int i) const { return m_filtered[i]; } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index 874868b5bc..ead320367e 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -803,7 +803,7 @@ void SandboxIntegrationManager::SetupLayerContextMenu(QMenu* menu) menu->addSeparator(); - const int selectedLayerCount = layersInSelection.size(); + const int selectedLayerCount = static_cast(layersInSelection.size()); QString saveTitle = QObject::tr("Save layer"); if(selectedLayerCount > 1) { diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp index 50d111d9b3..02d2174fb8 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp @@ -259,7 +259,7 @@ QVariant OutlinerListModel::dataForName(const QModelIndex& index, int role) cons if (highlightTextIndex >= 0) { const QString BACKGROUND_COLOR{ "#707070" }; - label.insert(highlightTextIndex + m_filterString.length(), ""); + label.insert(static_cast(highlightTextIndex + m_filterString.length()), ""); label.insert(highlightTextIndex, ""); } } while(highlightTextIndex > 0); diff --git a/Code/Editor/Plugins/PerforcePlugin/PasswordDlg.cpp b/Code/Editor/Plugins/PerforcePlugin/PasswordDlg.cpp index f1f742949c..6e9c0a42b0 100644 --- a/Code/Editor/Plugins/PerforcePlugin/PasswordDlg.cpp +++ b/Code/Editor/Plugins/PerforcePlugin/PasswordDlg.cpp @@ -53,7 +53,7 @@ namespace PerforceConnection setEnabled(false); - int numSettingsToGet = m_retrievedSettings.size(); + int numSettingsToGet = static_cast(m_retrievedSettings.size()); auto applySettingResultFunction = [this, &numSettingsToGet](AZStd::string setting, const SourceControlSettingInfo& info) -> void { diff --git a/Code/Editor/RenderHelpers/AxisHelperShared.inl b/Code/Editor/RenderHelpers/AxisHelperShared.inl index 9db4c82e84..2ceac98eae 100644 --- a/Code/Editor/RenderHelpers/AxisHelperShared.inl +++ b/Code/Editor/RenderHelpers/AxisHelperShared.inl @@ -546,7 +546,7 @@ bool CAxisHelper::HitTestForRotationCircle(const Matrix34& worldTM, IDisplayView Vec3 vShortestHitPos; float shortestDist = 3e11f; - for (int i = 0, iCount(vList.size()); i < iCount; ++i) + for (int i = 0, iCount(static_cast(vList.size())); i < iCount; ++i) { const Vec3& v0 = vList[i]; const Vec3& v1 = vList[(i + 1) % iCount]; diff --git a/Code/Editor/RenderViewport.cpp b/Code/Editor/RenderViewport.cpp index d268a57684..47e5106221 100644 --- a/Code/Editor/RenderViewport.cpp +++ b/Code/Editor/RenderViewport.cpp @@ -2342,7 +2342,7 @@ bool CRenderViewport::AddCameraMenuItems(QMenu* menu) AZ::EBusAggregateResults getCameraResults; Camera::CameraBus::BroadcastResult(getCameraResults, &Camera::CameraRequests::GetCameras); - const int numCameras = getCameraResults.values.size(); + const int numCameras = static_cast(getCameraResults.values.size()); // only enable if we're editing a sequence in Track View and have cameras in the level bool enableSequenceCameraMenu = (GetIEditor()->GetAnimation()->GetSequence() && numCameras); @@ -2354,7 +2354,7 @@ bool CRenderViewport::AddCameraMenuItems(QMenu* menu) connect(action, &QAction::triggered, this, &CRenderViewport::SetSequenceCamera); QVector additionalCameras; - additionalCameras.reserve(getCameraResults.values.size()); + additionalCameras.reserve(static_cast(getCameraResults.values.size())); for (const AZ::EntityId& entityId : getCameraResults.values) { @@ -2930,7 +2930,7 @@ void CRenderViewport::RenderSelectedRegion() // Draw volume dc.DepthWriteOff(); dc.CullOff(); - dc.pRenderAuxGeom->DrawTriangles(&verts[0], verts.size(), &inds[0], numInds, &colors[0]); + dc.pRenderAuxGeom->DrawTriangles(&verts[0], static_cast(verts.size()), &inds[0], numInds, &colors[0]); dc.CullOn(); dc.DepthWriteOn(); } diff --git a/Code/Editor/RenderViewport.h b/Code/Editor/RenderViewport.h index c66d56176e..d63f319276 100644 --- a/Code/Editor/RenderViewport.h +++ b/Code/Editor/RenderViewport.h @@ -275,19 +275,19 @@ public: m_relCameraRotX = 0; m_relCameraRotZ = 0; - uint32 numSample6 = m_arrAnimatedCharacterPath.size(); + uint32 numSample6 = static_cast(m_arrAnimatedCharacterPath.size()); for (uint32 i = 0; i < numSample6; i++) { m_arrAnimatedCharacterPath[i] = Vec3(ZERO); } - numSample6 = m_arrSmoothEntityPath.size(); + numSample6 = static_cast(m_arrSmoothEntityPath.size()); for (uint32 i = 0; i < numSample6; i++) { m_arrSmoothEntityPath[i] = Vec3(ZERO); } - uint32 numSample7 = m_arrRunStrafeSmoothing.size(); + uint32 numSample7 = static_cast(m_arrRunStrafeSmoothing.size()); for (uint32 i = 0; i < numSample7; i++) { m_arrRunStrafeSmoothing[i] = 0; diff --git a/Code/Editor/Resource.h b/Code/Editor/Resource.h index a6f714afa4..b3640fac70 100644 --- a/Code/Editor/Resource.h +++ b/Code/Editor/Resource.h @@ -82,7 +82,6 @@ #define ID_TOOLS_CUSTOMIZEKEYBOARD 32914 #define ID_EXPORT_INDOORS 32915 #define ID_VIEW_CYCLE2DVIEWPORT 32916 -#define ID_SNAPANGLE 32917 #define ID_PHYSICS_GETPHYSICSSTATE 32937 #define ID_PHYSICS_RESETPHYSICSSTATE 32938 #define ID_GAME_SYNCPLAYER 32941 @@ -108,9 +107,6 @@ #define ID_MOVE_OBJECT 33481 #define ID_RENAME_OBJ 33483 #define ID_FETCH 33496 -#define ID_EDITMODE_ROTATE 33506 -#define ID_EDITMODE_SCALE 33507 -#define ID_EDITMODE_MOVE 33508 #define ID_SELECTION_DELETE 33512 #define ID_EDIT_ESCAPE 33513 #define ID_UNDO 33524 @@ -137,7 +133,6 @@ #define ID_ADDNODE 33570 #define ID_ADDSCENETRACK 33573 #define ID_FIND 33574 -#define ID_SNAP_TO_GRID 33575 #define ID_TAG_LOC1 33576 #define ID_TAG_LOC2 33577 #define ID_TAG_LOC3 33578 diff --git a/Code/Editor/Settings.cpp b/Code/Editor/Settings.cpp index ae4fa75d41..50b1e77150 100644 --- a/Code/Editor/Settings.cpp +++ b/Code/Editor/Settings.cpp @@ -189,6 +189,7 @@ SEditorSettings::SEditorSettings() consoleBackgroundColorTheme = AzToolsFramework::ConsoleColorTheme::Dark; bShowTimeInConsole = false; + clearConsoleOnGameModeStart = false; enableSceneInspector = false; @@ -527,6 +528,8 @@ void SEditorSettings::Save() SaveValue("Settings", "ConsoleBackgroundColorThemeV2", (int)consoleBackgroundColorTheme); + SaveValue("Settings", "ClearConsoleOnGameModeStart", clearConsoleOnGameModeStart); + SaveValue("Settings", "ShowTimeInConsole", bShowTimeInConsole); SaveValue("Settings", "EnableSceneInspector", enableSceneInspector); @@ -729,6 +732,8 @@ void SEditorSettings::Load() consoleBackgroundColorTheme = AzToolsFramework::ConsoleColorTheme::Dark; } + LoadValue("Settings", "ClearConsoleOnGameModeStart", clearConsoleOnGameModeStart); + LoadValue("Settings", "ShowTimeInConsole", bShowTimeInConsole); LoadValue("Settings", "EnableSceneInspector", enableSceneInspector); @@ -1067,7 +1072,7 @@ void SEditorSettings::ConvertPath(const AZStd::string_view sourcePath, AZStd::st AzToolsFramework::EditorSettingsAPIRequests::SettingOutcome SEditorSettings::GetValue(const AZStd::string_view path) { - if (path.find("|") < 0) + if (path.find("|") == AZStd::string_view::npos) { return { AZStd::string("Invalid Path - could not find separator \"|\"") }; } @@ -1085,7 +1090,7 @@ AzToolsFramework::EditorSettingsAPIRequests::SettingOutcome SEditorSettings::Get AzToolsFramework::EditorSettingsAPIRequests::SettingOutcome SEditorSettings::SetValue(const AZStd::string_view path, const AZStd::any& value) { - if (path.find("|") < 0) + if (path.find("|") == AZStd::string_view::npos) { return { AZStd::string("Invalid Path - could not find separator \"|\"") }; } diff --git a/Code/Editor/Settings.h b/Code/Editor/Settings.h index 979820e5e6..39a4093915 100644 --- a/Code/Editor/Settings.h +++ b/Code/Editor/Settings.h @@ -380,6 +380,7 @@ AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING //! Source Control Enabling. bool enableSourceControl; + bool clearConsoleOnGameModeStart; //! Text editor. QString textEditorForScript; diff --git a/Code/Editor/TrackView/TrackViewAnimNode.h b/Code/Editor/TrackView/TrackViewAnimNode.h index 475307ffa9..466e60bcf0 100644 --- a/Code/Editor/TrackView/TrackViewAnimNode.h +++ b/Code/Editor/TrackView/TrackViewAnimNode.h @@ -27,7 +27,7 @@ class QWidget; class CTrackViewAnimNodeBundle { public: - unsigned int GetCount() const { return m_animNodes.size(); } + unsigned int GetCount() const { return static_cast(m_animNodes.size()); } CTrackViewAnimNode* GetNode(const unsigned int index) { return m_animNodes[index]; } const CTrackViewAnimNode* GetNode(const unsigned int index) const { return m_animNodes[index]; } diff --git a/Code/Editor/TrackView/TrackViewNode.h b/Code/Editor/TrackView/TrackViewNode.h index 600a66877f..2c289049e9 100644 --- a/Code/Editor/TrackView/TrackViewNode.h +++ b/Code/Editor/TrackView/TrackViewNode.h @@ -123,7 +123,7 @@ public: virtual bool AreAllKeysOfSameType() const override { return m_bAllOfSameType; } - virtual unsigned int GetKeyCount() const override { return m_keys.size(); } + virtual unsigned int GetKeyCount() const override { return static_cast(m_keys.size()); } virtual CTrackViewKeyHandle GetKey(unsigned int index) override { return m_keys[index]; } virtual void SelectKeys(const bool bSelected) override; @@ -174,7 +174,7 @@ public: CTrackViewNode* GetParentNode() const { return m_pParentNode; } // Children - unsigned int GetChildCount() const { return m_childNodes.size(); } + unsigned int GetChildCount() const { return static_cast(m_childNodes.size()); } CTrackViewNode* GetChild(unsigned int index) const { return m_childNodes[index].get(); } // Snap time value to prev/next key in sequence diff --git a/Code/Editor/TrackView/TrackViewSequenceManager.h b/Code/Editor/TrackView/TrackViewSequenceManager.h index b181cf54b1..21c10f009a 100644 --- a/Code/Editor/TrackView/TrackViewSequenceManager.h +++ b/Code/Editor/TrackView/TrackViewSequenceManager.h @@ -29,7 +29,7 @@ public: virtual void OnEditorNotifyEvent(EEditorNotifyEvent event); - unsigned int GetCount() const { return m_sequences.size(); } + unsigned int GetCount() const { return static_cast(m_sequences.size()); } void CreateSequence(QString name, SequenceType sequenceType); void DeleteSequence(CTrackViewSequence* pSequence); diff --git a/Code/Editor/TrackView/TrackViewTrack.h b/Code/Editor/TrackView/TrackViewTrack.h index 0c1f13274c..bbe81f6377 100644 --- a/Code/Editor/TrackView/TrackViewTrack.h +++ b/Code/Editor/TrackView/TrackViewTrack.h @@ -27,7 +27,7 @@ public: : m_bAllOfSameType(true) , m_bHasRotationTrack(false) {} - unsigned int GetCount() const { return m_tracks.size(); } + unsigned int GetCount() const { return static_cast(m_tracks.size()); } CTrackViewTrack* GetTrack(const unsigned int index) { return m_tracks[index]; } const CTrackViewTrack* GetTrack(const unsigned int index) const { return m_tracks[index]; } diff --git a/Code/Editor/Undo/Undo.h b/Code/Editor/Undo/Undo.h index 3f943f7a82..594d3b3f3d 100644 --- a/Code/Editor/Undo/Undo.h +++ b/Code/Editor/Undo/Undo.h @@ -61,12 +61,12 @@ public: // Confetti: Get the size of m_undoObjects virtual int GetCount() const { - return m_undoObjects.size(); + return static_cast(m_undoObjects.size()); } virtual bool IsEmpty() const { return m_undoObjects.empty(); }; virtual void Undo(bool bUndo) { - for (int i = m_undoObjects.size() - 1; i >= 0; i--) + for (int i = static_cast(m_undoObjects.size() - 1); i >= 0; i--) { m_undoObjects[i]->Undo(bUndo); } diff --git a/Code/Editor/ViewManager.h b/Code/Editor/ViewManager.h index 22f9f6804f..434c38df2f 100644 --- a/Code/Editor/ViewManager.h +++ b/Code/Editor/ViewManager.h @@ -86,7 +86,7 @@ public: ////////////////////////////////////////////////////////////////////////// //! Get number of currently existing viewports. - virtual int GetViewCount() { return m_viewports.size(); }; + virtual int GetViewCount() { return static_cast(m_viewports.size()); }; //! Get viewport by index. //! @param index 0 <= index < GetViewportCount() virtual CViewport* GetView(int index) { return m_viewports[index]; } diff --git a/Code/Editor/ViewportTitleDlg.cpp b/Code/Editor/ViewportTitleDlg.cpp index 4d27506929..c1e1afb908 100644 --- a/Code/Editor/ViewportTitleDlg.cpp +++ b/Code/Editor/ViewportTitleDlg.cpp @@ -953,13 +953,13 @@ void CViewportTitleDlg::CheckForCameraSpeedUpdate() void CViewportTitleDlg::OnGridSnappingToggled() { m_gridSizeActionWidget->setEnabled(m_enableGridSnappingAction->isChecked()); - MainWindow::instance()->GetActionManager()->GetAction(ID_SNAP_TO_GRID)->trigger(); + MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->trigger(); } void CViewportTitleDlg::OnAngleSnappingToggled() { m_angleSizeActionWidget->setEnabled(m_enableAngleSnappingAction->isChecked()); - MainWindow::instance()->GetActionManager()->GetAction(ID_SNAPANGLE)->trigger(); + MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->trigger(); } void CViewportTitleDlg::OnGridSpinBoxChanged(double value) @@ -974,14 +974,14 @@ void CViewportTitleDlg::OnAngleSpinBoxChanged(double value) void CViewportTitleDlg::UpdateOverFlowMenuState() { - bool gridSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(ID_SNAP_TO_GRID)->isChecked(); + bool gridSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->isChecked(); { QSignalBlocker signalBlocker(m_enableGridSnappingAction); m_enableGridSnappingAction->setChecked(gridSnappingActive); } m_gridSizeActionWidget->setEnabled(gridSnappingActive); - bool angleSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(ID_SNAPANGLE)->isChecked(); + bool angleSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->isChecked(); { QSignalBlocker signalBlocker(m_enableAngleSnappingAction); m_enableAngleSnappingAction->setChecked(angleSnappingActive); diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp index 6e46b930b6..f358370be5 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.cpp @@ -47,7 +47,7 @@ namespace AZ } auto stackEntry = AZStd::make_shared( - cacheSize, blockSize, aznumeric_caster(hardware.m_maxPhysicalSectorSize), false); + cacheSize, aznumeric_cast(blockSize), aznumeric_cast(hardware.m_maxPhysicalSectorSize), false); stackEntry->SetNext(AZStd::move(parent)); return stackEntry; } diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp index 5b67c8c255..6ec3fb295c 100644 --- a/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp +++ b/Code/Framework/AzCore/AzCore/IO/Streamer/DedicatedCache.cpp @@ -45,7 +45,7 @@ namespace AZ } auto stackEntry = AZStd::make_shared( - cacheSize, blockSize, aznumeric_caster(hardware.m_maxPhysicalSectorSize), m_writeOnlyEpilog); + cacheSize, aznumeric_cast(blockSize), aznumeric_cast(hardware.m_maxPhysicalSectorSize), m_writeOnlyEpilog); stackEntry->SetNext(AZStd::move(parent)); return stackEntry; } diff --git a/Code/Framework/AzCore/AzCore/Math/Aabb.h b/Code/Framework/AzCore/AzCore/Math/Aabb.h index 8d8ded7b2d..488808bc4c 100644 --- a/Code/Framework/AzCore/AzCore/Math/Aabb.h +++ b/Code/Framework/AzCore/AzCore/Math/Aabb.h @@ -43,7 +43,7 @@ namespace AZ static Aabb CreateCenterRadius(const Vector3& center, float radius); //! Creates an AABB which contains the specified points. - static Aabb CreatePoints(const Vector3* pts, int numPts); + static Aabb CreatePoints(const Vector3* pts, size_t numPts); //! Creates an AABB which contains the specified OBB. static Aabb CreateFromObb(const Obb& obb); diff --git a/Code/Framework/AzCore/AzCore/Math/Aabb.inl b/Code/Framework/AzCore/AzCore/Math/Aabb.inl index 5806857bb1..3ce7b99792 100644 --- a/Code/Framework/AzCore/AzCore/Math/Aabb.inl +++ b/Code/Framework/AzCore/AzCore/Math/Aabb.inl @@ -60,10 +60,10 @@ namespace AZ } - AZ_MATH_INLINE Aabb Aabb::CreatePoints(const Vector3* pts, int numPts) + AZ_MATH_INLINE Aabb Aabb::CreatePoints(const Vector3* pts, size_t numPts) { Aabb aabb = Aabb::CreateFromPoint(pts[0]); - for (int i = 1; i < numPts; ++i) + for (size_t i = 1; i < numPts; ++i) { aabb.AddPoint(pts[i]); } diff --git a/Code/Framework/AzCore/AzCore/Module/Environment.cpp b/Code/Framework/AzCore/AzCore/Module/Environment.cpp index f3a3533f4a..bec530e2d1 100644 --- a/Code/Framework/AzCore/AzCore/Module/Environment.cpp +++ b/Code/Framework/AzCore/AzCore/Module/Environment.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace AZ { @@ -75,6 +76,42 @@ namespace AZ bool operator==(const OSStdAllocator& a, const OSStdAllocator& b) { (void)a; (void)b; return true; } bool operator!=(const OSStdAllocator& a, const OSStdAllocator& b) { (void)a; (void)b; return false; } + void EnvironmentVariableHolderBase::UnregisterAndDestroy(DestructFunc destruct, bool moduleRelease) + { + const bool releaseByUseCount = (--m_useCount == 0); + // We take over the lock, and release it before potentially destroying/freeing ourselves + { + AZStd::scoped_lock envLockHolder(AZStd::adopt_lock, m_mutex); + const bool releaseByModule = (moduleRelease && !m_canTransferOwnership && m_moduleOwner == AZ::Environment::GetModuleId()); + + if (!releaseByModule && !releaseByUseCount) + { + return; + } + // if the environment that created us is gone the owner can be null + // which means (assuming intermodule allocator) that the variable is still alive + // but can't be found as it's not part of any environment. + if (m_environmentOwner) + { + m_environmentOwner->RemoveVariable(m_guid); + m_environmentOwner = nullptr; + } + if (m_isConstructed) + { + destruct(this, DestroyTarget::Member); // destruct the value + } + } + // m_mutex is no longer held here, envLockHolder has released it above. + if (releaseByUseCount) + { + // m_mutex is unlocked before this is deleted + Environment::AllocatorInterface* allocator = m_allocator; + // Call child class dtor and clear the memory + destruct(this, DestroyTarget::Self); + allocator->DeAllocate(this); + } + } + // instance of the environment EnvironmentInterface* EnvironmentInterface::s_environment = nullptr; @@ -110,7 +147,7 @@ namespace AZ #ifdef AZ_ENVIRONMENT_VALIDATE_ON_EXIT AZ_Assert(m_numAttached == 0, "We should not delete an environment while there are %d modules attached! Unload all DLLs first!", m_numAttached); #endif - + for (auto variableIt : m_variableMap) { EnvironmentVariableHolderBase* holder = reinterpret_cast(variableIt.second); diff --git a/Code/Framework/AzCore/AzCore/Module/Environment.h b/Code/Framework/AzCore/AzCore/Module/Environment.h index b0711b1bbe..e87ff81446 100644 --- a/Code/Framework/AzCore/AzCore/Module/Environment.h +++ b/Code/Framework/AzCore/AzCore/Module/Environment.h @@ -200,6 +200,11 @@ namespace AZ class EnvironmentVariableHolderBase { friend class EnvironmentImpl; + protected: + enum class DestroyTarget { + Member, + Self + }; public: EnvironmentVariableHolderBase(u32 guid, AZ::Internal::EnvironmentInterface* environmentOwner, bool canOwnershipTransfer, Environment::AllocatorInterface* allocator) : m_environmentOwner(environmentOwner) @@ -217,12 +222,21 @@ namespace AZ return m_isConstructed; } + bool IsOwner() const + { + return m_moduleOwner == Environment::GetModuleId(); + } + u32 GetId() const { return m_guid; } - protected: + using DestructFunc = void (*)(EnvironmentVariableHolderBase *, DestroyTarget); + // Assumes the m_mutex is already locked. + // On return m_mutex is in an unlocked state. + void UnregisterAndDestroy(DestructFunc destruct, bool moduleRelease); + AZ::Internal::EnvironmentInterface* m_environmentOwner; ///< Used to know which environment we should use to free the variable if we can't transfer ownership void* m_moduleOwner; ///< Used when the variable can't transfered across module and we need to destruct the variable when the module is going away bool m_canTransferOwnership; ///< True if variable can be allocated in one module and freed in other. Usually true for POD types when they share allocator. @@ -242,41 +256,29 @@ namespace AZ memset(&m_value, 0, sizeof(T)); } - template + template void ConstructImpl(const AZStd::false_type& /* AZStd::has_trivial_constructor */, Args&&... args) { // Construction of non-trivial types is left up to the type's constructor. new(&m_value) T(AZStd::forward(args)...); } - - void DestructImpl(const AZStd::true_type& /* AZStd::is_trivially_destructible */) + static void DestructDispatchNoLock(EnvironmentVariableHolderBase *base, DestroyTarget selfDestruct) { - // do nothing - } - - void DestructImpl(const AZStd::false_type& /* AZStd::is_trivially_destructible */) - { - reinterpret_cast(&m_value)->~T(); - } - - // Assumes the lock is already held - void UnregisterAndDestruct() - { - // if the environment that created us is gone the owner can be null - // which means (assuming intermodule allocator) that the variable is still alive - // but can't be found as it's not part of any environment. - if (m_environmentOwner) + auto *self = reinterpret_cast(base); + if (selfDestruct == DestroyTarget::Self) { - m_environmentOwner->RemoveVariable(m_guid); - m_environmentOwner = nullptr; + self->~EnvironmentVariableHolder(); + return; } - if (m_isConstructed) + AZ_Assert(self->m_isConstructed, "Variable is not constructed. Please check your logic and guard if needed!"); + self->m_isConstructed = false; + self->m_moduleOwner = nullptr; + if constexpr(!AZStd::is_trivially_destructible_v) { - DestructNoLock(); + reinterpret_cast(&self->m_value)->~T(); } } - public: EnvironmentVariableHolder(u32 guid, bool isOwnershipTransfer, Environment::AllocatorInterface* allocator) : EnvironmentVariableHolderBase(guid, Environment::GetInstance(), isOwnershipTransfer, allocator) @@ -287,12 +289,6 @@ namespace AZ { AZ_Assert(!m_isConstructed, "To get the destructor we should have already destructed the variable!"); } - - bool IsOwner() const - { - return m_moduleOwner == Environment::GetModuleId(); - } - void AddRef() { AZStd::lock_guard lock(m_mutex); @@ -303,30 +299,8 @@ namespace AZ void Release() { m_mutex.lock(); - - if (--s_moduleUseCount == 0) - { - if (!m_canTransferOwnership && m_moduleOwner == AZ::Environment::GetModuleId()) - { - UnregisterAndDestruct(); - } - } - - if (--m_useCount == 0) - { - UnregisterAndDestruct(); - - // unlock before this is deleted - m_mutex.unlock(); - - Environment::AllocatorInterface* allocator = m_allocator; - // Call dtor and clear the memory - this->~EnvironmentVariableHolder(); - allocator->DeAllocate(this); - return; - } - - m_mutex.unlock(); + const bool moduleRelease = (--s_moduleUseCount == 0); + UnregisterAndDestroy(DestructDispatchNoLock, moduleRelease); } void Construct() @@ -352,18 +326,10 @@ namespace AZ } } - void DestructNoLock() - { - AZ_Assert(m_isConstructed, "Variable is not constructed. Please check your logic and guard if needed!"); - m_isConstructed = false; - m_moduleOwner = nullptr; - DestructImpl(typename AZStd::is_trivially_destructible::type()); - } - void Destruct() { AZStd::lock_guard lock(m_mutex); - DestructNoLock(); + DestructDispatchNoLock(this, DestroyTarget::Member); } // variable storage diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ByteStreamSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/ByteStreamSerializer.cpp index c6fe112c6f..1c472ef901 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/ByteStreamSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ByteStreamSerializer.cpp @@ -71,7 +71,7 @@ namespace AZ if (context.ShouldKeepDefaults() || !defaultValue || (valAsByteStream != *static_cast(defaultValue))) { const auto base64ByteStream = AZ::StringFunc::Base64::Encode(valAsByteStream.data(), valAsByteStream.size()); - outputValue.SetString(base64ByteStream.c_str(), base64ByteStream.size(), context.GetJsonAllocator()); + outputValue.SetString(base64ByteStream.c_str(), static_cast(base64ByteStream.size()), context.GetJsonAllocator()); return context.Report(Tasks::WriteValue, Outcomes::Success, "ByteStream successfully stored."); } diff --git a/Code/Framework/AzCore/AzCore/std/chrono/types.h b/Code/Framework/AzCore/AzCore/std/chrono/types.h index c86c684426..19ef2c8469 100644 --- a/Code/Framework/AzCore/AzCore/std/chrono/types.h +++ b/Code/Framework/AzCore/AzCore/std/chrono/types.h @@ -211,7 +211,7 @@ namespace AZStd // 20.9.3.2, observer: constexpr rep count() const { return m_rep; } // 20.9.3.3, arithmetic: - constexpr duration operator+() const { *this; } + constexpr duration operator+() const { return *this; } constexpr duration operator-() const { return duration(-m_rep); } constexpr duration& operator++() { ++m_rep; return *this; } constexpr duration operator++(int) { return duration(m_rep++); } diff --git a/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h b/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h index 746af8974e..31fbdd85e9 100644 --- a/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h +++ b/Code/Framework/AzCore/AzCore/std/containers/ring_buffer.h @@ -1056,7 +1056,7 @@ namespace AZStd inline void insert(const iterator& pos, ForwardIterator first, ForwardIterator last, const AZStd::forward_iterator_tag&) { size_type size = AZStd::distance(first, last); - AZSTD_CONTAINER_ASSERT(size >= 0, "AZStd::ring_buffer::insert - there are no elements to insert!"); + AZSTD_CONTAINER_ASSERT(first > last, "AZStd::ring_buffer::insert - there are no elements to insert!"); if (size == 0) { return; diff --git a/Code/Framework/AzCore/AzCore/std/hash.cpp b/Code/Framework/AzCore/AzCore/std/hash.cpp index c2f7a104d4..b5277de2f4 100644 --- a/Code/Framework/AzCore/AzCore/std/hash.cpp +++ b/Code/Framework/AzCore/AzCore/std/hash.cpp @@ -21,6 +21,7 @@ namespace AZStd 1610612741ul, 3221225473ul, 4294967291ul }; + // Bucket size suitable to hold n elements. AZStd::size_t hash_next_bucket_size(AZStd::size_t n) { const AZStd::size_t* first = prime_list; diff --git a/Code/Framework/AzCore/AzCore/std/hash_table.h b/Code/Framework/AzCore/AzCore/std/hash_table.h index 5b76b6cb82..c364720b3b 100644 --- a/Code/Framework/AzCore/AzCore/std/hash_table.h +++ b/Code/Framework/AzCore/AzCore/std/hash_table.h @@ -134,6 +134,7 @@ namespace AZStd void rehash(HashTable* table, size_type numBucketsMin) { size_type num_buckets = 0; + numBucketsMin = (AZStd::max)(numBucketsMin, (size_type)ceilf((float)m_list.size() / m_max_load_factor)); if (numBucketsMin != 0) @@ -143,7 +144,7 @@ namespace AZStd if (num_buckets == m_numBuckets) { - return; // no point + return; // no need yet to rehash } m_numBuckets = num_buckets; @@ -165,32 +166,43 @@ namespace AZStd while (!m_list.empty()) { cur = m_list.begin(); + typename list_type::iterator insertIter, curEnd(cur); + const typename HashTable::key_type& valueKey = Traits::key_from_value(*cur); - typename list_type::iterator newIter, iter(cur); size_type numValues = 1; - for (++iter; iter != last && table->m_keyEqual(Traits::key_from_value(*cur), Traits::key_from_value(*iter)); ++iter, ++numValues) + // Get the number of same consecutive elements in the table with same key, + // this allows range insertion of elements at once + for (++curEnd; curEnd != last && table->m_keyEqual(valueKey, Traits::key_from_value(*curEnd)); ++curEnd, ++numValues) { } - ; - const typename HashTable::key_type& valueKey = Traits::key_from_value(*cur); size_type newBucketIndex = table->bucket_from_hash(table->m_hasher(valueKey)); + + // newBucket.first holds the total number of elements in the bucket + // newBucket.second contains the pointer to the first element in the bucket vector_value_type& newBucket = newBuckets[newBucketIndex]; size_type numElements = newBucket.first; - newIter = newBucket.second; + insertIter = newBucket.second; + + // If we don't have elements in the bucket yet, transfer the elements directly if (numElements == 0) { - newList.splice(newList.begin(), m_list, cur, iter); + newList.splice(newList.begin(), m_list, cur, curEnd); newBucket.second = newList.begin(); } else { - if (!table->find_insert_position(valueKey, table->m_keyEqual, newIter, numElements, integral_constant())) + // Since there are elements already in the bucket, update `insertIter` to where the elements will need to be inserted. + if (!table->find_insert_position(valueKey, table->m_keyEqual, insertIter, numElements, integral_constant())) { - continue; + // An element was found but we don't allow for duplicate elements in this table. + // This happens when there was an insertion of two elements that are equal but have different hashes, + // which is undefined behavior for a hash table: ISO C++ N4713, section 23.14.15 - 5.3 + AZ_Assert(false, "Found a duplicate element when rehashing. " + "Review the hashing function for this type and make sure two equal elements always have the same hash"); } - newList.splice(newIter, m_list, cur, iter); + newList.splice(insertIter, m_list, cur, curEnd); } newBucket.first += numValues; @@ -251,15 +263,15 @@ namespace AZStd m_vector.set_allocator(typename vector_type::allocator_type(&m_allocator)); } - allocator_type m_allocator; ///< The single instance of the allocator shared between list and vector containers. - list_type m_list; ///< List with elements. - vector_type m_vector; ///< Buckets with list iterators. + allocator_type m_allocator; //!< The single instance of the allocator shared between list and vector containers. + list_type m_list; //!< List with elements. + vector_type m_vector; //!< Buckets with list iterators. private: - vector_value_type* m_buckets; ///< Current buckets array. (can point to the m_vector or m_startBucket). - size_type m_numBuckets; ///< Current number of buckets. - float m_max_load_factor; - vector_value_type m_startBucket; ///< Start bucket used for before we start dynamically allocate memory from m_vector. + vector_value_type* m_buckets; //!< Current buckets array. (can point to the m_vector or m_startBucket). + size_type m_numBuckets; //!< Current number of buckets. + float m_max_load_factor; //!< Maximum load (elements/buckets) before rehashing. + vector_value_type m_startBucket; //!< Start bucket used for before we start dynamically allocate memory from m_vector. }; /** @@ -321,8 +333,8 @@ namespace AZStd template AZ_FORCE_INLINE void rehash(HashTable*, size_type) {} - vector_type m_vector; ///< Buckets with list iterators. - list_type m_list; ///< List with elements. + vector_type m_vector; //!< Buckets with list iterators. + list_type m_list; //!< List with elements. }; } @@ -972,28 +984,32 @@ namespace AZStd rhs.clear(); } + // find_insert_position sets insertIter to where the element should be inserted + // and returns true if the element should be inserted, otherwise false template - bool find_insert_position(const ComparableToKey& keyCmp, const KeyEq& keyEq, iterator& iter, size_type numElements, const true_type& /* is multi elements */) + bool find_insert_position(const ComparableToKey& keyCmp, const KeyEq& keyEq, iterator& insertIter, size_type numElements, const true_type& /* is multi elements */) { - for (size_type i = 0; i < numElements; ++i, ++iter) + for (size_type i = 0; i < numElements; ++i, ++insertIter) { - if (keyEq(keyCmp, Traits::key_from_value(*iter))) + if (keyEq(keyCmp, Traits::key_from_value(*insertIter))) { - ++iter; + ++insertIter; break; } } + // always return true since multi elements (like multiset) allow repeated elements return true; } template - bool find_insert_position(const ComparableToKey& keyCmp, const KeyEq& keyEq, iterator& iter, size_type numElements, const false_type& /* !is multi elements */) + bool find_insert_position(const ComparableToKey& keyCmp, const KeyEq& keyEq, iterator& insertIter, size_type numElements, const false_type& /* !is multi elements */) { - for (size_type i = 0; i < numElements; ++i, ++iter) + for (size_type i = 0; i < numElements; ++i, ++insertIter) { - if (keyEq(keyCmp, Traits::key_from_value(*iter))) + if (keyEq(keyCmp, Traits::key_from_value(*insertIter))) { + // Element already exists, it shouldn't be inserted as we don't allow more than one repeated element for this specialization return false; } } diff --git a/Code/Framework/AzCore/AzCore/std/utils.h b/Code/Framework/AzCore/AzCore/std/utils.h index 2d098af55e..0de56cedcb 100644 --- a/Code/Framework/AzCore/AzCore/std/utils.h +++ b/Code/Framework/AzCore/AzCore/std/utils.h @@ -294,7 +294,7 @@ namespace AZStd T& m_v; constexpr addr_impl_ref(T& v) : m_v(v) {} - constexpr addr_impl_ref& operator=(const addr_impl_ref& v) { m_v = v; } + constexpr addr_impl_ref& operator=(const addr_impl_ref& v) { m_v = v; return *this; } constexpr operator T& () const { return m_v; } }; diff --git a/Code/Framework/AzCore/Tests/AZStd/Hashed.cpp b/Code/Framework/AzCore/Tests/AZStd/Hashed.cpp index f2558289ea..4e4dfc1f89 100644 --- a/Code/Framework/AzCore/Tests/AZStd/Hashed.cpp +++ b/Code/Framework/AzCore/Tests/AZStd/Hashed.cpp @@ -287,6 +287,55 @@ namespace UnitTest } } + TEST_F(HashedContainers, HashTable_InsertionDuplicateOnRehash) + { + struct TwoPtrs + { + void* m_ptr1; + void* m_ptr2; + + bool operator==(const TwoPtrs& other) const + { + if (m_ptr1 == other.m_ptr1) + { + return m_ptr2 == other.m_ptr2; + } + else if (m_ptr1 == other.m_ptr2) + { + return m_ptr2 == other.m_ptr1; + } + return false; + } + }; + + // This hashing function produces different hashes for two equal values, + // which violates the requirement for hashing functions. + // The test makes sure that this does not reproduce an issue that caused the insert() function to loop infinitely. + struct TwoPtrsHasher + { + size_t operator()(const TwoPtrs& p) const + { + size_t hash{ 0 }; + AZStd::hash_combine(hash, p.m_ptr1, p.m_ptr2); + return hash; + } + }; + using PairSet = AZStd::unordered_set; + PairSet set; + set.insert({ (void*)1, (void*)2 }); + set.insert({ (void*)3, (void*)4 }); + set.insert({ (void*)5, (void*)6 }); + set.insert({ (void*)7, (void*)8 }); + // Elements with different hashes, but equal + set.insert({ (void*)0x000001ceddd9ca20, (void*)0x000001ceddd9cba0 }); // hash(148335135725641) + set.insert({ (void*)0x000001ceddd9cba0, (void*)0x000001ceddd9ca20 }); // hash(148335135764189) + AZ_TEST_START_TRACE_SUPPRESSION; + // This will trigger the assertion of duplicated elements found + // A bucket size of 23 since is where the collision between different hashes happens + set.rehash(23); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // 1 assertion + } + TEST_F(HashedContainers, HashTable_Fixed) { array elements = { diff --git a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp index 156719b8a7..e25c3dbcf7 100644 --- a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp +++ b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp @@ -1150,7 +1150,7 @@ namespace UnitTest #if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS TEST_F(AssetJobsFloodTest, DISABLED_ContainerFilterTest_ContainersWithAndWithoutFiltering_Success) #else - TEST_F(AssetJobsFloodTest, ContainerFilterTest_ContainersWithAndWithoutFiltering_Success) + TEST_F(AssetJobsFloodTest, DISABLED_ContainerFilterTest_ContainersWithAndWithoutFiltering_Success) #endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS { m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect(); diff --git a/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponentHelper.cpp b/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponentHelper.cpp index 14ce16163a..f9411a1f8d 100644 --- a/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponentHelper.cpp +++ b/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponentHelper.cpp @@ -163,7 +163,11 @@ namespace AzFramework AZ_TracePrintfOnce("AssetSystemComponent", "Failed to find asset platform, setting 'pc'\n"); outputConnectionSettings.m_assetPlatform = "pc"; } - outputConnectionSettings.m_assetPlatform = assetsPlatform; + else + { + outputConnectionSettings.m_assetPlatform = assetsPlatform; + } + if (outputConnectionSettings.m_assetPlatform.empty()) { assetsPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME); diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp index 87353c5807..617eb3a0b9 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp @@ -227,8 +227,10 @@ namespace AzFramework EntitySpawnTicket::EntitySpawnTicket(EntitySpawnTicket&& rhs) : m_payload(rhs.m_payload) + , m_id(rhs.m_id) { rhs.m_payload = nullptr; + rhs.m_id = 0; } EntitySpawnTicket::EntitySpawnTicket(AZ::Data::Asset spawnable) diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Process/ProcessWatcher_Linux.cpp b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Process/ProcessWatcher_Linux.cpp index 51c256a9b3..8deed820d3 100644 --- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Process/ProcessWatcher_Linux.cpp +++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Process/ProcessWatcher_Linux.cpp @@ -269,7 +269,7 @@ namespace AzFramework int numEnvironmentVars = 0; if (processLaunchInfo.m_environmentVariables) { - const int numEnvironmentVars = processLaunchInfo.m_environmentVariables->size(); + numEnvironmentVars = processLaunchInfo.m_environmentVariables->size(); // Adding one more as exec expects the array to have a nullptr as the last element environmentVariables = new char*[numEnvironmentVars + 1]; for (int i = 0; i < numEnvironmentVars; i++) diff --git a/Code/Framework/AzFramework/Tests/OctreeTests.cpp b/Code/Framework/AzFramework/Tests/OctreeTests.cpp index 3faf98adfb..f248dbfa66 100644 --- a/Code/Framework/AzFramework/Tests/OctreeTests.cpp +++ b/Code/Framework/AzFramework/Tests/OctreeTests.cpp @@ -98,7 +98,7 @@ namespace UnitTest // If an entry is removed from the octree as an unintended side effect of updating an existing entry, // GetEntryCount can't be relied upon to report the actual entry count. // So manually count the entries when using the entry count for validation. - uint32_t manualEntryCount = 0; + size_t manualEntryCount = 0; visScene->EnumerateNoCull([&manualEntryCount](const AzFramework::IVisibilityScene::NodeData& nodeData) { manualEntryCount += nodeData.m_entries.size(); }); EXPECT_EQ(manualEntryCount, expectedEntryCount); @@ -409,7 +409,7 @@ namespace UnitTest } // Expect all the entries to be in the scene - ValidateEntryCountEqualsExpectedCount(m_octreeScene, visEntries.size()); + ValidateEntryCountEqualsExpectedCount(m_octreeScene, static_cast(visEntries.size())); // Update them, without making any actual changes for (AzFramework::VisibilityEntry& entry : visEntries) @@ -418,6 +418,6 @@ namespace UnitTest } // Expect all the entries to be in the scene - ValidateEntryCountEqualsExpectedCount(m_octreeScene, visEntries.size()); + ValidateEntryCountEqualsExpectedCount(m_octreeScene, static_cast(visEntries.size())); } } diff --git a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp index 7eff4b5eeb..f68af08f4a 100644 --- a/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp +++ b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp @@ -366,6 +366,24 @@ namespace UnitTest } } + TEST_F(SpawnableEntitiesManagerTest, EntitySpawnTicket_Move_Works) + { + AzFramework::EntitySpawnTicket ticket1(*m_spawnableAsset); + AzFramework::EntitySpawnTicket ticket2(*m_spawnableAsset); + + const AzFramework::EntitySpawnTicket::Id ticket1Id = ticket1.GetId(); + const AzFramework::EntitySpawnTicket::Id ticket2Id = ticket2.GetId(); + + AzFramework::EntitySpawnTicket ticketMoveConstructor(AZStd::move(ticket1)); + EXPECT_TRUE(ticketMoveConstructor.IsValid()); + EXPECT_EQ(ticketMoveConstructor.GetId(), ticket1Id); + + AzFramework::EntitySpawnTicket ticketMoveOperator; + ticketMoveOperator = AZStd::move(ticket2); + EXPECT_TRUE(ticketMoveOperator.IsValid()); + EXPECT_EQ(ticketMoveOperator.GetId(), ticket2Id); + } + TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_DeleteTicketBeforeCall_NoCrash) { { diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h index d47f76ceb8..09aa62f7d7 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h @@ -103,6 +103,14 @@ namespace AzNetworking //! @return boolean true on success virtual bool Disconnect(ConnectionId connectionId, DisconnectReason reason) = 0; + //! Sets whether this connection interface can disconnect by virtue of a timeout + //! @param timeoutEnabled If this connection interface will automatically disconnect due to a timeout + virtual void SetTimeoutEnabled(bool timeoutEnabled) = 0; + + //! Whether this connection interface will disconnect by virtue of a time out (does not account for cvars affecting all connections) + //! @return boolean true if this connection will not disconnect on timeout (does not account for cvars affecting all connections) + virtual bool IsTimeoutEnabled() const = 0; + //! Const access to the metrics tracked by this network interface. //! @return const reference to the metrics tracked by this network interface const NetworkInterfaceMetrics& GetMetrics() const; diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp index 1beb83e19f..6d7358a425 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp @@ -170,7 +170,7 @@ namespace AzNetworking } timeoutItem->UpdateTimeoutTime(startTimeMs); - NetworkOutputSerializer serializer(buffer.GetBuffer(), buffer.GetSize()); + NetworkOutputSerializer serializer(buffer.GetBuffer(), static_cast(buffer.GetSize())); if (m_state == ConnectionState::Connecting) { const ConnectResult connectResult = m_networkInterface.GetConnectionListener().ValidateConnect(GetRemoteAddress(), header, serializer); @@ -198,7 +198,7 @@ namespace AzNetworking { TcpPacketEncodingBuffer buffer; { - NetworkInputSerializer serializer(buffer.GetBuffer(), buffer.GetCapacity()); + NetworkInputSerializer serializer(buffer.GetBuffer(), static_cast(buffer.GetCapacity())); if (!const_cast(packet).Serialize(serializer)) { AZ_Assert(false, "SendReliablePacket: Unable to serialize packet [Type: %d]", packet.GetPacketType()); @@ -272,7 +272,7 @@ namespace AzNetworking { TcpPacketHeader header(packetType, aznumeric_cast(payloadBuffer.GetSize())); header.SetPacketFlag(PacketFlag::Compressed, shouldCompress); - NetworkInputSerializer serializer(headerBuffer.GetBuffer(), headerBuffer.GetCapacity()); + NetworkInputSerializer serializer(headerBuffer.GetBuffer(), static_cast(headerBuffer.GetCapacity())); if (!header.Serialize(serializer)) { return false; @@ -313,7 +313,7 @@ namespace AzNetworking m_networkInterface.GetMetrics().m_sendBytesCompressedDelta += (payloadSize - compressionMemBytesUsed); writeBuffer.Resize(aznumeric_cast(compressionMemBytesUsed)); - payloadSize = writeBuffer.GetSize(); + payloadSize = static_cast(writeBuffer.GetSize()); srcData = writeBuffer.GetBuffer(); } diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp index f9569b5c7e..62335a9b39 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp @@ -174,6 +174,16 @@ namespace AzNetworking return connection->Disconnect(reason, TerminationEndpoint::Local); } + void TcpNetworkInterface::SetTimeoutEnabled(bool timeoutEnabled) + { + m_timeoutEnabled = timeoutEnabled; + } + + bool TcpNetworkInterface::IsTimeoutEnabled() const + { + return m_timeoutEnabled; + } + void TcpNetworkInterface::QueueNewConnection(const PendingConnection& pendingConnection) { m_pendingConnections.PushBackItem(pendingConnection); @@ -306,7 +316,7 @@ namespace AzNetworking { tcpConnection->SendReliablePacket(CorePackets::HeartbeatPacket()); } - else if (net_TcpTimeoutConnections) + else if (net_TcpTimeoutConnections && m_networkInterface.IsTimeoutEnabled()) { tcpConnection->Disconnect(DisconnectReason::Timeout, TerminationEndpoint::Local); return TimeoutResult::Delete; diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h index 1d590da2aa..b9ea88974d 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h @@ -99,6 +99,8 @@ namespace AzNetworking bool WasPacketAcked(ConnectionId connectionId, PacketId packetId) override; bool StopListening() override; bool Disconnect(ConnectionId connectionId, DisconnectReason reason) override; + void SetTimeoutEnabled(bool timeoutEnabled) override; + bool IsTimeoutEnabled() const override; //! @} //! Queues a new incoming connection for this network interface. @@ -154,6 +156,7 @@ namespace AzNetworking AZ::Name m_name; TrustZone m_trustZone; uint16_t m_port = 0; + bool m_timeoutEnabled = true; IConnectionListener& m_connectionListener; TcpConnectionSet m_connectionSet; TcpSocketManager m_tcpSocketManager; diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpRingBuffer.inl b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpRingBuffer.inl index 322a4e6abf..9c4b2f1a17 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpRingBuffer.inl +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpRingBuffer.inl @@ -12,7 +12,7 @@ namespace AzNetworking { template inline TcpRingBuffer::TcpRingBuffer() - : m_impl(m_buffer.data(), m_buffer.size()) + : m_impl(m_buffer.data(), static_cast(m_buffer.size())) { ; } diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/DtlsEndpoint.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/DtlsEndpoint.cpp index 37c952cf30..bd5e62983f 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/DtlsEndpoint.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/DtlsEndpoint.cpp @@ -84,7 +84,7 @@ namespace AzNetworking if (dtlsData.GetSize() > 0) { const uint8_t* encryptedData = dtlsData.GetBuffer(); - const uint32_t encryptedSize = dtlsData.GetSize(); + const uint32_t encryptedSize = static_cast(dtlsData.GetSize()); BIO_write(m_readBio, encryptedData, encryptedSize); } DtlsEndpoint::HandshakeState prevState = m_state; @@ -196,7 +196,7 @@ namespace AzNetworking // Need to do this... connection negotiation may have left data in the write bio that we need to send out if (BIO_ctrl_pending(m_writeBio) > 0) { - const uint32_t maxBufferSize = outHandshakeData.GetCapacity(); + const uint32_t maxBufferSize = static_cast(outHandshakeData.GetCapacity()); outHandshakeData.Resize(maxBufferSize); const int32_t dataSize = BIO_read(m_writeBio, outHandshakeData.GetBuffer(), maxBufferSize); outHandshakeData.Resize(dataSize); diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpFragmentQueue.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpFragmentQueue.cpp index 831c35552c..66fe6f30eb 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpFragmentQueue.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpFragmentQueue.cpp @@ -108,7 +108,7 @@ namespace AzNetworking return true; } - totalPacketSize += packetFragments[index]->GetChunkBuffer().GetSize(); + totalPacketSize += static_cast(packetFragments[index]->GetChunkBuffer().GetSize()); } // We now mark this sequence as delivered, so if by some chance all the individual chunks get redelivered again we don't double deliver the reconstructed packet @@ -125,7 +125,7 @@ namespace AzNetworking uint8_t* bufferPointer = buffer.GetBuffer(); for (uint32_t index = 0; index < packetFragments.size(); ++index) { - const uint32_t chunkSize = packetFragments[index]->GetChunkBuffer().GetSize(); + const uint32_t chunkSize = static_cast(packetFragments[index]->GetChunkBuffer().GetSize()); memcpy(bufferPointer, packetFragments[index]->GetChunkBuffer().GetBuffer(), chunkSize); bufferPointer += chunkSize; } @@ -133,7 +133,7 @@ namespace AzNetworking // We can erase all the chunks now, packet is completed m_packetFragments.erase(fragmentSequence); - NetworkOutputSerializer networkSerializer(buffer.GetBuffer(), buffer.GetSize()); + NetworkOutputSerializer networkSerializer(buffer.GetBuffer(), static_cast(buffer.GetSize())); { ISerializer& networkISerializer = networkSerializer; // To get the default typeinfo parameters in ISerializer diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp index a3ddb856d2..d50b20831f 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp @@ -249,7 +249,7 @@ namespace AzNetworking continue; } decodedPacketData = m_decompressBuffer.GetBuffer(); - decodedPacketSize = m_decompressBuffer.GetSize(); + decodedPacketSize = static_cast(m_decompressBuffer.GetSize()); } GetMetrics().m_recvBytesUncompressed += decodedPacketSize; @@ -397,6 +397,16 @@ namespace AzNetworking return connection->Disconnect(reason, TerminationEndpoint::Local); } + void UdpNetworkInterface::SetTimeoutEnabled(bool timeoutEnabled) + { + m_timeoutEnabled = timeoutEnabled; + } + + bool UdpNetworkInterface::IsTimeoutEnabled() const + { + return m_timeoutEnabled; + } + bool UdpNetworkInterface::IsEncrypted() const { return m_socket->IsEncrypted(); @@ -494,7 +504,7 @@ namespace AzNetworking { buffer.Resize(buffer.GetCapacity()); - NetworkInputSerializer networkSerializer(buffer.GetBuffer(), buffer.GetCapacity()); + NetworkInputSerializer networkSerializer(buffer.GetBuffer(), static_cast(buffer.GetCapacity())); ISerializer& serializer = networkSerializer; // To get the default typeinfo parameters in ISerializer if (!header.SerializePacketFlags(serializer)) @@ -517,7 +527,7 @@ namespace AzNetworking buffer.Resize(serializer.GetSize()); } - uint32_t packetSize = buffer.GetSize(); + uint32_t packetSize = static_cast(buffer.GetSize()); uint8_t* packetData = buffer.GetBuffer(); // If the packet doesn't fit within our MTU (minus potential SSL encryption overhead), break it up @@ -549,7 +559,7 @@ namespace AzNetworking UdpPacketEncodingBuffer writeBuffer; if (m_compressor && shouldCompress) { - NetworkInputSerializer flagSerializer(writeBuffer.GetBuffer(), writeBuffer.GetCapacity()); + NetworkInputSerializer flagSerializer(writeBuffer.GetBuffer(), static_cast(writeBuffer.GetCapacity())); ISerializer& serializer = flagSerializer; // To get the default typeinfo parameters in ISerializer header.SetPacketFlag(PacketFlag::Compressed, true); @@ -562,7 +572,7 @@ namespace AzNetworking AZ_Assert(flagSize == 1, "Flag bitfield should serialize to one byte"); // Compress the packet, make sure to offset by the size of the flag which is now serialized - const uint32_t payloadSize = buffer.GetSize() - flagSize; + const uint32_t payloadSize = static_cast(buffer.GetSize() - flagSize); uint8_t* payload = buffer.GetBuffer() + flagSize; const AZStd::size_t maxSizeNeeded = m_compressor->GetMaxCompressedBufferSize(payloadSize); AZStd::size_t compressionMemBytesUsed = 0; @@ -578,7 +588,7 @@ namespace AzNetworking if (compressionMemBytesUsed < payloadSize) { writeBuffer.Resize(aznumeric_cast(flagSize + compressionMemBytesUsed)); - packetSize = writeBuffer.GetSize(); + packetSize = static_cast(writeBuffer.GetSize()); packetData = writeBuffer.GetBuffer(); // Track byte delta caused by compression GetMetrics().m_sendBytesCompressedDelta += (packetSize - compressionMemBytesUsed); @@ -729,7 +739,7 @@ namespace AzNetworking { udpConnection->SendUnreliablePacket(CorePackets::HeartbeatPacket()); } - else if (net_UdpTimeoutConnections) + else if (net_UdpTimeoutConnections && m_networkInterface.IsTimeoutEnabled()) { udpConnection->Disconnect(DisconnectReason::Timeout, TerminationEndpoint::Local); return TimeoutResult::Delete; diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h index 7a391c152e..949914da91 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h @@ -104,6 +104,8 @@ namespace AzNetworking bool WasPacketAcked(ConnectionId connectionId, PacketId packetId) override; bool StopListening() override; bool Disconnect(ConnectionId connectionId, DisconnectReason reason) override; + void SetTimeoutEnabled(bool timeoutEnabled) override; + bool IsTimeoutEnabled() const override; //! @} //! Returns true if this is an encrypted socket, false if not. @@ -179,6 +181,7 @@ namespace AzNetworking TrustZone m_trustZone; uint16_t m_port = 0; bool m_allowIncomingConnections = false; + bool m_timeoutEnabled = true; IConnectionListener& m_connectionListener; UdpConnectionSet m_connectionSet; TimeoutQueue m_connectionTimeoutQueue; diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpReaderThread.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpReaderThread.cpp index 8b535e01aa..b1474bc10f 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpReaderThread.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpReaderThread.cpp @@ -177,7 +177,7 @@ namespace AzNetworking } IpAddress address; - const uint32_t bufferHead = receiveBuffer.GetSize(); + const uint32_t bufferHead = static_cast(receiveBuffer.GetSize()); if (bufferHead + MaxUdpTransmissionUnit >= receiveBuffer.GetCapacity()) { AZLOG_INFO("Receive buffer full, leaving data on the socket. Size exceeded by %d", diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp index 29a99f96a1..997fc323a9 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp @@ -241,7 +241,7 @@ namespace AzNetworking #ifdef ENABLE_LATENCY_DEBUG int32_t UdpSocket::SendInternalDeferred(const DeferredData& data) const { - return SendInternal(data.m_address, data.m_dataBuffer.GetBuffer(), data.m_dataBuffer.GetSize(), data.m_encrypt, *data.m_dtlsEndpoint); + return SendInternal(data.m_address, data.m_dataBuffer.GetBuffer(), static_cast(data.m_dataBuffer.GetSize()), data.m_encrypt, *data.m_dtlsEndpoint); } #endif } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.h index e95b306d43..e7fa543faf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.h @@ -98,7 +98,7 @@ namespace AzToolsFramework SourceControlFileInfo GetSceneSourceControlInfo() override; bool AreAnyEntitiesSelected() override { return !m_selectedEntities.empty(); } - int GetSelectedEntitiesCount() override { return m_selectedEntities.size(); } + int GetSelectedEntitiesCount() override { return static_cast(m_selectedEntities.size()); } const EntityIdList& GetSelectedEntities() override { return m_selectedEntities; } const EntityIdList& GetHighlightedEntities() override { return m_highlightedEntities; } void SetSelectedEntities(const EntityIdList& selectedEntities) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetUtils.cpp index 69ee4e6188..92c8d37540 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Asset/AssetUtils.cpp @@ -34,8 +34,6 @@ namespace AzToolsFramework::AssetUtils::Internal return {}; } - const int pathLen = sourceFolder.length() + 1; - AZ::IO::Path sourceWildcard{ sourceFolder }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 2d97689610..b5cf5fb878 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -72,15 +72,8 @@ namespace AzToolsFramework if (m_rootInstance != nullptr) { - // Need to save off the template id to remove the template after the instance is deleted. - Prefab::TemplateId templateId = m_rootInstance->GetTemplateId(); m_rootInstance.reset(); - if (templateId != Prefab::InvalidTemplateId) - { - // Remove the template here so that if we're in a Deactivate/Activate cycle, it can recreate the template/rootInstance - // correctly - m_prefabSystemComponent->RemoveTemplate(templateId); - } + m_prefabSystemComponent->RemoveAllTemplates(); } } @@ -95,7 +88,7 @@ namespace AzToolsFramework if (templateId != Prefab::InvalidTemplateId) { m_rootInstance->SetTemplateId(Prefab::InvalidTemplateId); - m_prefabSystemComponent->RemoveTemplate(templateId); + m_prefabSystemComponent->RemoveAllTemplates(); } m_rootInstance->SetContainerEntityName("Level"); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index 8f93ebb6df..814c4e2a7f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -164,7 +164,7 @@ namespace AzToolsFramework AZStd::string path = prefix + pathIter->value.GetString(); - pathIter->value.SetString(path.c_str(), path.length(), providedPatch.GetAllocator()); + pathIter->value.SetString(path.c_str(), static_cast(path.length()), providedPatch.GetAllocator()); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp index 1c389f6b97..9ef74167a6 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceUpdateExecutor.cpp @@ -97,7 +97,7 @@ namespace AzToolsFramework m_updatingTemplateInstancesInQueue = true; const int instanceCountToUpdateInBatch = - m_instanceCountToUpdateInBatch == 0 ? m_instancesUpdateQueue.size() : m_instanceCountToUpdateInBatch; + m_instanceCountToUpdateInBatch == 0 ? static_cast(m_instancesUpdateQueue.size()) : m_instanceCountToUpdateInBatch; TemplateId currentTemplateId = InvalidTemplateId; TemplateReference currentTemplateReference = AZStd::nullopt; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index a03e48062c..69efe33d72 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -1458,7 +1458,7 @@ namespace AzToolsFramework if (&owningInstance->get() == &commonRootEntityOwningInstance) { // If it's the same instance, we can add this entity to the new instance entities. - int priorEntitiesSize = entities.size(); + size_t priorEntitiesSize = entities.size(); entities.insert(entity); @@ -1645,7 +1645,7 @@ namespace AzToolsFramework entityDomAfter.Parse(newEntityDomString.toUtf8().constData()); // Add the new Entity DOM to the Entities member of the instance - rapidjson::Value aliasName(newEntityAlias.c_str(), newEntityAlias.length(), domToAddDuplicatedEntitiesUnder.GetAllocator()); + rapidjson::Value aliasName(newEntityAlias.c_str(), static_cast(newEntityAlias.length()), domToAddDuplicatedEntitiesUnder.GetAllocator()); entitiesIter->value.AddMember(AZStd::move(aliasName), entityDomAfter, domToAddDuplicatedEntitiesUnder.GetAllocator()); } @@ -1717,7 +1717,7 @@ namespace AzToolsFramework nestedInstanceDomAfter.Parse(newInstanceDomString.toUtf8().constData()); // Add the new Instance DOM to the Instances member of the instance - rapidjson::Value aliasName(newInstanceAlias.c_str(), newInstanceAlias.length(), domToAddDuplicatedInstancesUnder.GetAllocator()); + rapidjson::Value aliasName(newInstanceAlias.c_str(), static_cast(newInstanceAlias.length()), domToAddDuplicatedInstancesUnder.GetAllocator()); instancesIter->value.AddMember(AZStd::move(aliasName), nestedInstanceDomAfter, domToAddDuplicatedInstancesUnder.GetAllocator()); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/PythonTerminal/ScriptHelpDialog.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/PythonTerminal/ScriptHelpDialog.cpp index 0a2fbb14f6..ea13d368cd 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/PythonTerminal/ScriptHelpDialog.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/PythonTerminal/ScriptHelpDialog.cpp @@ -251,7 +251,7 @@ namespace AzToolsFramework { EditorPythonConsoleInterface::GlobalFunctionCollection globalFunctionCollection; editorPythonConsoleInterface->GetGlobalFunctionList(globalFunctionCollection); - m_items.reserve(globalFunctionCollection.size()); + m_items.reserve(static_cast(globalFunctionCollection.size())); for (const EditorPythonConsoleInterface::GlobalFunction& globalFunction : globalFunctionCollection) { Item item; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp index 30b3f8915b..4115fe409e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerListModel.cpp @@ -247,7 +247,7 @@ namespace AzToolsFramework if (highlightTextIndex >= 0) { const QString BACKGROUND_COLOR{ "#707070" }; - label.insert(highlightTextIndex + m_filterString.length(), ""); + label.insert(highlightTextIndex + static_cast(m_filterString.length()), ""); label.insert(highlightTextIndex, ""); } } while(highlightTextIndex > 0); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp index 17155076ec..f166e85ff9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp @@ -2643,22 +2643,22 @@ namespace AzToolsFramework m_gui->m_statusComboBox->setItalic(false); if (allActive) { - m_gui->m_statusComboBox->setHeaderOverride(m_itemNames[StatusTypeToIndex(StatusType::StatusStartActive)]); - m_gui->m_statusComboBox->setCurrentIndex(StatusTypeToIndex(StatusType::StatusStartActive)); + m_gui->m_statusComboBox->setHeaderOverride(m_itemNames[static_cast(StatusTypeToIndex(StatusType::StatusStartActive))]); + m_gui->m_statusComboBox->setCurrentIndex(static_cast(StatusTypeToIndex(StatusType::StatusStartActive))); m_comboItems[StatusTypeToIndex(StatusType::StatusStartActive)]->setCheckState(Qt::Checked); } else if (allInactive) { - m_gui->m_statusComboBox->setHeaderOverride(m_itemNames[StatusTypeToIndex(StatusType::StatusStartInactive)]); - m_gui->m_statusComboBox->setCurrentIndex(StatusTypeToIndex(StatusType::StatusStartInactive)); + m_gui->m_statusComboBox->setHeaderOverride(m_itemNames[static_cast(StatusTypeToIndex(StatusType::StatusStartInactive))]); + m_gui->m_statusComboBox->setCurrentIndex(static_cast(StatusTypeToIndex(StatusType::StatusStartInactive))); m_comboItems[StatusTypeToIndex(StatusType::StatusStartInactive)]->setCheckState(Qt::Checked); } else if (allEditorOnly) { - m_gui->m_statusComboBox->setHeaderOverride(m_itemNames[StatusTypeToIndex(StatusType::StatusEditorOnly)]); - m_gui->m_statusComboBox->setCurrentIndex(StatusTypeToIndex(StatusType::StatusEditorOnly)); + m_gui->m_statusComboBox->setHeaderOverride(m_itemNames[static_cast(StatusTypeToIndex(StatusType::StatusEditorOnly))]); + m_gui->m_statusComboBox->setCurrentIndex(static_cast(StatusTypeToIndex(StatusType::StatusEditorOnly))); m_comboItems[StatusTypeToIndex(StatusType::StatusEditorOnly)]->setCheckState(Qt::Checked); } else // Some marked active, some not diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp index 51a044e9c1..7e47fa9569 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/Benchmark/PrefabBenchmarkFixture.cpp @@ -110,8 +110,8 @@ namespace Benchmark void BM_Prefab::SetUpMockValidatorForReadPrefab() { - int pathCount = m_paths.size(); - for (int number = 0; number < pathCount; ++number) + const size_t pathCount = m_paths.size(); + for (size_t number = 0; number < pathCount; ++number) { m_mockIOActionValidator->ReadPrefabDom( m_paths[number], UnitTest::PrefabTestDomUtils::CreatePrefabDom()); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp index e3b65db97e..8379992553 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstanceToTemplatePropagatorTests.cpp @@ -245,7 +245,9 @@ namespace UnitTest m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomBeforeUpdate, *firstInstance); //remove instance from instance - firstInstance->DetachNestedInstance(addedAlias); + AZStd::unique_ptr detachedInstance = firstInstance->DetachNestedInstance(addedAlias); + ASSERT_TRUE(detachedInstance != nullptr); + m_prefabSystemComponent->RemoveLink(detachedInstance->GetLinkId()); //create document with after change snapshot PrefabDom instanceDomAfterUpdate; diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.h b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.h index 66ad2fbe44..f90a91ea3c 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.h +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.h @@ -38,7 +38,7 @@ namespace UnitTest const EntityAlias& entityAlias) { return GetPrefabDomEntitiesPath() - .Append(entityAlias.c_str(), entityAlias.length()); + .Append(entityAlias.c_str(), static_cast(entityAlias.length())); }; inline PrefabDomPath GetPrefabDomEntityNamePath( @@ -62,7 +62,7 @@ namespace UnitTest inline PrefabDomPath GetPrefabDomInstancePath( const InstanceAlias& instanceAlias) { - return GetPrefabDomInstancesPath().Append(instanceAlias.c_str(), instanceAlias.length()); + return GetPrefabDomInstancesPath().Append(instanceAlias.c_str(), static_cast(instanceAlias.length())); }; inline PrefabDomPath GetPrefabDomInstancePath( diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateInstancesTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateInstancesTests.cpp index 0d955789ac..baded6d43e 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateInstancesTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateInstancesTests.cpp @@ -309,6 +309,7 @@ namespace UnitTest // and use the updated enclosing Instance to update the PrefabDom of Template. AZStd::unique_ptr detachedInstance = newEnclosingInstance->DetachNestedInstance(nestedInstanceAliases.front()); ASSERT_TRUE(detachedInstance); + m_prefabSystemComponent->RemoveLink(detachedInstance->GetLinkId()); PrefabDom updatedTemplateDom; ASSERT_TRUE(PrefabDomUtils::StoreInstanceInPrefabDom(*newEnclosingInstance, updatedTemplateDom)); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateTemplateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateTemplateTests.cpp index 4e7d9d95d1..6f90e245f7 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateTemplateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUpdateTemplateTests.cpp @@ -274,6 +274,7 @@ namespace UnitTest InstanceAlias aliasOfWheelInstanceToRetain = wheelInstanceAliasesUnderAxle.front(); AZStd::unique_ptr detachedInstance = axleInstance->DetachNestedInstance(wheelInstanceAliasesUnderAxle.back()); ASSERT_TRUE(detachedInstance); + m_prefabSystemComponent->RemoveLink(detachedInstance->GetLinkId()); PrefabDom updatedAxleInstanceDom; ASSERT_TRUE(PrefabDomUtils::StoreInstanceInPrefabDom(*axleInstance, updatedAxleInstanceDom)); m_prefabSystemComponent->UpdatePrefabTemplate(axleTemplateId, updatedAxleInstanceDom); diff --git a/Code/Legacy/CryCommon/CryArray.h b/Code/Legacy/CryCommon/CryArray.h index 8b0cea3de6..61224784a2 100644 --- a/Code/Legacy/CryCommon/CryArray.h +++ b/Code/Legacy/CryCommon/CryArray.h @@ -11,7 +11,7 @@ #define CRYINCLUDE_CRYCOMMON_CRYARRAY_H #pragma once -#include "CryLegacyAllocator.h" +#include #include //--------------------------------------------------------------------------- @@ -664,7 +664,7 @@ namespace NArray I capacity() const { - I aligned_bytes = Align(size() * sizeof(T), sizeof(I)); + I aligned_bytes = static_cast(Align(size() * sizeof(T), sizeof(I))); if (m_nSizeCap & nCAP_BIT) { // Capacity stored in word following data @@ -682,7 +682,7 @@ namespace NArray // Store size, and assert against overflow. assert(s <= c); m_nSizeCap = s; - I aligned_bytes = Align(s * sizeof(T), sizeof(I)); + I aligned_bytes = static_cast(Align(s * sizeof(T), sizeof(I))); if (c * sizeof(T) >= aligned_bytes + sizeof(I)) { // Has extra capacity, more than word-alignment diff --git a/Code/Legacy/CryCommon/CryLegacyAllocator.h b/Code/Legacy/CryCommon/CryLegacyAllocator.h index 81e3f90026..b0e1e29657 100644 --- a/Code/Legacy/CryCommon/CryLegacyAllocator.h +++ b/Code/Legacy/CryCommon/CryLegacyAllocator.h @@ -10,8 +10,6 @@ #include "LegacyAllocator.h" -#include - //----------------------------------------------------------------------------- // CryModule allocation API //----------------------------------------------------------------------------- @@ -95,128 +93,3 @@ inline void* CryModuleReallocAlignImpl(void* prev, size_t size, size_t alignment return ptr; } - -//----------------------------------------------------------------------------- -// CryCrt alloc API -//----------------------------------------------------------------------------- -inline size_t CryCrtSize(void* p) -{ - return AZ::AllocatorInstance::Get().AllocationSize(p); -} - -inline void* CryCrtMalloc(size_t size) -{ - return CryModuleMalloc(size); -} - -inline size_t CryCrtFree(void* p) -{ - size_t size = CryCrtSize(p); - CryModuleFree(p); - return size; -}; - -//----------------------------------------------------------------------------- -// CrySystemCrt alloc API -//----------------------------------------------------------------------------- -inline size_t CrySystemCrtSize(void* p) -{ - return AZ::AllocatorInstance::Get().AllocationSize(p); -} - -inline void* CrySystemCrtMalloc(size_t size) -{ - return AZ::AllocatorInstance::Get().Allocate(size, 0, 0, "AZ::LegacyAllocator"); -} - -inline void* CrySystemCrtRealloc(void* p, size_t size) -{ - // Use LegacyAllocator's special ReAllocate - return AZ::AllocatorInstance::Get().ReAllocate(p, size, 0); -} - -inline size_t CrySystemCrtFree(void* p) -{ - size_t size = CrySystemCrtSize(p); - CryModuleFree(p); - return size; -} - -inline size_t CrySystemCrtGetUsedSpace() -{ - return AZ::AllocatorInstance::Get().NumAllocatedBytes(); -} - -//----------------------------------------------------------------------------- -// CryMalloc API -//----------------------------------------------------------------------------- -inline void* CryMalloc(size_t size, size_t& allocated, size_t alignment) -{ - if (!size) - { - allocated = 0; - return nullptr; - } - - // The original implementation guaranteed 16 byte min alignment - alignment = AZStd::GetMax(alignment, 16); - void* ptr = AZ::AllocatorInstance::Get().Allocate(size, alignment, 0, "CryMalloc", __FILE__, __LINE__); - allocated = AZ::AllocatorInstance::Get().AllocationSize(ptr); - return ptr; -} - -inline void* CryRealloc(void* memblock, size_t size, size_t& allocated, size_t& oldsize, size_t alignment) -{ - oldsize = AZ::AllocatorInstance::Get().AllocationSize(memblock); - void* ptr = AZ::AllocatorInstance::Get().ReAllocate(memblock, size, alignment); - allocated = AZ::AllocatorInstance::Get().AllocationSize(ptr); - return ptr; -} - -inline size_t CryFree(void* p, size_t /*alignment*/) -{ - size_t size = AZ::AllocatorInstance::Get().AllocationSize(p); - AZ::AllocatorInstance::Get().DeAllocate(p, size); - return size; -} - -inline size_t CryGetMemSize(void* memblock, size_t /*sourceSize*/) -{ - return AZ::AllocatorInstance::Get().AllocationSize(memblock); -} - -inline int CryMemoryGetAllocatedSize() -{ - return AZ::AllocatorInstance::Get().NumAllocatedBytes(); -} - -////////////////////////////////////////////////////////////////////////// -inline int CryMemoryGetPoolSize() -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////// -inline int CryStats([[maybe_unused]] char* buf) -{ - return 0; -} - -inline int CryGetUsedHeapSize() -{ - return AZ::AllocatorInstance::Get().NumAllocatedBytes(); -} - -inline int CryGetWastedHeapSize() -{ - return 0; -} - -inline void CryCleanup() -{ - AZ::AllocatorInstance::Get().GarbageCollect(); -} - -inline void CryResetStats(void) -{ -} diff --git a/Code/Legacy/CryCommon/CryName.h b/Code/Legacy/CryCommon/CryName.h index 552391419a..b9b3799dd7 100644 --- a/Code/Legacy/CryCommon/CryName.h +++ b/Code/Legacy/CryCommon/CryName.h @@ -45,7 +45,7 @@ struct INameTable const char* GetStr() { return (char*)(this + 1); } void AddRef() { nRefCount++; /*InterlockedIncrement(&_header()->nRefCount);*/}; int Release() { return --nRefCount; }; - int GetMemoryUsage() { return sizeof(SNameEntry) + strlen(GetStr()); } + int GetMemoryUsage() { return static_cast(sizeof(SNameEntry) + strlen(GetStr())); } int GetLength(){return nLength; } }; @@ -102,14 +102,14 @@ public: if (!pEntry) { // Create a new entry. - unsigned int nLen = strlen(str); - unsigned int allocLen = sizeof(SNameEntry) + (nLen + 1) * sizeof(char); + size_t nLen = strlen(str); + size_t allocLen = sizeof(SNameEntry) + (nLen + 1) * sizeof(char); pEntry = (SNameEntry*)CryModuleMalloc(allocLen); assert(pEntry != NULL); pEntry->nTag = SNameEntry::TAG; pEntry->nRefCount = 0; - pEntry->nLength = nLen; - pEntry->nAllocSize = allocLen; + pEntry->nLength = static_cast(nLen); + pEntry->nAllocSize = static_cast(allocLen); // Copy string to the end of name entry. char* pEntryStr = const_cast(pEntry->GetStr()); memcpy(pEntryStr, str, nLen + 1); @@ -134,7 +134,7 @@ public: int n = 0; for (it = m_nameMap.begin(); it != m_nameMap.end(); it++) { - nSize += strlen(it->first); + nSize += static_cast(strlen(it->first)); nSize += it->second->GetMemoryUsage(); n++; } @@ -149,7 +149,7 @@ public: } virtual int GetNumberOfEntries() { - return m_nameMap.size(); + return static_cast(m_nameMap.size()); } // Log all names inside CryName table. diff --git a/Code/Legacy/CryCommon/CryPodArray.h b/Code/Legacy/CryCommon/CryPodArray.h index ee36750f7f..20693b29ac 100644 --- a/Code/Legacy/CryCommon/CryPodArray.h +++ b/Code/Legacy/CryCommon/CryPodArray.h @@ -159,8 +159,8 @@ public: return numElements != m_elements.size(); } - ILINE int Count() const { return m_elements.size(); } - ILINE unsigned int Size() const { return m_elements.size(); } + ILINE size_t Count() const { return m_elements.size(); } + ILINE size_t Size() const { return m_elements.size(); } ILINE int IsEmpty() const { return m_elements.empty(); } diff --git a/Code/Legacy/CryCommon/IIndexedMesh.h b/Code/Legacy/CryCommon/IIndexedMesh.h index cb19656e35..87c3df98bd 100644 --- a/Code/Legacy/CryCommon/IIndexedMesh.h +++ b/Code/Legacy/CryCommon/IIndexedMesh.h @@ -2094,7 +2094,7 @@ public: { if (activeStreams & (1U << i)) { - nMeshSize += ((i == VSF_GENERAL) ? sizeof(SVF_P3S_C4B_T2S) : cSizeStream[i]) * GetVertexCount(); + nMeshSize += static_cast(((i == VSF_GENERAL) ? sizeof(SVF_P3S_C4B_T2S) : cSizeStream[i]) * GetVertexCount()); nMeshSize += TARGET_DEFAULT_ALIGN - (nMeshSize & (TARGET_DEFAULT_ALIGN - 1)); } } diff --git a/Code/Legacy/CryCommon/IShader.h b/Code/Legacy/CryCommon/IShader.h index 978da1a77f..6ae3bd73df 100644 --- a/Code/Legacy/CryCommon/IShader.h +++ b/Code/Legacy/CryCommon/IShader.h @@ -1425,9 +1425,9 @@ struct STexSamplerFX SAFE_RELEASE(m_pITarget); } - int Size() + size_t Size() { - int nSize = sizeof(*this); + size_t nSize = sizeof(*this); nSize += m_szName.capacity(); nSize += m_szTexture.capacity(); #if SHADER_REFLECT_TEXTURE_SLOTS @@ -1804,9 +1804,9 @@ struct SEfResTexture return m_Ext.m_pTexModifier; } - int Size() const + size_t Size() const { - int nSize = sizeof(SEfResTexture) - sizeof(STexSamplerRT) - sizeof(SEfResTextureExt); + size_t nSize = sizeof(SEfResTexture) - sizeof(STexSamplerRT) - sizeof(SEfResTextureExt); nSize += m_Name.size(); nSize += m_Sampler.Size(); nSize += m_Ext.Size(); @@ -1899,9 +1899,9 @@ struct SBaseShaderResources uint8 m_VoxelCoverage; - int Size() const + size_t Size() const { - int nSize = sizeof(SBaseShaderResources) + m_ShaderParams.size() * sizeof(SShaderParam); + size_t nSize = sizeof(SBaseShaderResources) + m_ShaderParams.size() * sizeof(SShaderParam); return nSize; } @@ -2031,9 +2031,9 @@ struct SInputShaderResources TexturesResourcesMap m_TexturesResourcesMap; // a map of all textures resources used by the shader by name SDeformInfo m_DeformInfo; - int Size() const + size_t Size() const { - int nSize = SBaseShaderResources::Size();// -sizeof(SEfResTexture) * m_TexturesResourcesMap.size(); + size_t nSize = SBaseShaderResources::Size();// -sizeof(SEfResTexture) * m_TexturesResourcesMap.size(); nSize += m_TexturePath.size(); nSize += sizeof(SDeformInfo); diff --git a/Code/Legacy/CryCommon/VectorMap.h b/Code/Legacy/CryCommon/VectorMap.h index 0f2b7e57e4..1a42f0e48f 100644 --- a/Code/Legacy/CryCommon/VectorMap.h +++ b/Code/Legacy/CryCommon/VectorMap.h @@ -408,8 +408,7 @@ typename VectorMap::key_compare VectorMap::key_comp() co template typename VectorMap::iterator VectorMap::lower_bound(const key_type& key) { - int count = 0; - count = m_entries.size(); + int count = static_cast(m_entries.size()); iterator first = m_entries.begin(); iterator last = m_entries.end(); for (; 0 < count; ) @@ -432,8 +431,7 @@ typename VectorMap::iterator VectorMap::lower_bound(cons template typename VectorMap::const_iterator VectorMap::lower_bound(const key_type& key) const { - int count = 0; - count = m_entries.size(); + int count = static_cast(m_entries.size()); const_iterator first = m_entries.begin(); const_iterator last = m_entries.end(); for (; 0 < count; ) diff --git a/Code/Legacy/CryCommon/platform.h b/Code/Legacy/CryCommon/platform.h index c040139b5a..12f732a729 100644 --- a/Code/Legacy/CryCommon/platform.h +++ b/Code/Legacy/CryCommon/platform.h @@ -475,8 +475,6 @@ ILINE DestinationType alias_cast(SourceType pPtr) return conv_union.pDst; } -#include "CryLegacyAllocator.h" - ////////////////////////////////////////////////////////////////////////// #ifndef DEPRECATED #define DEPRECATED diff --git a/Code/Legacy/CrySystem/ConsoleBatchFile.cpp b/Code/Legacy/CrySystem/ConsoleBatchFile.cpp index 8b25773c45..3d46716873 100644 --- a/Code/Legacy/CrySystem/ConsoleBatchFile.cpp +++ b/Code/Legacy/CrySystem/ConsoleBatchFile.cpp @@ -112,7 +112,7 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) CryLog("%s \"%s\" found in %s ...", szLog, PathUtil::GetFile(filenameLog.c_str()), PathUtil::GetPath(filenameLog).c_str()); } - int nLen = file.GetLength(); + size_t nLen = file.GetLength(); char* sAllText = new char [nLen + 16]; file.ReadRaw(sAllText, nLen); sAllText[nLen] = '\0'; diff --git a/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp b/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp index d21fff3dd3..d8ba36da3d 100644 --- a/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp +++ b/Code/Legacy/CrySystem/LevelSystem/LevelSystem.cpp @@ -161,7 +161,7 @@ struct SLevelNameAutoComplete : public IConsoleArgumentAutoComplete { AZStd::vector levels; - virtual int GetCount() const { return levels.size(); }; + virtual int GetCount() const { return static_cast(levels.size()); }; virtual const char* GetValue(int nIndex) const { return levels[nIndex].c_str(); }; }; // definition and declaration must be separated for devirtualization diff --git a/Code/Legacy/CrySystem/LocalizedStringManager.cpp b/Code/Legacy/CrySystem/LocalizedStringManager.cpp index cffe1c38c6..6013b44f92 100644 --- a/Code/Legacy/CrySystem/LocalizedStringManager.cpp +++ b/Code/Legacy/CrySystem/LocalizedStringManager.cpp @@ -479,7 +479,7 @@ void CLocalizedStringsManager::ParseFirstLine(IXmlTableReader* pXmlTableReader, if (i == ELOCALIZED_COLUMN_SOUNDMOOD) { const char* pSoundMoodName = pFind + strlen(sLocalizedColumnNames[i]) + 1; - int nSoundMoodNameLength = sCellContent.length() - strlen(sLocalizedColumnNames[i]) - 1; + int nSoundMoodNameLength = static_cast(sCellContent.length() - strlen(sLocalizedColumnNames[i]) - 1); if (nSoundMoodNameLength > 0) { SoundMoodIndex[nCellIndex] = pSoundMoodName; @@ -490,7 +490,7 @@ void CLocalizedStringsManager::ParseFirstLine(IXmlTableReader* pXmlTableReader, if (i == ELOCALIZED_COLUMN_EVENTPARAMETER) { const char* pParameterName = pFind + strlen(sLocalizedColumnNames[i]) + 1; - int nParameterNameLength = sCellContent.length() - strlen(sLocalizedColumnNames[i]) - 1; + int nParameterNameLength = static_cast(sCellContent.length() - strlen(sLocalizedColumnNames[i]) - 1); if (nParameterNameLength > 0) { EventParameterIndex[nCellIndex] = pParameterName; @@ -622,7 +622,7 @@ bool CLocalizedStringsManager::InitLocalizationData( CRY_ASSERT(m_tagFileNames.size() < 255); - uint8 curNumTags = m_tagFileNames.size(); + uint8 curNumTags = static_cast(m_tagFileNames.size()); m_tagFileNames[sType].filenames = vEntries; m_tagFileNames[sType].id = curNumTags + 1; @@ -757,7 +757,7 @@ bool CLocalizedStringsManager::ReleaseLocalizationDataByTag( bool bVecEntryErased = false; //Then remove the entries in the storage vector - const uint32 numEntries = m_pLanguage->m_vLocalizedStrings.size(); + const int32 numEntries = static_cast(m_pLanguage->m_vLocalizedStrings.size()); for (int32 i = numEntries - 1; i >= 0; i--) { SLocalizedStringEntry* entry = m_pLanguage->m_vLocalizedStrings[i]; @@ -1436,7 +1436,7 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName, // SoundMood Entries { - pEntry->SoundMoods.resize(SoundMoodValues.size()); + pEntry->SoundMoods.resize(static_cast(SoundMoodValues.size())); if (SoundMoodValues.size() > 0) { std::map::const_iterator itEnd = SoundMoodValues.end(); @@ -1452,7 +1452,7 @@ bool CLocalizedStringsManager::DoLoadExcelXmlSpreadsheet(const char* sFileName, // EventParameter Entries { - pEntry->EventParameters.resize(EventParameterValues.size()); + pEntry->EventParameters.resize(static_cast(EventParameterValues.size())); if (EventParameterValues.size() > 0) { std::map::const_iterator itEnd = EventParameterValues.end(); @@ -2226,7 +2226,7 @@ int CLocalizedStringsManager::GetLocalizedStringCount() { return 0; } - return m_pLanguage->m_vLocalizedStrings.size(); + return static_cast(m_pLanguage->m_vLocalizedStrings.size()); } ////////////////////////////////////////////////////////////////////////// @@ -2339,7 +2339,7 @@ void InternalFormatStringMessage(AZStd::string& outString, const AZStd::string& int maxArgUsed = 0; int lastPos = 0; int curPos = 0; - const int sourceLen = sString.length(); + const int sourceLen = static_cast(sString.length()); while (true) { auto foundPos = sString.find(token, curPos); diff --git a/Code/Legacy/CrySystem/Log.cpp b/Code/Legacy/CrySystem/Log.cpp index 0385ff8eb3..90c15588c3 100644 --- a/Code/Legacy/CrySystem/Log.cpp +++ b/Code/Legacy/CrySystem/Log.cpp @@ -483,7 +483,7 @@ void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFo break; } - int bufferlen = sizeof(szBuffer) - prefixSize; + int bufferlen = static_cast(sizeof(szBuffer) - prefixSize); if (bufferlen > 0) { #if defined(AZ_RESTRICTED_PLATFORM) diff --git a/Code/Legacy/CrySystem/SimpleStringPool.h b/Code/Legacy/CrySystem/SimpleStringPool.h index ddeca0f44c..d1a618425c 100644 --- a/Code/Legacy/CrySystem/SimpleStringPool.h +++ b/Code/Legacy/CrySystem/SimpleStringPool.h @@ -216,8 +216,8 @@ public: CryFatalError("Can't replace strings in an xml node that reuses strings"); } - int nStrLen1 = strlen(str1); - int nStrLen2 = strlen(str2); + int nStrLen1 = static_cast(strlen(str1)); + int nStrLen2 = static_cast(strlen(str2)); // undo ptr1 add. if (m_ptr != m_start) diff --git a/Code/Legacy/CrySystem/SystemCFG.cpp b/Code/Legacy/CrySystem/SystemCFG.cpp index 4d193c72a5..57de0be909 100644 --- a/Code/Legacy/CrySystem/SystemCFG.cpp +++ b/Code/Legacy/CrySystem/SystemCFG.cpp @@ -287,7 +287,7 @@ public: pos = 1; for (;; ) { - pos = szValue.find_first_of("\\", pos); + pos = static_cast(szValue.find_first_of("\\", pos)); if (pos == AZStd::string::npos) { @@ -302,7 +302,7 @@ public: pos = 1; for (;; ) { - pos = szValue.find_first_of("\"", pos); + pos = static_cast(szValue.find_first_of("\"", pos)); if (pos == AZStd::string::npos) { @@ -416,7 +416,7 @@ bool CSystemConfiguration::ParseSystemConfig() INDENT_LOG_DURING_SCOPE(); - int nLen = file.GetLength(); + int nLen = static_cast(file.GetLength()); if (nLen == 0) { CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Couldn't get length for Config file %s", filename.c_str()); diff --git a/Code/Legacy/CrySystem/ViewSystem/View.cpp b/Code/Legacy/CrySystem/ViewSystem/View.cpp index ef9f2591c4..e6e9f7a984 100644 --- a/Code/Legacy/CrySystem/ViewSystem/View.cpp +++ b/Code/Legacy/CrySystem/ViewSystem/View.cpp @@ -173,7 +173,7 @@ void CView::SetViewShakeEx(const SShakeParams& params) return; } - int shakes(m_shakes.size()); + int shakes = static_cast(m_shakes.size()); SShake* pSetShake(NULL); for (int i = 0; i < shakes; ++i) @@ -250,7 +250,7 @@ void CView::ProcessShaking(float frameTime) m_viewParams.shakingRatio = 0; m_viewParams.groundOnly = false; - int shakes(m_shakes.size()); + int shakes = static_cast(m_shakes.size()); for (int i = 0; i < shakes; ++i) { ProcessShake(&m_shakes[i], frameTime); @@ -556,7 +556,7 @@ void CView::ProcessShakeNormal_DoShaking(SShake* pShake, float frameTime) //------------------------------------------------------------------------ void CView::StopShake(int shakeID) { - uint32 num = m_shakes.size(); + uint32 num = static_cast(m_shakes.size()); for (uint32 i = 0; i < num; ++i) { if (m_shakes[i].ID == shakeID && m_shakes[i].updating) diff --git a/Code/Legacy/CrySystem/XConsole.cpp b/Code/Legacy/CrySystem/XConsole.cpp index 0f98dd12d6..8e598c481d 100644 --- a/Code/Legacy/CrySystem/XConsole.cpp +++ b/Code/Legacy/CrySystem/XConsole.cpp @@ -1283,7 +1283,7 @@ bool CXConsole::ProcessInput(const AzFramework::InputChannel& inputChannel) { if (isCtrlModifierActive) { - m_nScrollLine = m_dqConsoleBuffer.size() - 1; + m_nScrollLine = static_cast(m_dqConsoleBuffer.size() - 1); } else { @@ -1396,7 +1396,7 @@ bool CXConsole::GetLineNo(const int indwLineNo, char* outszBuffer, const int ind ////////////////////////////////////////////////////////////////////////// int CXConsole::GetLineCount() const { - return m_dqConsoleBuffer.size(); + return static_cast(m_dqConsoleBuffer.size()); } ////////////////////////////////////////////////////////////////////////// @@ -2614,7 +2614,7 @@ void CXConsole::RemoveOutputPrintSink(IOutputPrintSink* inpSink) { assert(inpSink); - int nCount = m_OutputSinks.size(); + int nCount = static_cast(m_OutputSinks.size()); for (int i = 0; i < nCount; i++) { @@ -2900,7 +2900,7 @@ bool CXConsole::IsHashCalculated() ////////////////////////////////////////////////////////////////////////// int CXConsole::GetNumCheatVars() { - return m_randomCheckedVariables.size(); + return static_cast(m_randomCheckedVariables.size()); } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Legacy/CrySystem/XConsole.h b/Code/Legacy/CrySystem/XConsole.h index 16d1870be6..67d9371e8d 100644 --- a/Code/Legacy/CrySystem/XConsole.h +++ b/Code/Legacy/CrySystem/XConsole.h @@ -70,7 +70,7 @@ struct CConsoleCommandArgs CConsoleCommandArgs(AZStd::string& line, std::vector& args) : m_line(line) , m_args(args) {}; - virtual int GetArgCount() const { return m_args.size(); }; + virtual int GetArgCount() const { return static_cast(m_args.size()); }; // Get argument by index, nIndex must be in 0 <= nIndex < GetArgCount() virtual const char* GetArg(int nIndex) const { diff --git a/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp b/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp index b0d7a6f1af..c5fa3839e0 100644 --- a/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp +++ b/Code/Legacy/CrySystem/XML/WriteXMLSource.cpp @@ -190,8 +190,9 @@ bool SaveArray(const IdTable& idTable, XmlNodeRef& definition, XmlNodeRef& data, } bool needIndex = false; - for (size_t i = 1; i <= numElems; i++) + for (size_t sizei = 1; sizei <= numElems; sizei++) { + const int i = static_cast(sizei); if (!childSource->HaveElemAt(i)) { needIndex = true; diff --git a/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp b/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp index 7fd9df30c9..f55f792516 100644 --- a/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp +++ b/Code/Legacy/CrySystem/XML/XMLBinaryWriter.cpp @@ -114,26 +114,26 @@ bool XMLBinary::CXMLBinaryWriter::WriteNode(IDataWriter* pFile, XmlNodeRef node, nTheoreticalPosition += sizeof(header); align(nTheoreticalPosition, nAlignment); - header.nNodeTablePosition = nTheoreticalPosition; + header.nNodeTablePosition = static_cast(nTheoreticalPosition); header.nNodeCount = int(m_nodes.size()); nTheoreticalPosition += header.nNodeCount * sizeof(Node); align(nTheoreticalPosition, nAlignment); - header.nChildTablePosition = nTheoreticalPosition; + header.nChildTablePosition = static_cast(nTheoreticalPosition); header.nChildCount = int(m_childs.size()); nTheoreticalPosition += header.nChildCount * sizeof(NodeIndex); align(nTheoreticalPosition, nAlignment); - header.nAttributeTablePosition = nTheoreticalPosition; + header.nAttributeTablePosition = static_cast(nTheoreticalPosition); header.nAttributeCount = int(m_attributes.size()); nTheoreticalPosition += header.nAttributeCount * sizeof(Attribute); align(nTheoreticalPosition, nAlignment); - header.nStringDataPosition = nTheoreticalPosition; + header.nStringDataPosition = static_cast(nTheoreticalPosition); header.nStringDataSize = m_nStringDataSize; nTheoreticalPosition += header.nStringDataSize; - header.nXMLSize = nTheoreticalPosition; + header.nXMLSize = static_cast(nTheoreticalPosition); // Swap endianness of the data structures if (bNeedSwapEndian) @@ -328,7 +328,7 @@ int XMLBinary::CXMLBinaryWriter::AddString(const XmlString& sString) // We don't have such string yet, so we should add it to the tables. m_strings.push_back(sString); itStringEntry = m_stringMap.insert(StringMap::value_type(sString, m_nStringDataSize)).first; - m_nStringDataSize += sString.length() + 1; + m_nStringDataSize += static_cast(sString.length() + 1); } // Return offset of the string in the string data buffer. diff --git a/Code/Legacy/CrySystem/XML/XmlUtils.cpp b/Code/Legacy/CrySystem/XML/XmlUtils.cpp index 5e31fff8d7..ecc10508f1 100644 --- a/Code/Legacy/CrySystem/XML/XmlUtils.cpp +++ b/Code/Legacy/CrySystem/XML/XmlUtils.cpp @@ -91,7 +91,7 @@ XmlNodeRef CXmlUtils::LoadXmlFromFile(const char* sFilename, bool bReuseStrings, XmlNodeRef CXmlUtils::LoadXmlFromBuffer(const char* buffer, size_t size, bool bReuseStrings, bool bSuppressWarnings) { XmlParser parser(bReuseStrings); - XmlNodeRef node = parser.ParseBuffer(buffer, size, true, bSuppressWarnings); + XmlNodeRef node = parser.ParseBuffer(buffer, static_cast(size), true, bSuppressWarnings); return node; } @@ -111,7 +111,7 @@ const char* CXmlUtils::HashXml(XmlNodeRef node) static char temp[16]; static const char* hex = "0123456789abcdef"; XmlString str = node->getXML(); - GetMD5(str.data(), str.length(), temp); + GetMD5(str.data(), static_cast(str.length()), temp); for (int i = 0; i < 16; i++) { signature[2 * i + 0] = hex[((uint8)temp[i]) >> 4]; diff --git a/Code/Legacy/CrySystem/XML/xml.cpp b/Code/Legacy/CrySystem/XML/xml.cpp index 728d9441f2..8eb13c5247 100644 --- a/Code/Legacy/CrySystem/XML/xml.cpp +++ b/Code/Legacy/CrySystem/XML/xml.cpp @@ -655,7 +655,7 @@ XmlNodeRef CXmlNode::findChild(const char* tag) const if (m_pChilds) { XmlNodes& childs = *m_pChilds; - for (int i = 0, num = childs.size(); i < num; ++i) + for (int i = 0, num = static_cast(childs.size()); i < num; ++i) { if (childs[i]->isTag(tag)) { @@ -690,7 +690,7 @@ void CXmlNode::deleteChild(const char* tag) if (m_pChilds) { XmlNodes& childs = *m_pChilds; - for (int i = 0, num = childs.size(); i < num; ++i) + for (int i = 0, num = static_cast(childs.size()); i < num; ++i) { if (childs[i]->isTag(tag)) { @@ -913,7 +913,7 @@ XmlNodeRef CXmlNode::clone() node->m_pChilds = new XmlNodes; node->m_pChilds->reserve(childs.size()); - for (int i = 0, num = childs.size(); i < num; ++i) + for (int i = 0, num = static_cast(childs.size()); i < num; ++i) { node->addChild(childs[i]->clone()); } @@ -956,7 +956,7 @@ static void AddTabsToString(XmlString& xml, int level) ////////////////////////////////////////////////////////////////////////// bool CXmlNode::IsValidXmlString(const char* str) const { - int len = strlen(str); + int len = static_cast(strlen(str)); { // Prevents invalid characters not from standard ASCII set to propagate to xml. @@ -1432,7 +1432,7 @@ protected: void XmlParserImp::CleanStack() { m_nNodeStackTop = 0; - for (int i = 0, num = m_nodeStack.size(); i < num; i++) + for (int i = 0, num = static_cast(m_nodeStack.size()); i < num; i++) { m_nodeStack[i].node = 0; m_nodeStack[i].childs.resize(0); diff --git a/Code/Tools/AssetBundler/source/ui/PlatformSelectionWidget.cpp b/Code/Tools/AssetBundler/source/ui/PlatformSelectionWidget.cpp index 4f1e7a6337..e59bdfa8ac 100644 --- a/Code/Tools/AssetBundler/source/ui/PlatformSelectionWidget.cpp +++ b/Code/Tools/AssetBundler/source/ui/PlatformSelectionWidget.cpp @@ -34,7 +34,7 @@ namespace AssetBundler for (const AZStd::string_view& platformString : m_platformHelper->GetPlatforms(PlatformFlags::AllNamedPlatforms)) { // Create the CheckBox and store what platform it maps to - QSharedPointer platformCheckBox(new QCheckBox(QString::fromUtf8(platformString.data(), platformString.size()))); + QSharedPointer platformCheckBox(new QCheckBox(QString::fromUtf8(platformString.data(), static_cast(platformString.size())))); m_platformCheckBoxes.push_back(platformCheckBox); PlatformFlags currentPlatformFlag = m_platformHelper->GetPlatformFlag(platformString); m_platformList.push_back(currentPlatformFlag); diff --git a/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp b/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp index eb0416f125..64e176ffe4 100644 --- a/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp +++ b/Code/Tools/AssetProcessor/native/AssetManager/SourceFileRelocator.cpp @@ -88,7 +88,7 @@ Please note that only those seed files will get updated that are active for your { scanFolderInfo = nullptr; bool isRelative = AzFramework::StringFunc::Path::IsRelative(normalizedSource.c_str()); - + if (isRelative) { // Relative paths can match multiple files/folders, search each scan folder for a valid match @@ -264,7 +264,7 @@ Please note that only those seed files will get updated that are active for your metaDataFile.m_sourceFileIndex = sourceFileIndex.value(); metadataFiles.emplace_back(metaDataFile); metaDataFileEntries.insert(metadaFileCorrectCase); - } + } } } } @@ -601,7 +601,7 @@ Please note that only those seed files will get updated that are active for your AZ::StringFunc::Path::ReplaceFullName(newDestinationPath, fullFileName.c_str()); } - + if (!AzFramework::StringFunc::Path::IsRelative(newDestinationPath.c_str())) { @@ -1025,14 +1025,14 @@ Please note that only those seed files will get updated that are active for your AZStd::binary_semaphore waitSignal; int errorCount = 0; - AzToolsFramework::SourceControlResponseCallbackBulk callback = AZStd::bind(&HandleSourceControlResult, - AZStd::ref (relocationContainer), - AZStd::ref(waitSignal), - AZStd::ref(errorCount), - static_cast(SCF_OpenByUser), // If a file is moved from A -> B and then again from B -> A, the result is just an "edit", so we're just going to assume success if the file is checked out, regardless of state - true, - AZStd::placeholders::_1, - AZStd::placeholders::_2); + AzToolsFramework::SourceControlResponseCallbackBulk callback = [&](bool success, AZStd::vector info) + { + HandleSourceControlResult( + relocationContainer, waitSignal, errorCount, + SCF_OpenByUser, // If a file is moved from A -> B and then again from B -> A, the result is just an "edit", so we're just going + // to assume success if the file is checked out, regardless of state + true, success, info); + }; AzToolsFramework::SourceControlCommandBus::Broadcast(&AzToolsFramework::SourceControlCommandBus::Events::RequestRenameBulkExtended, @@ -1049,7 +1049,7 @@ Please note that only those seed files will get updated that are active for your { if (relocationInfo.m_operationStatus == SourceFileRelocationStatus::Succeeded || relocationInfo.m_sourceFileIndex == AssetProcessor::SourceFileRelocationInvalidIndex) { - // we do not want to retry if the move operation already succeeded or if it is a source file + // we do not want to retry if the move operation already succeeded or if it is a source file continue; } @@ -1108,7 +1108,7 @@ Please note that only those seed files will get updated that are active for your { if (entry.m_operationStatus == SourceFileRelocationStatus::Succeeded || entry.m_sourceFileIndex == AssetProcessor::SourceFileRelocationInvalidIndex) { - // we do not want to retry if the move operation already succeeded or if it is a source file + // we do not want to retry if the move operation already succeeded or if it is a source file continue; } @@ -1224,7 +1224,7 @@ Please note that only those seed files will get updated that are active for your m_stateData->QuerySourceByProductID(productDependency.m_productPK, [this, &sourceName, &scanPath](AzToolsFramework::AssetDatabase::SourceDatabaseEntry& entry) { sourceName = entry.m_sourceName; - + m_stateData->QueryScanFolderByScanFolderID(entry.m_scanFolderPK, [&scanPath](AzToolsFramework::AssetDatabase::ScanFolderDatabaseEntry& entry) { scanPath = entry.m_scanFolder; diff --git a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp index 08546365c5..27210685fc 100644 --- a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp +++ b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp @@ -322,7 +322,7 @@ namespace AssetProcessor executableDirectory /= ASSETPROCESSOR_TRAIT_LEGACY_RC_RELATIVE_PATH; if (AZ::IO::SystemFile::Exists(executableDirectory.c_str())) { - rcAbsolutePathOut = QString::fromUtf8(executableDirectory.c_str(), executableDirectory.Native().size()); + rcAbsolutePathOut = QString::fromUtf8(executableDirectory.c_str(), static_cast(executableDirectory.Native().size())); return true; } diff --git a/Code/Tools/ProjectManager/Platform/Windows/ProjectBuilderWorker_windows.cpp b/Code/Tools/ProjectManager/Platform/Windows/ProjectBuilderWorker_windows.cpp index a228f58e51..8856e2312a 100644 --- a/Code/Tools/ProjectManager/Platform/Windows/ProjectBuilderWorker_windows.cpp +++ b/Code/Tools/ProjectManager/Platform/Windows/ProjectBuilderWorker_windows.cpp @@ -118,7 +118,9 @@ namespace O3DE::ProjectManager } } - if (m_configProjectProcess->exitCode() != 0 || !containsGeneratingDone) + if (m_configProjectProcess->exitStatus() != QProcess::ExitStatus::NormalExit + || m_configProjectProcess->exitCode() != 0 + || !containsGeneratingDone) { QString error = tr("Configuring project failed. See log for details."); QStringToAZTracePrint(error); @@ -180,7 +182,8 @@ namespace O3DE::ProjectManager } } - if (m_configProjectProcess->exitCode() != 0) + if (m_configProjectProcess->exitStatus() != QProcess::ExitStatus::NormalExit + || m_configProjectProcess->exitCode() != 0) { QString error = tr("Building project failed. See log for details."); QStringToAZTracePrint(error); diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index 20d564d8b0..f098518fd3 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -265,6 +265,6 @@ namespace O3DE::ProjectManager void CreateProjectCtrl::ReinitGemCatalogForSelectedTemplate() { const QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath(); - m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true); + m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template"); } } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp index 53d772c217..863f611ec8 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp @@ -62,10 +62,10 @@ namespace O3DE::ProjectManager hLayout->addWidget(m_gemInspector); } - void GemCatalogScreen::ReinitForProject(const QString& projectPath, bool isNewProject) + void GemCatalogScreen::ReinitForProject(const QString& projectPath) { m_gemModel->clear(); - FillModel(projectPath, isNewProject); + FillModel(projectPath); if (m_filterWidget) { @@ -88,18 +88,9 @@ namespace O3DE::ProjectManager }); } - void GemCatalogScreen::FillModel(const QString& projectPath, bool isNewProject) + void GemCatalogScreen::FillModel(const QString& projectPath) { - AZ::Outcome, AZStd::string> allGemInfosResult; - if (isNewProject) - { - allGemInfosResult = PythonBindingsInterface::Get()->GetEngineGemInfos(); - } - else - { - allGemInfosResult = PythonBindingsInterface::Get()->GetAllGemInfos(projectPath); - } - + AZ::Outcome, AZStd::string> allGemInfosResult = PythonBindingsInterface::Get()->GetAllGemInfos(projectPath); if (allGemInfosResult.IsSuccess()) { // Add all available gems to the model. diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h index 204ad0e5c5..5b48b2f90e 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h @@ -28,13 +28,13 @@ namespace O3DE::ProjectManager ~GemCatalogScreen() = default; ProjectManagerScreen GetScreenEnum() override; - void ReinitForProject(const QString& projectPath, bool isNewProject); + void ReinitForProject(const QString& projectPath); bool EnableDisableGemsForProject(const QString& projectPath); GemModel* GetGemModel() const { return m_gemModel; } private: - void FillModel(const QString& projectPath, bool isNewProject); + void FillModel(const QString& projectPath); GemListView* m_gemListView = nullptr; GemInspector* m_gemInspector = nullptr; diff --git a/Code/Tools/ProjectManager/Source/ProjectBuilderController.cpp b/Code/Tools/ProjectManager/Source/ProjectBuilderController.cpp index e782f0b57f..0ff963e539 100644 --- a/Code/Tools/ProjectManager/Source/ProjectBuilderController.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectBuilderController.cpp @@ -104,7 +104,7 @@ namespace O3DE::ProjectManager QMessageBox::critical(m_parent, tr("Project Failed to Build!"), result); m_projectInfo.m_buildFailed = true; - m_projectInfo.m_logUrl = QUrl(); + m_projectInfo.m_logUrl = QUrl("file:///" + m_worker->GetLogFilePath()); emit NotifyBuildProject(m_projectInfo); } diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp index 981a9352f7..6aba261cd2 100644 --- a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp @@ -94,7 +94,7 @@ namespace O3DE::ProjectManager Update(); // Gather the available gems that will be shown in the gem catalog. - m_gemCatalogScreen->ReinitForProject(m_projectInfo.m_path, /*isNewProject=*/false); + m_gemCatalogScreen->ReinitForProject(m_projectInfo.m_path); } void UpdateProjectCtrl::HandleGemsButton() diff --git a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp index aa439116a0..b6a7898ca2 100644 --- a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp +++ b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp @@ -323,7 +323,7 @@ bool SRemoteServer::ReadBuffer(const char* buffer, int data) } // Advance to the next null terminated string in the buffer - const int currentSize = strnlen(curBuffer, bytesRemaining); + const int currentSize = static_cast(strnlen(curBuffer, bytesRemaining)); bytesRemaining -= currentSize + 1; curBuffer += currentSize + 1; } @@ -466,7 +466,7 @@ void SRemoteClient::FillAutoCompleteList(AZStd::vector& list) AZStd::string item = "map "; const char* levelName = pLevel->GetName(); int start = 0; - for (int k = 0, kend = strlen(levelName); k < kend; ++k) + for (int k = 0, kend = static_cast(strlen(levelName)); k < kend; ++k) { if ((levelName[k] == '\\' || levelName[k] == '/') && k + 1 < kend) { diff --git a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp index 1b712cb134..aadb834aa9 100644 --- a/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp +++ b/Code/Tools/SceneAPI/SceneBuilder/Importers/AssImpAnimationImporter.cpp @@ -634,21 +634,21 @@ namespace AZ AZStd::shared_ptr morphAnimNode = AZStd::make_shared(); - const size_t numKeyFrames = GetNumKeyFrames(keys.size(), animation->mDuration, animation->mTicksPerSecond); + const size_t numKeyFrames = GetNumKeyFrames(static_cast(keys.size()), animation->mDuration, animation->mTicksPerSecond); morphAnimNode->ReserveKeyFrames(numKeyFrames); morphAnimNode->SetTimeStepBetweenFrames(s_defaultTimeStepBetweenFrames); aiAnimMesh* aiAnimMesh = mesh->mAnimMeshes[meshIdx]; AZStd::string_view nodeName(aiAnimMesh->mName.C_Str()); - const AZ::u32 maxKeys = keys.size(); + const AZ::u32 maxKeys = static_cast(keys.size()); AZ::u32 keyIdx = 0; for (AZ::u32 frame = 0; frame < numKeyFrames; ++frame) { const double time = GetTimeForFrame(frame, animation->mTicksPerSecond); float weight = 0; - if (!SampleKeyFrame(weight, keys, keys.size(), time + keyOffset, keyIdx)) + if (!SampleKeyFrame(weight, keys, static_cast(keys.size()), time + keyOffset, keyIdx)) { return Events::ProcessingResult::Failure; } diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceCoveringTestsSerializer.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceCoveringTestsSerializer.cpp index 4de52e0f78..266791e05c 100644 --- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceCoveringTestsSerializer.cpp +++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactSourceCoveringTestsSerializer.cpp @@ -50,8 +50,8 @@ namespace TestImpact AZStd::vector coveringTests; sourceCoveringTests.reserve(1U << 16); // Reserve for approx. 65k source files const AZStd::string delim = "\n"; - auto start = 0U; - auto end = sourceCoveringTestsListString.find(delim); + size_t start = 0U; + size_t end = sourceCoveringTestsListString.find(delim); while (end != AZStd::string::npos) { diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceJobUtil.h b/Gems/AWSCore/Code/Include/Public/Framework/ServiceJobUtil.h index e9c30566cd..ad160303f7 100644 --- a/Gems/AWSCore/Code/Include/Public/Framework/ServiceJobUtil.h +++ b/Gems/AWSCore/Code/Include/Public/Framework/ServiceJobUtil.h @@ -43,8 +43,7 @@ namespace AWSCore if (urlSections.size() > ExpectedUrlSections) { - int i; - i = urlSections[ExpectedUrlSections - 1].find('.'); + int i = static_cast(urlSections[ExpectedUrlSections - 1].find('.')); if (i != -1) { // Handle APIGateway URLs with custom domains: diff --git a/Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJob.h b/Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJob.h index 20b94d6e1a..cd0686c2d0 100644 --- a/Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJob.h +++ b/Gems/AWSCore/Code/Include/Public/Framework/ServiceRequestJob.h @@ -391,7 +391,7 @@ namespace AWSCore int offset = 0; while (offset < message.size()) { - int count = (offset + MAX_MESSAGE_LENGTH < message.size()) ? MAX_MESSAGE_LENGTH : message.size() - offset; + int count = static_cast((offset + MAX_MESSAGE_LENGTH < message.size()) ? MAX_MESSAGE_LENGTH : message.size() - offset); AZ_Warning(ServiceClientJobType::COMPONENT_DISPLAY_NAME, false, message.substr(offset, count).c_str()); offset += MAX_MESSAGE_LENGTH; } diff --git a/Gems/AWSCore/Code/Source/Framework/JsonObjectHandler.cpp b/Gems/AWSCore/Code/Source/Framework/JsonObjectHandler.cpp index 71fe0fc221..d041a97428 100644 --- a/Gems/AWSCore/Code/Source/Framework/JsonObjectHandler.cpp +++ b/Gems/AWSCore/Code/Source/Framework/JsonObjectHandler.cpp @@ -443,7 +443,7 @@ namespace AWSCore msg += AZStd::string::format(" at character %zu: ", result.Offset()); const int snippet_size = 40; - int start = result.Offset() - snippet_size / 2; + int start = static_cast(result.Offset() - snippet_size / 2); int length = snippet_size; int offset = snippet_size / 2; if (start < 0) { diff --git a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp index 5c80813590..caba8b5ae7 100644 --- a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp +++ b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp @@ -51,7 +51,7 @@ protected: TEST_F(AWSScriptBehaviorsComponentTest, Reflect) { - int oldEBusNum = m_behaviorContext->m_ebuses.size(); + int oldEBusNum = static_cast(m_behaviorContext->m_ebuses.size()); m_componentDescriptor.reset(AWSScriptBehaviorsComponent::CreateDescriptor()); m_componentDescriptor->Reflect(m_serializeContext.get()); m_componentDescriptor->Reflect(m_behaviorContext.get()); diff --git a/Gems/AWSMetrics/Code/Source/MetricsEvent.cpp b/Gems/AWSMetrics/Code/Source/MetricsEvent.cpp index d787cf0bfb..e23c97a5fe 100644 --- a/Gems/AWSMetrics/Code/Source/MetricsEvent.cpp +++ b/Gems/AWSMetrics/Code/Source/MetricsEvent.cpp @@ -58,7 +58,7 @@ namespace AWSMetrics int MetricsEvent::GetNumAttributes() const { - return m_attributes.size(); + return static_cast(m_attributes.size()); } size_t MetricsEvent::GetSizeInBytes() const diff --git a/Gems/AWSMetrics/Code/Source/MetricsManager.cpp b/Gems/AWSMetrics/Code/Source/MetricsManager.cpp index 680c946b37..5c4d910658 100644 --- a/Gems/AWSMetrics/Code/Source/MetricsManager.cpp +++ b/Gems/AWSMetrics/Code/Source/MetricsManager.cpp @@ -256,7 +256,7 @@ namespace AWSMetrics } m_globalStats.m_numSuccesses++; - m_globalStats.m_sendSizeInBytes += metricsEvent.GetSizeInBytes(); + m_globalStats.m_sendSizeInBytes += static_cast(metricsEvent.GetSizeInBytes()); } else { diff --git a/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp b/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp index cd22bce5e0..ab54fb9e3e 100644 --- a/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp +++ b/Gems/AWSMetrics/Code/Source/MetricsQueue.cpp @@ -134,7 +134,7 @@ namespace AWSMetrics int MetricsQueue::GetNumMetrics() const { - return m_metrics.size(); + return static_cast(m_metrics.size()); } size_t MetricsQueue::GetSizeInBytes() const @@ -175,7 +175,7 @@ namespace AWSMetrics MetricsEvent& curEvent = m_metrics.front(); curNum += 1; - curSizeInBytes += curEvent.GetSizeInBytes(); + curSizeInBytes += static_cast(curEvent.GetSizeInBytes()); if (curNum <= maxBatchedRecordsCount && curSizeInBytes <= maxPayloadSizeInBytes) { m_sizeSerializedToJson -= curEvent.GetSizeInBytes(); diff --git a/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp b/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp index 149f23ccf2..2d9990ad1e 100644 --- a/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp +++ b/Gems/AWSMetrics/Code/Tests/MetricsManagerTest.cpp @@ -452,7 +452,7 @@ namespace AWSMetrics EXPECT_EQ(stats.m_numErrors, MaxNumMetricsEvents / 2); EXPECT_EQ(stats.m_numDropped, 0); - int metricsEventSize = sizeof(AwsMetricsAttributeKeyEventName) - 1 + strlen(AttrValue); + int metricsEventSize = static_cast(sizeof(AwsMetricsAttributeKeyEventName) - 1 + strlen(AttrValue)); EXPECT_EQ(stats.m_sendSizeInBytes, metricsEventSize * MaxNumMetricsEvents / 2); ASSERT_EQ(m_metricsManager->GetNumBufferedMetrics(), MaxNumMetricsEvents / 2); diff --git a/Gems/AWSMetrics/Code/Tests/MetricsQueueTest.cpp b/Gems/AWSMetrics/Code/Tests/MetricsQueueTest.cpp index cc05a60798..85a9d8a4a7 100644 --- a/Gems/AWSMetrics/Code/Tests/MetricsQueueTest.cpp +++ b/Gems/AWSMetrics/Code/Tests/MetricsQueueTest.cpp @@ -124,7 +124,7 @@ namespace AWSMetrics queue.AddMetrics(metrics); } - int maxCapacity = queue[0].GetSizeInBytes() * NumTestMetrics / 2; + int maxCapacity = static_cast(queue[0].GetSizeInBytes() * NumTestMetrics / 2); ASSERT_EQ(queue.FilterMetricsByPriority(maxCapacity), NumTestMetrics / 2); ASSERT_EQ(queue.GetNumMetrics(), NumTestMetrics / 2); @@ -230,7 +230,7 @@ namespace AWSMetrics { MetricsEvent metrics; metrics.AddAttribute(MetricsAttribute(AttrName, AttrValue)); - int sizeOfEachMetrics = metrics.GetSizeInBytes(); + int sizeOfEachMetrics = static_cast(metrics.GetSizeInBytes()); MetricsQueue queue; queue.AddMetrics(metrics); diff --git a/Gems/AssetMemoryAnalyzer/Code/Source/DebugImGUI.cpp b/Gems/AssetMemoryAnalyzer/Code/Source/DebugImGUI.cpp index 6e9fe1855c..aecac5fa34 100644 --- a/Gems/AssetMemoryAnalyzer/Code/Source/DebugImGUI.cpp +++ b/Gems/AssetMemoryAnalyzer/Code/Source/DebugImGUI.cpp @@ -201,13 +201,13 @@ namespace AssetMemoryAnalyzer { case AllocationCategories::HEAP: ImGui::Text(FormatUtils::FormatCodePoint(*ap->m_codePoint)); - heapSummary.m_allocationCount = ap->m_allocations.size(); + heapSummary.m_allocationCount = static_cast(ap->m_allocations.size()); heapSummary.m_allocatedMemory = ap->m_totalAllocatedMemory; break; case AllocationCategories::VRAM: ImGui::Text("%s", ap->m_codePoint->m_file); - vramSummary.m_allocationCount = ap->m_allocations.size(); + vramSummary.m_allocationCount = static_cast(ap->m_allocations.size()); vramSummary.m_allocatedMemory = ap->m_totalAllocatedMemory; break; } diff --git a/Gems/AssetMemoryAnalyzer/Code/Source/ExportJSON.cpp b/Gems/AssetMemoryAnalyzer/Code/Source/ExportJSON.cpp index 20a6089323..9f75e62454 100644 --- a/Gems/AssetMemoryAnalyzer/Code/Source/ExportJSON.cpp +++ b/Gems/AssetMemoryAnalyzer/Code/Source/ExportJSON.cpp @@ -78,7 +78,7 @@ namespace AssetMemoryAnalyzer writer.StartObject(); writer.Key("id"); - writer.Int(idCounter++); + writer.Int(static_cast(idCounter++)); writer.Key("label"); writer.String(asset.m_id ? asset.m_id : "Root"); @@ -98,7 +98,7 @@ namespace AssetMemoryAnalyzer { writer.StartObject(); writer.Key("id"); - writer.Int(idCounter++); + writer.Int(static_cast(idCounter++)); writer.Key("label"); writer.String(""); @@ -119,7 +119,7 @@ namespace AssetMemoryAnalyzer writer.StartObject(); writer.Key("id"); - writer.Int(idCounter++); + writer.Int(static_cast(idCounter++)); writer.Key("label"); @@ -127,13 +127,13 @@ namespace AssetMemoryAnalyzer { case AllocationCategories::HEAP: writer.String(FormatUtils::FormatCodePoint(*ap.m_codePoint)); - heapSummary.m_allocationCount = ap.m_allocations.size(); + heapSummary.m_allocationCount = static_cast(ap.m_allocations.size()); heapSummary.m_allocatedMemory = ap.m_totalAllocatedMemory; break; case AllocationCategories::VRAM: writer.String(ap.m_codePoint->m_file); - vramSummary.m_allocationCount = ap.m_allocations.size(); + vramSummary.m_allocationCount = static_cast(ap.m_allocations.size()); vramSummary.m_allocatedMemory = ap.m_totalAllocatedMemory; break; } diff --git a/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp b/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp index 9a6f7c83ab..330b6571f3 100644 --- a/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp +++ b/Gems/Atom/Component/DebugCamera/Code/Source/CameraComponent.cpp @@ -235,7 +235,7 @@ namespace AZ UpdateViewToClipMatrix(); } - void CameraComponent::SetOrthographic(bool orthographic) + void CameraComponent::SetOrthographic([[maybe_unused]] bool orthographic) { AZ_Assert(!orthographic, "DebugCamera does not support orthographic projection"); } diff --git a/Gems/Atom/Feature/Common/Assets/Passes/UI.pass b/Gems/Atom/Feature/Common/Assets/Passes/UI.pass index ac43f17c11..fd59df5336 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/UI.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/UI.pass @@ -13,13 +13,7 @@ "ScopeAttachmentUsage": "DepthStencil", "LoadStoreAction": { "ClearValue": { - "Type": "DepthStencil", - "Value": [ - 0.0, - 0.0, - 0.0, - 0.0 - ] + "Type": "DepthStencil" }, "LoadActionStencil": "Clear" } diff --git a/Gems/Atom/Feature/Common/Code/Source/AuxGeom/DynamicPrimitiveProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/AuxGeom/DynamicPrimitiveProcessor.cpp index 08b3821b41..ea726dd914 100644 --- a/Gems/Atom/Feature/Common/Code/Source/AuxGeom/DynamicPrimitiveProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/AuxGeom/DynamicPrimitiveProcessor.cpp @@ -196,13 +196,13 @@ namespace AZ { const size_t sourceByteSize = source.size() * sizeof(AuxGeomIndex); - RHI::Ptr dynamicBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(sourceByteSize); + RHI::Ptr dynamicBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(static_cast(sourceByteSize)); if (!dynamicBuffer) { AZ_WarningOnce("AuxGeom", false, "Failed to allocate dynamic buffer of size %d.", sourceByteSize); return false; - } - dynamicBuffer->Write(source.data(), sourceByteSize); + } + dynamicBuffer->Write(source.data(), static_cast(sourceByteSize)); group.m_indexBufferView = dynamicBuffer->GetIndexBufferView(RHI::IndexFormat::Uint32); return true; } @@ -211,13 +211,13 @@ namespace AZ { const size_t sourceByteSize = source.size() * sizeof(AuxGeomDynamicVertex); - RHI::Ptr dynamicBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(sourceByteSize); + RHI::Ptr dynamicBuffer = RPI::DynamicDrawInterface::Get()->GetDynamicBuffer(static_cast(sourceByteSize)); if (!dynamicBuffer) { AZ_WarningOnce("AuxGeom", false, "Failed to allocate dynamic buffer of size %d.", sourceByteSize); return false; - } - dynamicBuffer->Write(source.data(), sourceByteSize); + } + dynamicBuffer->Write(source.data(), static_cast(sourceByteSize)); group.m_streamBufferViews[0] = dynamicBuffer->GetStreamBufferView(sizeof(AuxGeomDynamicVertex)); return true; } diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PolygonLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PolygonLightFeatureProcessor.cpp index b1456f82fe..089adf4621 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PolygonLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PolygonLightFeatureProcessor.cpp @@ -145,7 +145,7 @@ namespace AZ::Render // individual point as its own element instead of each array being its own element. Since all // the arrays are stored in a contiguous vector, we can treat it as one giant array. const LightPosition* firstPosition = m_polygonLightData.GetDataVector<1>().at(0).data(); - m_lightPolygonPointBufferHandler.UpdateBuffer(firstPosition, m_polygonLightData.GetDataCount() * MaxPolygonPoints); + m_lightPolygonPointBufferHandler.UpdateBuffer(firstPosition, static_cast(m_polygonLightData.GetDataCount() * MaxPolygonPoints)); } m_deviceBufferNeedsUpdate = false; } diff --git a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp index 96041dc89d..4b1a6ec7f6 100644 --- a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp @@ -65,7 +65,7 @@ namespace AZ AZ::JobCompletion jobCompletion; const int numThreads = 8; - const int numPixelsPerThread = buffer->size() / numChannels / numThreads; + const int numPixelsPerThread = static_cast(buffer->size() / numChannels / numThreads); for (int i = 0; i < numThreads; ++i) { int startPixel = i * numPixelsPerThread; diff --git a/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetDispatchItem.cpp b/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetDispatchItem.cpp index 71f17b3361..0f8a30d8aa 100644 --- a/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetDispatchItem.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/MorphTargets/MorphTargetDispatchItem.cpp @@ -162,7 +162,7 @@ namespace AZ m_rootConstantData.SetConstant(colorOffsetIndex, m_morphInstanceMetaData.m_accumulatedColorDeltaOffsetInBytes / 4); } - m_dispatchItem.m_rootConstantSize = m_rootConstantData.GetConstantData().size(); + m_dispatchItem.m_rootConstantSize = static_cast(m_rootConstantData.GetConstantData().size()); m_dispatchItem.m_rootConstants = m_rootConstantData.GetConstantData().data(); } diff --git a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp index 03ee176fd0..5a25951163 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp @@ -497,7 +497,7 @@ namespace AZ::Render const ShadowmapAtlas& atlas = m_projectedShadowmapsPasses.front()->GetShadowmapAtlas(); const Data::Instance indexTableBuffer = atlas.CreateShadowmapIndexTableBuffer(indexTableBufferName); - m_filterParamBufferHandler.UpdateBuffer(m_shadowData.GetRawData(), m_shadowData.GetSize()); + m_filterParamBufferHandler.UpdateBuffer(m_shadowData.GetRawData(), static_cast(m_shadowData.GetSize())); // Set index table buffer and ESM parameter buffer to ESM pass. for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses) @@ -564,7 +564,7 @@ namespace AZ::Render if (m_deviceBufferNeedsUpdate) { - m_shadowBufferHandler.UpdateBuffer(m_shadowData.GetRawData(), m_shadowData.GetSize()); + m_shadowBufferHandler.UpdateBuffer(m_shadowData.GetRawData(), static_cast(m_shadowData.GetSize())); m_deviceBufferNeedsUpdate = false; } } diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp index de2c52d1c8..af427eb554 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshInputBuffers.cpp @@ -446,7 +446,7 @@ namespace AZ // Positions start at the beginning of the allocation instanceMetaData.m_accumulatedPositionDeltaOffsetInBytes = allocation->GetVirtualAddress().m_ptr; - uint32_t deltaStreamSizeInBytes = vertexCount * MorphTargetConstants::s_unpackedMorphTargetDeltaSizeInBytes; + uint32_t deltaStreamSizeInBytes = static_cast(vertexCount * MorphTargetConstants::s_unpackedMorphTargetDeltaSizeInBytes); // Followed by normals, tangents, and bitangents instanceMetaData.m_accumulatedNormalDeltaOffsetInBytes = instanceMetaData.m_accumulatedPositionDeltaOffsetInBytes + deltaStreamSizeInBytes; diff --git a/Gems/Atom/Feature/Common/Code/Tests/SparseVectorTests.cpp b/Gems/Atom/Feature/Common/Code/Tests/SparseVectorTests.cpp index 0a31fe4c9e..e3f3ea906b 100644 --- a/Gems/Atom/Feature/Common/Code/Tests/SparseVectorTests.cpp +++ b/Gems/Atom/Feature/Common/Code/Tests/SparseVectorTests.cpp @@ -81,7 +81,7 @@ namespace UnitTest EXPECT_EQ(data.c, TestData::DefaultValueC); // Assign new unique values - data.a = TestData::DefaultValueA * i; + data.a = TestData::DefaultValueA * static_cast(i); data.b = TestData::DefaultValueB * float(i); data.c = i % 2 == 0; } @@ -190,12 +190,12 @@ namespace UnitTest EXPECT_EQ(data.b, TestData::DefaultValueB); EXPECT_EQ(data.c, TestData::DefaultValueC); - data.a = TestData::DefaultValueA * i; + data.a = TestData::DefaultValueA * static_cast(i); data.b = TestData::DefaultValueB * float(i); data.c = i % 2 == 0; // Assign some values to the uninitialized primitive types - container.GetElement<1>(indices[i]) = i * 10; + container.GetElement<1>(indices[i]) = static_cast(i * 10); container.GetElement<2>(indices[i]) = i * 20.0f; } @@ -254,7 +254,7 @@ namespace UnitTest { indices[i] = container.Reserve(); - container.GetElement<1>(i) = i * 10; + container.GetElement<1>(i) = static_cast(i * 10); container.GetElement<2>(i) = i * 20.0f; } diff --git a/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp b/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp index 7461a7c3e8..a9e08249c4 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/ShaderResourceGroupData.cpp @@ -139,7 +139,7 @@ namespace AZ bool isValidAll = true; for (size_t i = 0; i < imageViews.size(); ++i) { - const bool isValid = ValidateImageViewAccess(inputIndex, imageViews[i], i); + const bool isValid = ValidateImageViewAccess(inputIndex, imageViews[i], static_cast(i)); if (isValid) { m_imageViewsUnboundedArray.push_back(imageViews[i]); @@ -185,7 +185,7 @@ namespace AZ bool isValidAll = true; for (size_t i = 0; i < bufferViews.size(); ++i) { - const bool isValid = ValidateBufferViewAccess(inputIndex, bufferViews[i], i); + const bool isValid = ValidateBufferViewAccess(inputIndex, bufferViews[i], static_cast(i)); if (isValid) { m_bufferViewsUnboundedArray.push_back(bufferViews[i]); diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/ShaderResourceGroupPool.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/ShaderResourceGroupPool.cpp index 7437c3b339..d51fdd3495 100644 --- a/Gems/Atom/RHI/DX12/Code/Source/RHI/ShaderResourceGroupPool.cpp +++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/ShaderResourceGroupPool.cpp @@ -356,7 +356,7 @@ namespace AZ if (!bufferViews.empty()) { - group.m_unboundedDescriptorTables[tableIndex] = m_descriptorContext->CreateDescriptorTable(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, bufferViews.size()); + group.m_unboundedDescriptorTables[tableIndex] = m_descriptorContext->CreateDescriptorTable(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, static_cast(bufferViews.size())); AZ_Assert(group.m_unboundedDescriptorTables[tableIndex].IsValid(), "Descriptor context failed to allocate unbounded array descriptor table, most likely out of memory."); ShaderResourceGroupCompiledData& compiledData = group.m_compiledData[group.m_compiledDataIndex]; @@ -415,7 +415,7 @@ namespace AZ if (!imageViews.empty()) { - group.m_unboundedDescriptorTables[tableIndex] = m_descriptorContext->CreateDescriptorTable(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, imageViews.size()); + group.m_unboundedDescriptorTables[tableIndex] = m_descriptorContext->CreateDescriptorTable(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, static_cast(imageViews.size())); AZ_Assert(group.m_unboundedDescriptorTables[tableIndex].IsValid(), "Descriptor context failed to allocate unbounded array descriptor table, most likely out of memory."); ShaderResourceGroupCompiledData& compiledData = group.m_compiledData[group.m_compiledDataIndex]; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingPipelineState.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingPipelineState.cpp index b4c153a38c..33623f93e4 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingPipelineState.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RayTracingPipelineState.cpp @@ -163,9 +163,9 @@ namespace AZ createInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR; createInfo.pNext = nullptr; createInfo.flags = 0; - createInfo.stageCount = stages.size(); + createInfo.stageCount = static_cast(stages.size()); createInfo.pStages = stages.data(); - createInfo.groupCount = groups.size(); + createInfo.groupCount = static_cast(groups.size()); createInfo.pGroups = groups.data(); createInfo.maxPipelineRayRecursionDepth = descriptor->GetConfiguration().m_maxRecursionDepth; createInfo.layout = m_pipelineLayout; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp index 7100b2cd48..fb8708fb88 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp @@ -109,7 +109,7 @@ namespace AZ if (auto* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(29); // (updated to separate material slot ID from default material asset) + ->Version(30); // (updated to separate material slot ID from default material asset) } } @@ -882,7 +882,7 @@ namespace AZ processedMorphTargets = true; } - totalVertexCount += vertexCount; + totalVertexCount += static_cast(vertexCount); productMeshList.emplace_back(productMesh); } } @@ -960,7 +960,7 @@ namespace AZ for (const auto& skinData : sourceMesh.m_skinData) { const size_t numJoints = skinData->GetBoneCount(); - const AZ::u32 controlPointIndex = sourceMeshData->GetControlPointIndex(vertexIndex); + const AZ::u32 controlPointIndex = sourceMeshData->GetControlPointIndex(static_cast(vertexIndex)); const size_t numSkinInfluences = skinData->GetLinkCount(controlPointIndex); size_t numInfluencesExcess = 0; @@ -1195,15 +1195,15 @@ namespace AZ mesh.m_skinWeights.size(), m_numSkinJointInfluencesPerVertex, m_numSkinJointInfluencesPerVertex); const size_t numSkinInfluences = mesh.m_skinWeights.size(); - uint32_t jointIndicesSizeInBytes = numSkinInfluences * sizeof(uint16_t); + uint32_t jointIndicesSizeInBytes = static_cast(numSkinInfluences * sizeof(uint16_t)); meshView.m_skinJointIndicesView = RHI::BufferViewDescriptor::CreateRaw(0, jointIndicesSizeInBytes); - meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(0, numSkinInfluences, SkinWeightFormat); + meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(0, static_cast(numSkinInfluences), SkinWeightFormat); } if (!mesh.m_morphTargetVertexData.empty()) { const size_t numTotalVertices = mesh.m_morphTargetVertexData.size(); - meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(0, numTotalVertices, sizeof(PackedCompressedMorphTargetDelta)); + meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(0, static_cast(numTotalVertices), sizeof(PackedCompressedMorphTargetDelta)); } if (!mesh.m_clothData.empty()) @@ -1358,8 +1358,8 @@ namespace AZ const size_t numPrevSkinInfluences = lodBufferInfo.m_skinInfluencesCount; const size_t numNewSkinInfluences = mesh.m_skinWeights.size(); - meshView.m_skinJointIndicesView = RHI::BufferViewDescriptor::CreateRaw(/*byteOffset=*/numPrevSkinInfluences * sizeof(uint16_t), numNewSkinInfluences * sizeof(uint16_t)); - meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(/*elementOffset=*/numPrevSkinInfluences, numNewSkinInfluences, SkinWeightFormat); + meshView.m_skinJointIndicesView = RHI::BufferViewDescriptor::CreateRaw(/*byteOffset=*/ static_cast(numPrevSkinInfluences * sizeof(uint16_t)), static_cast(numNewSkinInfluences * sizeof(uint16_t))); + meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(/*elementOffset=*/ static_cast(numPrevSkinInfluences), static_cast(numNewSkinInfluences), SkinWeightFormat); lodBufferInfo.m_skinInfluencesCount += numNewSkinInfluences; } @@ -1369,7 +1369,7 @@ namespace AZ const size_t numPrevVertexDeltas = lodBufferInfo.m_morphTargetVertexDeltaCount; const size_t numNewVertexDeltas = mesh.m_morphTargetVertexData.size(); - meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(/*elementOffset=*/numPrevVertexDeltas, numNewVertexDeltas, sizeof(PackedCompressedMorphTargetDelta)); + meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(/*elementOffset=*/ static_cast(numPrevVertexDeltas), static_cast(numNewVertexDeltas), sizeof(PackedCompressedMorphTargetDelta)); lodBufferInfo.m_morphTargetVertexDeltaCount += numNewVertexDeltas; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp index fefe835ee9..0a1fb49ab5 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp @@ -110,8 +110,8 @@ namespace AZ::RPI { AZ::Aabb meshAabb = AZ::Aabb::CreateNull(); - const size_t numVertices = mesh.m_meshData->GetVertexCount(); - for (size_t i = 0; i < numVertices; ++i) + const unsigned int numVertices = static_cast(mesh.m_meshData->GetVertexCount()); + for (unsigned int i = 0; i < numVertices; ++i) { meshAabb.AddPoint(mesh.m_meshData->GetPosition(i)); } @@ -164,7 +164,7 @@ namespace AZ::RPI blendShapeName.c_str(), numVertices, sourceMesh.m_meshData->GetVertexCount()); // The start index is after any previously added deltas - metaData.m_startIndex = aznumeric_caster(packedCompressedMorphTargetVertexData.size()); + metaData.m_startIndex = aznumeric_cast(packedCompressedMorphTargetVertexData.size()); // Multiply normal by inverse transpose to avoid incorrect values produced by non-uniformly scaled transforms. diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/PipelineState.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/PipelineState.cpp index ba9e6b20ed..8e0aa62554 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/PipelineState.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/PipelineState.cpp @@ -172,7 +172,7 @@ namespace AZ } m_pipelineState = m_shader->AcquirePipelineState(descriptor); - } + } m_dirty = false; } return m_pipelineState; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp index 071a07ecda..02a03ee853 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp @@ -782,7 +782,7 @@ namespace AZ pipelineStateList.push_back(); pipelineStateList[size].m_multisampleState = rasterPass->GetMultisampleState(); pipelineStateList[size].m_renderAttachmentConfiguration = rasterPass->GetRenderAttachmentConfiguration(); - rasterPass->SetPipelineStateDataIndex(size); + rasterPass->SetPipelineStateDataIndex(static_cast(size)); } } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAsset.cpp index 1436e62d7f..f2d82918ea 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderAsset.cpp @@ -516,7 +516,7 @@ namespace AZ SupervariantIndex ShaderAsset::GetSupervariantIndexInternal(AZ::Name supervariantName) const { const auto& supervariants = GetCurrentShaderApiData().m_supervariants; - const uint32_t supervariantCount = supervariants.size(); + const uint32_t supervariantCount = static_cast(supervariants.size()); for (uint32_t index = 0; index < supervariantCount; ++index) { if (supervariants[index].m_name == supervariantName) diff --git a/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp b/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp index 368fb2c3c6..21f3239698 100644 --- a/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Model/ModelTests.cpp @@ -1045,23 +1045,23 @@ namespace UnitTest lodCreator.SetMeshMaterialSlot(AZ::Sfmt::GetInstance().Rand32()); { - AZ::Data::Asset indexBuffer = BuildTestBuffer(indicesCount, sizeof(uint32_t)); + AZ::Data::Asset indexBuffer = BuildTestBuffer(static_cast(indicesCount), sizeof(uint32_t)); AZStd::copy(indices, indices + indicesCount, reinterpret_cast(const_cast(indexBuffer->GetBuffer().data()))); lodCreator.SetMeshIndexBuffer({ indexBuffer, - AZ::RHI::BufferViewDescriptor::CreateStructured(0, indicesCount, sizeof(uint32_t)) + AZ::RHI::BufferViewDescriptor::CreateStructured(0, static_cast(indicesCount), sizeof(uint32_t)) }); } { - AZ::Data::Asset positionBuffer = BuildTestBuffer(positionCount / 3, sizeof(float) * 3); + AZ::Data::Asset positionBuffer = BuildTestBuffer(static_cast(positionCount / 3), sizeof(float) * 3); AZStd::copy(positions, positions + positionCount, reinterpret_cast(const_cast(positionBuffer->GetBuffer().data()))); lodCreator.AddMeshStreamBuffer( AZ::RHI::ShaderSemantic(AZ::Name("POSITION")), AZ::Name(), { positionBuffer, - AZ::RHI::BufferViewDescriptor::CreateStructured(0, positionCount / 3, sizeof(float) * 3) + AZ::RHI::BufferViewDescriptor::CreateStructured(0, static_cast(positionCount / 3), sizeof(float) * 3) } ); } diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h index 1d2ccc07e1..e6a666c640 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h @@ -16,37 +16,62 @@ namespace AtomToolsFramework { - class ModernViewportCameraControllerInstance; + class ModularViewportCameraControllerInstance; + + //! A function object to represent returning a camera controller priority. + using CameraControllerPriorityFn = + AZStd::function; + + //! The default behavior for what priority the camera controller should respond to events at. + //! @note This can change based on the state of the camera controller/system. + AzFramework::ViewportControllerPriority DefaultCameraControllerPriority(const AzFramework::CameraSystem& cameraSystem); + + //! Builder class to create and configure a ModularViewportCameraControllerInstance. class ModularViewportCameraController : public AzFramework::MultiViewportController< - ModernViewportCameraControllerInstance, AzFramework::ViewportControllerPriority::DispatchToAllPriorities> + ModularViewportCameraControllerInstance, + AzFramework::ViewportControllerPriority::DispatchToAllPriorities> { public: + friend ModularViewportCameraControllerInstance; + using CameraListBuilder = AZStd::function; using CameraPropsBuilder = AZStd::function; + using CameraPriorityBuilder = AZStd::function; - //! Sets the camera list builder callback used to populate new ModernViewportCameraControllerInstances + //! Sets the camera list builder callback used to populate new ModularViewportCameraControllerInstances. void SetCameraListBuilderCallback(const CameraListBuilder& builder); - //! Sets the camera props builder callback used to populate new ModernViewportCameraControllerInstances + //! Sets the camera props builder callback used to populate new ModularViewportCameraControllerInstances. void SetCameraPropsBuilderCallback(const CameraPropsBuilder& builder); - //! Sets up a camera list based on this controller's CameraListBuilderCallback - void SetupCameras(AzFramework::Cameras& cameras); - //! Sets up properties shared across all cameras - void SetupCameraProperies(AzFramework::CameraProps& cameraProps); + //! Sets the camera controller priority builder callback used to populate new ModularViewportCameraControllerInstances. + void SetCameraPriorityBuilderCallback(const CameraPriorityBuilder& builder); private: + //! Sets up a camera list based on this controller's CameraListBuilderCallback. + void SetupCameras(AzFramework::Cameras& cameras); + //! Sets up properties shared across all cameras. + void SetupCameraProperties(AzFramework::CameraProps& cameraProps); + //! Sets up how the camera controller should decide at what priority level to respond to. + void SetupCameraControllerPriority(CameraControllerPriorityFn& cameraPriorityFn); + + //! Builder to generate a list of CameraInputs to run in the ModularViewportCameraControllerInstance. CameraListBuilder m_cameraListBuilder; + //! Builder to define custom camera properties to use for things such as rotate and translate interpolation. CameraPropsBuilder m_cameraPropsBuilder; + //! Builder to define what priority level the camera controller should respond to events at. + CameraPriorityBuilder m_cameraControllerPriorityBuilder; }; - class ModernViewportCameraControllerInstance final - : public AzFramework::MultiViewportControllerInstanceInterface, - public ModularViewportCameraControllerRequestBus::Handler, - private AzFramework::ViewportDebugDisplayEventBus::Handler + //! A customizable camera controller that can be configured to run a varying set of CameraInput instances. + //! The controller can also be animated from its current transform to a new translation and orientation. + class ModularViewportCameraControllerInstance final + : public AzFramework::MultiViewportControllerInstanceInterface + , public ModularViewportCameraControllerRequestBus::Handler + , private AzFramework::ViewportDebugDisplayEventBus::Handler { public: - explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModularViewportCameraController* controller); - ~ModernViewportCameraControllerInstance() override; + explicit ModularViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModularViewportCameraController* controller); + ~ModularViewportCameraControllerInstance() override; // MultiViewportControllerInstanceInterface overrides ... bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override; @@ -60,25 +85,35 @@ namespace AtomToolsFramework // AzFramework::ViewportDebugDisplayEventBus overrides ... void DisplayViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; + //! The current mode the camera controller is in. enum class CameraMode { - Control, - Animation + Control, //!< The camera is being driven by user input. + Animation //!< The camera is being animated (interpolated) from one transform to another. }; - AzFramework::Camera m_camera; - AzFramework::Camera m_targetCamera; - AzFramework::CameraSystem m_cameraSystem; - AzFramework::CameraProps m_cameraProps; + //! Encapsulates an animation (interpolation) between two transforms. + struct CameraAnimation + { + //! The transform of the camera at the start of the animation. + AZ::Transform m_transformStart = AZ::Transform::CreateIdentity(); + AZ::Transform m_transformEnd = AZ::Transform::CreateIdentity(); //!< The transform of the camera at the end of the animation. + float m_time = 0.0f; //!< The interpolation amount between the start and end transforms (in the range 0.0 - 1.0). + }; - AZ::Transform m_transformStart = AZ::Transform::CreateIdentity(); - AZ::Transform m_transformEnd = AZ::Transform::CreateIdentity(); - float m_animationT = 0.0f; - CameraMode m_cameraMode = CameraMode::Control; + AzFramework::Camera m_camera; //!< The current camera state (pitch/yaw/position/look-distance). + AzFramework::Camera m_targetCamera; //!< The target (next) camera state that m_camera is catching up to. + AzFramework::CameraSystem m_cameraSystem; //!< The camera system responsible for managing all CameraInputs. + AzFramework::CameraProps m_cameraProps; //!< Camera properties to control rotate and translate smoothness. + CameraControllerPriorityFn m_priorityFn; //!< Controls at what priority the camera controller should respond to events. + + CameraAnimation m_cameraAnimation; //!< Camera animation state (used during CameraMode::Animation). + CameraMode m_cameraMode = CameraMode::Control; //!< The current mode the camera is operating in. AZStd::optional m_lookAtAfterInterpolation; //!< The look at point after an interpolation has finished. //!< Will be cleared when the view changes (camera looks away). - bool m_updatingTransform = false; - + //! Flag to prevent circular updates of the camera transform (while the viewport transform is being updated internally). + bool m_updatingTransformInternally = false; + //! Listen for camera view changes outside of the camera controller. AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraViewMatrixChangeHandler; }; } // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 3a542db1a4..3d9219edc5 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -87,14 +87,12 @@ namespace AtomToolsFramework if (auto behaviorContext = azrtti_cast(context)) { - auto targetName = GetBuildTargetName(); - // this will put these methods into the 'azlmbr.AtomTools.general' module - auto addGeneral = [targetName](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) + auto addGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) { methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, targetName); + ->Attribute(AZ::Script::Attributes::Module, "atomtools.general"); }; // The reflection here is based on patterns in CryEditPythonHandler::Reflect addGeneral(behaviorContext->Method( diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp index 10cfa059aa..e98df83930 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp @@ -68,6 +68,11 @@ namespace AtomToolsFramework m_cameraPropsBuilder = builder; } + void ModularViewportCameraController::SetCameraPriorityBuilderCallback(const CameraPriorityBuilder& builder) + { + m_cameraControllerPriorityBuilder = builder; + } + void ModularViewportCameraController::SetupCameras(AzFramework::Cameras& cameras) { if (m_cameraListBuilder) @@ -76,7 +81,7 @@ namespace AtomToolsFramework } } - void ModularViewportCameraController::SetupCameraProperies(AzFramework::CameraProps& cameraProps) + void ModularViewportCameraController::SetupCameraProperties(AzFramework::CameraProps& cameraProps) { if (m_cameraPropsBuilder) { @@ -84,18 +89,43 @@ namespace AtomToolsFramework } } - ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance( + void ModularViewportCameraController::SetupCameraControllerPriority(CameraControllerPriorityFn& cameraPriorityFn) + { + if (m_cameraControllerPriorityBuilder) + { + m_cameraControllerPriorityBuilder(cameraPriorityFn); + } + } + + // what priority should the camera system respond to + AzFramework::ViewportControllerPriority DefaultCameraControllerPriority(const AzFramework::CameraSystem& cameraSystem) + { + // ModernViewportCameraControllerInstance receives events at all priorities, when it is in 'exclusive' mode + // or it is actively handling events (essentially when the camera system is 'active' and responding to inputs) + // it should only respond to the highest priority + if (cameraSystem.m_cameras.Exclusive() || cameraSystem.HandlingEvents()) + { + return AzFramework::ViewportControllerPriority::Highest; + } + + // otherwise it should only respond to normal priority events + return AzFramework::ViewportControllerPriority::Normal; + } + + ModularViewportCameraControllerInstance::ModularViewportCameraControllerInstance( const AzFramework::ViewportId viewportId, ModularViewportCameraController* controller) : MultiViewportControllerInstanceInterface(viewportId, controller) { controller->SetupCameras(m_cameraSystem.m_cameras); - controller->SetupCameraProperies(m_cameraProps); + controller->SetupCameraProperties(m_cameraProps); + controller->SetupCameraControllerPriority(m_priorityFn); if (auto viewportContext = RetrieveViewportContext(GetViewportId())) { auto handleCameraChange = [this, viewportContext](const AZ::Matrix4x4&) { - if (!m_updatingTransform) + // ignore these updates if the camera is being updated internally + if (!m_updatingTransformInternally) { UpdateCameraFromTransform(m_targetCamera, viewportContext->GetCameraTransform()); m_camera = m_targetCamera; @@ -111,30 +141,15 @@ namespace AtomToolsFramework ModularViewportCameraControllerRequestBus::Handler::BusConnect(viewportId); } - ModernViewportCameraControllerInstance::~ModernViewportCameraControllerInstance() + ModularViewportCameraControllerInstance::~ModularViewportCameraControllerInstance() { ModularViewportCameraControllerRequestBus::Handler::BusDisconnect(); AzFramework::ViewportDebugDisplayEventBus::Handler::BusDisconnect(); } - // what priority should the camera system respond to - static AzFramework::ViewportControllerPriority GetPriority(const AzFramework::CameraSystem& cameraSystem) + bool ModularViewportCameraControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) { - // ModernViewportCameraControllerInstance receives events at all priorities, when it is in 'exclusive' mode - // or it is actively handling events (essentially when the camera system is 'active' and responding to inputs) - // it should only respond to the highest priority - if (cameraSystem.m_cameras.Exclusive() || cameraSystem.HandlingEvents()) - { - return AzFramework::ViewportControllerPriority::Highest; - } - - // otherwise it should only respond to normal priority events - return AzFramework::ViewportControllerPriority::Normal; - } - - bool ModernViewportCameraControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) - { - if (event.m_priority == GetPriority(m_cameraSystem)) + if (event.m_priority == m_priorityFn(m_cameraSystem)) { return m_cameraSystem.HandleEvents(AzFramework::BuildInputEvent(event.m_inputChannel)); } @@ -142,7 +157,7 @@ namespace AtomToolsFramework return false; } - void ModernViewportCameraControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) + void ModularViewportCameraControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) { // only update for a single priority (normal is the default) if (event.m_priority != AzFramework::ViewportControllerPriority::Normal) @@ -152,7 +167,7 @@ namespace AtomToolsFramework if (auto viewportContext = RetrieveViewportContext(GetViewportId())) { - m_updatingTransform = true; + m_updatingTransformInternally = true; if (m_cameraMode == CameraMode::Control) { @@ -180,10 +195,12 @@ namespace AtomToolsFramework return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); }; - const float transitionT = smootherStepFn(m_animationT); + const auto& [transformStart, transformEnd, animationTime] = m_cameraAnimation; + + const float transitionTime = smootherStepFn(animationTime); const AZ::Transform current = AZ::Transform::CreateFromQuaternionAndTranslation( - m_transformStart.GetRotation().Slerp(m_transformEnd.GetRotation(), transitionT), - m_transformStart.GetTranslation().Lerp(m_transformEnd.GetTranslation(), transitionT)); + transformStart.GetRotation().Slerp(transformEnd.GetRotation(), transitionTime), + transformStart.GetTranslation().Lerp(transformEnd.GetTranslation(), transitionTime)); const AZ::Vector3 eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromTransform(current)); m_camera.m_pitch = eulerAngles.GetX(); @@ -191,21 +208,21 @@ namespace AtomToolsFramework m_camera.m_lookAt = current.GetTranslation(); m_targetCamera = m_camera; - if (m_animationT >= 1.0f) + if (animationTime >= 1.0f) { m_cameraMode = CameraMode::Control; } - m_animationT = AZ::GetClamp(m_animationT + event.m_deltaTime.count(), 0.0f, 1.0f); + m_cameraAnimation.m_time = AZ::GetClamp(animationTime + event.m_deltaTime.count(), 0.0f, 1.0f); viewportContext->SetCameraTransform(current); } - m_updatingTransform = false; + m_updatingTransformInternally = false; } } - void ModernViewportCameraControllerInstance::DisplayViewport( + void ModularViewportCameraControllerInstance::DisplayViewport( [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) { if (const float alpha = AZStd::min(-m_camera.m_lookDist / 5.0f, 1.0f); alpha > AZ::Constants::FloatEpsilon) @@ -216,16 +233,14 @@ namespace AtomToolsFramework } } - void ModernViewportCameraControllerInstance::InterpolateToTransform(const AZ::Transform& worldFromLocal, const float lookAtDistance) + void ModularViewportCameraControllerInstance::InterpolateToTransform(const AZ::Transform& worldFromLocal, const float lookAtDistance) { - m_animationT = 0.0f; m_cameraMode = CameraMode::Animation; - m_transformStart = m_camera.Transform(); - m_transformEnd = worldFromLocal; - m_lookAtAfterInterpolation = m_transformEnd.GetTranslation() + m_transformEnd.GetBasisY() * lookAtDistance; + m_cameraAnimation = CameraAnimation{ m_camera.Transform(), worldFromLocal, 0.0f }; + m_lookAtAfterInterpolation = worldFromLocal.GetTranslation() + worldFromLocal.GetBasisY() * lookAtDistance; } - AZStd::optional ModernViewportCameraControllerInstance::LookAtAfterInterpolation() const + AZStd::optional ModularViewportCameraControllerInstance::LookAtAfterInterpolation() const { return m_lookAtAfterInterpolation; } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 0977694b90..6f1bdfb083 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -28,11 +27,11 @@ #include -#include #include #include #include +#include #include #include #include @@ -73,15 +72,14 @@ namespace MaterialEditor { QApplication::setApplicationName("O3DE Material Editor"); + // The settings registry has been created at this point, so add the CMake target AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); } MaterialEditorApplication::~MaterialEditorApplication() { - AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); MaterialEditorWindowNotificationBus::Handler::BusDisconnect(); - AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); } void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) @@ -122,7 +120,7 @@ namespace MaterialEditor &MaterialEditor::MaterialEditorWindowRequestBus::Handler::ActivateWindow); } - // Process command line options for opening one or more material documents on startup + // Process command line options for opening one or more documents on startup size_t openDocumentCount = commandLine.GetNumMiscValues(); for (size_t openDocumentIndex = 0; openDocumentIndex < openDocumentCount; ++openDocumentIndex) { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index abb0102de6..47f2127405 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -144,7 +144,7 @@ namespace MaterialEditor if (!windowSettings->m_mainWindowState.empty()) { - QByteArray windowState(windowSettings->m_mainWindowState.data(), windowSettings->m_mainWindowState.size()); + QByteArray windowState(windowSettings->m_mainWindowState.data(), static_cast(windowSettings->m_mainWindowState.size())); m_advancedDockManager->restoreState(windowState); } diff --git a/Gems/Atom/Tools/MaterialEditor/Scripts/GenerateAllMaterialScreenshots.py b/Gems/Atom/Tools/MaterialEditor/Scripts/GenerateAllMaterialScreenshots.py index d2c9bf209e..d7f52d7a24 100755 --- a/Gems/Atom/Tools/MaterialEditor/Scripts/GenerateAllMaterialScreenshots.py +++ b/Gems/Atom/Tools/MaterialEditor/Scripts/GenerateAllMaterialScreenshots.py @@ -114,11 +114,11 @@ def SetCameraPitch(pitch): azlmbr.render.ArcBallControllerRequestBus(azlmbr.bus.Broadcast, 'SetPitch', pitch) def IdleFrames(numFrames): - azlmbr.materialeditor.general.idle_wait_frames(numFrames) + azlmbr.atomtools.general.idle_wait_frames(numFrames) def CaptureScreenshot(screenshotOutputPath): print("Capturing screenshot to " + screenshotOutputPath + " ...") - return ScreenshotHelper(azlmbr.materialeditor.general.idle_wait_frames).capture_screenshot_blocking(screenshotOutputPath) + return ScreenshotHelper(azlmbr.atomtools.general.idle_wait_frames).capture_screenshot_blocking(screenshotOutputPath) def ResizeViewport(width, height): # This locks the size of the render target to the desired resolution diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 7e09f88f4f..947cf55050 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -25,26 +25,27 @@ #include #include -#include -#include #include -#include -#include +#include +#include #include #include #include #include +#include +#include + AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT -#include #include #include AZ_POP_DISABLE_WARNING namespace ShaderManagementConsole { + //! This function returns the build system target name of "ShaderManagementConsole AZStd::string ShaderManagementConsoleApplication::GetBuildTargetName() const { #if !defined(LY_CMAKE_TARGET) @@ -74,6 +75,11 @@ namespace ShaderManagementConsole *AZ::SettingsRegistry::Get(), GetBuildTargetName()); } + ShaderManagementConsoleApplication::~ShaderManagementConsoleApplication() + { + ShaderManagementConsoleWindowNotificationBus::Handler::BusDisconnect(); + } + void ShaderManagementConsoleApplication::CreateStaticModules(AZStd::vector& outModules) { Base::CreateStaticModules(outModules); @@ -84,8 +90,6 @@ namespace ShaderManagementConsole void ShaderManagementConsoleApplication::OnShaderManagementConsoleWindowClosing() { ExitMainLoop(); - ShaderManagementConsoleWindowNotificationBus::Handler::BusDisconnect(); - AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); } void ShaderManagementConsoleApplication::Destroy() @@ -104,27 +108,19 @@ namespace ShaderManagementConsole return AZStd::vector({ "passes/", "config/" }); } - void ShaderManagementConsoleApplication::ProcessCommandLine() + void ShaderManagementConsoleApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) { - // Process command line options for running one or more python scripts on startup - const AZStd::string runPythonScriptSwitchName = "runpython"; - size_t runPythonScriptCount = m_commandLine.GetNumSwitchValues(runPythonScriptSwitchName); - for (size_t runPythonScriptIndex = 0; runPythonScriptIndex < runPythonScriptCount; ++runPythonScriptIndex) - { - const AZStd::string runPythonScriptPath = m_commandLine.GetSwitchValue(runPythonScriptSwitchName, runPythonScriptIndex); - AZStd::vector runPythonArgs; - AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast( - &AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, runPythonScriptPath, runPythonArgs); - } - // Process command line options for opening one or more documents on startup - size_t openDocumentCount = m_commandLine.GetNumMiscValues(); + size_t openDocumentCount = commandLine.GetNumMiscValues(); for (size_t openDocumentIndex = 0; openDocumentIndex < openDocumentCount; ++openDocumentIndex) { - const AZStd::string openDocumentPath = m_commandLine.GetMiscValue(openDocumentIndex); - ShaderManagementConsoleDocumentSystemRequestBus::Broadcast( - &ShaderManagementConsoleDocumentSystemRequestBus::Events::OpenDocument, openDocumentPath); + const AZStd::string openDocumentPath = commandLine.GetMiscValue(openDocumentIndex); + + AZ_Printf(GetBuildTargetName().c_str(), "Opening document: %s", openDocumentPath.c_str()); + ShaderManagementConsoleDocumentSystemRequestBus::Broadcast(&ShaderManagementConsoleDocumentSystemRequestBus::Events::OpenDocument, openDocumentPath); } + + Base::ProcessCommandLine(commandLine); } void ShaderManagementConsoleApplication::StartInternal() @@ -136,4 +132,12 @@ namespace ShaderManagementConsole ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Broadcast( &ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Handler::CreateShaderManagementConsoleWindow); } + + void ShaderManagementConsoleApplication::Stop() + { + ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Broadcast( + &ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Handler::DestroyShaderManagementConsoleWindow); + + Base::Stop(); + } } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 5d3696fee3..d0a2b800b2 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -26,12 +26,13 @@ namespace ShaderManagementConsole using Base = AtomToolsFramework::AtomToolsApplication; ShaderManagementConsoleApplication(int* argc, char*** argv); - virtual ~ShaderManagementConsoleApplication() = default; + virtual ~ShaderManagementConsoleApplication(); ////////////////////////////////////////////////////////////////////////// // AzFramework::Application void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; + void Stop() override; private: ////////////////////////////////////////////////////////////////////////// @@ -44,9 +45,9 @@ namespace ShaderManagementConsole void Destroy() override; ////////////////////////////////////////////////////////////////////////// - void ProcessCommandLine(); + void ProcessCommandLine(const AZ::CommandLine& commandLine) override; void StartInternal() override; AZStd::string GetBuildTargetName() const override; AZStd::vector GetCriticalAssetFilters() const override; - }; + }; } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl index ffd7af2f20..ae707a10a7 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl @@ -520,13 +520,14 @@ namespace AZ { AZStd::size_t sizeBeforeRemove = savedRegions.size(); - auto firstRegionToKeep = AZStd::lower_bound( - savedRegions.begin(), savedRegions.end(), deleteBeforeTick, - [](const TimeRegion& region, AZStd::sys_time_t target) + // Use erase_if over plain upper_bound + erase to avoid repeated shifts. erase requires a shift of all elements to the right + // for each element that is erased, while erase_if squashes all removes into a single shift which significantly improves perf. + AZStd::erase_if( + savedRegions, + [deleteBeforeTick](const TimeRegion& region) { - return region.m_startTick < target; + return region.m_startTick < deleteBeforeTick; }); - savedRegions.erase(savedRegions.begin(), firstRegionToKeep); m_savedRegionCount -= sizeBeforeRemove - savedRegions.size(); } diff --git a/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.azsl b/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.azsl index 85b2dcc509..b5c0ffa068 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.azsl +++ b/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.azsl @@ -10,9 +10,6 @@ #include -// Indicates whether to use pre-multiplied alpha -option bool o_preMultiplyAlpha; - // If true pixels with an alpha value of less than 0.5 are clipped option bool o_alphaTest; @@ -86,9 +83,9 @@ struct PSOutput float4 m_color : SV_Target0; }; -float4 SampleTriangleTexture(int texIndex, float2 uv) +float4 SampleTriangleTexture(uint texIndex, float2 uv) { - if ((InstanceSrg::m_isClamp & (1 << texIndex)) != 0) + if ((InstanceSrg::m_isClamp & (1U << texIndex)) != 0) { return InstanceSrg::m_texture[texIndex].Sample(InstanceSrg::m_clampSampler, uv); } @@ -120,14 +117,6 @@ PSOutput MainPS(VSOutput IN) resColor.xyz = LinearToSRGB(resColor.xyz); } - // Check for flag to premultiply alpha - if (o_preMultiplyAlpha) - { - // premultiply the color by the alpha. This would not be required if we had full access to the separate alpha blend mode - float preMult = resColor.w; - resColor.xyz *= preMult; - } - // If the o_modulate option is not None it means that the verts have two texture indicies. The second texture is used to // mask the first. This is used for gradient masks. if (o_modulate == Modulate::Alpha) diff --git a/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist b/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist index c7eddb10f2..56f71e72f5 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist +++ b/Gems/AtomLyIntegration/AtomBridge/Assets/Shaders/LyShineUI.shadervariantlist @@ -4,7 +4,6 @@ { "StableId": 1, "Options": { - "o_preMultiplyAlpha": "false", "o_alphaTest": "false", "o_srgbWrite": "true", "o_modulate": "Modulate::None" @@ -13,11 +12,26 @@ { "StableId": 2, "Options": { - "o_preMultiplyAlpha": "false", - "o_alphaTest": "true", - "o_srgbWrite": "true", + "o_alphaTest": "false", + "o_srgbWrite": "false", "o_modulate": "Modulate::None" } + }, + { + "StableId": 3, + "Options": { + "o_alphaTest": "true", + "o_srgbWrite": "false", + "o_modulate": "Modulate::None" + } + }, + { + "StableId": 4, + "Options": { + "o_alphaTest": "false", + "o_srgbWrite": "false", + "o_modulate": "Modulate::Alpha" + } } ] } diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp index 08f3d8cf9e..b51e3b0e29 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp @@ -238,7 +238,7 @@ namespace AZ uint32_t AssetCollectionAsyncLoaderTestComponent::GetCountOfPendingAssets() const { - return m_pendingAssets.size(); + return static_cast(m_pendingAssets.size()); } bool AssetCollectionAsyncLoaderTestComponent::ValidateAssetWasLoaded(const AZStd::string& assetPath) const diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp index fe6f733abc..fd59b7aed4 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp @@ -332,7 +332,7 @@ void AZ::FFont::DrawStringUInternal( m_vertexBuffer[vertexOffset + 3].color.dcolor = packedColor; m_vertexBuffer[vertexOffset + 3].st = tc3; - uint16_t startingIndex = vertexOffset - startingVertexCount; + uint16_t startingIndex = static_cast(vertexOffset - startingVertexCount); m_indexBuffer[indexOffset + 0] = startingIndex + 0; m_indexBuffer[indexOffset + 1] = startingIndex + 1; m_indexBuffer[indexOffset + 2] = startingIndex + 2; @@ -704,12 +704,12 @@ uint32_t AZ::FFont::WriteTextQuadsToBuffers(SVF_P2F_C4B_T2F_F4B* verts, uint16_t vertexData[vertexOffset + 3].texIndex2 = 0; vertexData[vertexOffset + 3].pad = 0; - indexData[indexOffset + 0] = vertexOffset + 0; - indexData[indexOffset + 1] = vertexOffset + 1; - indexData[indexOffset + 2] = vertexOffset + 2; - indexData[indexOffset + 3] = vertexOffset + 2; - indexData[indexOffset + 4] = vertexOffset + 3; - indexData[indexOffset + 5] = vertexOffset + 0; + indexData[indexOffset + 0] = static_cast(vertexOffset + 0); + indexData[indexOffset + 1] = static_cast(vertexOffset + 1); + indexData[indexOffset + 2] = static_cast(vertexOffset + 2); + indexData[indexOffset + 3] = static_cast(vertexOffset + 2); + indexData[indexOffset + 4] = static_cast(vertexOffset + 3); + indexData[indexOffset + 5] = static_cast(vertexOffset + 0); vertexOffset += 4; indexOffset += 6; @@ -1343,7 +1343,7 @@ unsigned int AZ::FFont::GetEffectId(const char* effectName) const { if (!strcmp(m_effects[i].m_name.c_str(), effectName)) { - return i; + return static_cast(i); } } } @@ -1353,7 +1353,7 @@ unsigned int AZ::FFont::GetEffectId(const char* effectName) const unsigned int AZ::FFont::GetNumEffects() const { - return m_effects.size(); + return static_cast(m_effects.size()); } const char* AZ::FFont::GetEffectName(unsigned int effectId) const diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp index 62d673f9eb..6ea6a8e85f 100644 --- a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp +++ b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/Code/Source/AtomViewportDisplayIconsSystemComponent.cpp @@ -207,7 +207,7 @@ namespace AZ::Render createVertex(-0.5f, 0.5f, 0.f, 1.f) }; AZStd::array indices = {0, 1, 2, 0, 2, 3}; - dynamicDraw->DrawIndexed(&vertices, vertices.size(), &indices, indices.size(), RHI::IndexFormat::Uint16, drawSrg); + dynamicDraw->DrawIndexed(&vertices, static_cast(vertices.size()), &indices, static_cast(indices.size()), RHI::IndexFormat::Uint16, drawSrg); } QString AtomViewportDisplayIconsSystemComponent::FindAssetPath(const QString& path) const diff --git a/Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Groudplane/groundplane_521x521m.fbx b/Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Groudplane/groundplane_512x512m.fbx similarity index 100% rename from Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Groudplane/groundplane_521x521m.fbx rename to Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Groudplane/groundplane_512x512m.fbx diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/PolygonLightDelegate.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/PolygonLightDelegate.cpp index a001b5a453..7715dfde4f 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/PolygonLightDelegate.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/PolygonLightDelegate.cpp @@ -54,7 +54,7 @@ namespace AZ { transformedVertices.push_back(transform.TransformPoint(Vector3(vertex.GetX(), vertex.GetY(), 0.0f))); } - GetFeatureProcessor()->SetPolygonPoints(GetLightHandle(), transformedVertices.data(), transformedVertices.size(), GetTransform().GetBasisZ()); + GetFeatureProcessor()->SetPolygonPoints(GetLightHandle(), transformedVertices.data(), static_cast(transformedVertices.size()), GetTransform().GetBasisZ()); } } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp index fc62690cc4..4b3322c442 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/EditorMeshComponent.cpp @@ -213,7 +213,7 @@ namespace AZ { EditorMeshStatsForLod stats; const auto& meshes = lodAsset->GetMeshes(); - stats.m_meshCount = meshes.size(); + stats.m_meshCount = static_cast(meshes.size()); for (const auto& mesh : meshes) { stats.m_vertCount += mesh.GetVertexCount(); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp index cf548e965a..68276a7320 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Mesh/MeshComponentController.cpp @@ -58,7 +58,7 @@ namespace AZ { if (m_modelAsset.IsReady()) { - lodCount = m_modelAsset->GetLodCount(); + lodCount = static_cast(m_modelAsset->GetLodCount()); } else { @@ -66,7 +66,7 @@ namespace AZ Data::Instance model = Data::InstanceDatabase::Instance().Find(Data::InstanceId::CreateFromAssetId(m_modelAsset.GetId())); if (model) { - lodCount = model->GetLodCount(); + lodCount = static_cast(model->GetLodCount()); } } } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp index feabdb9510..608635b395 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp @@ -211,7 +211,7 @@ namespace AZ for (uint32_t vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) { const uint32_t originalVertex = sourceOriginalVertex[vertexIndex + vertexStart]; - const uint32_t influenceCount = AZStd::GetMin(MaxSupportedSkinInfluences, sourceSkinningInfo->GetNumInfluences(originalVertex)); + const uint32_t influenceCount = AZStd::GetMin(MaxSupportedSkinInfluences, static_cast(sourceSkinningInfo->GetNumInfluences(originalVertex))); uint32_t influenceIndex = 0; float weightError = 1.0f; @@ -378,7 +378,7 @@ namespace AZ size_t skinnedMeshSubmeshIndex = 0; for (size_t jointIndex = 0; jointIndex < numJoints; ++jointIndex) { - const EMotionFX::Mesh* mesh = actor->GetMesh(lodIndex, jointIndex); + const EMotionFX::Mesh* mesh = actor->GetMesh(static_cast(lodIndex), static_cast(jointIndex)); if (!mesh || mesh->GetIsCollisionMesh()) { continue; @@ -404,7 +404,7 @@ namespace AZ for (size_t subMeshIndex = 0; subMeshIndex < numSubMeshes; ++subMeshIndex) { - const EMotionFX::SubMesh* subMesh = mesh->GetSubMesh(subMeshIndex); + const EMotionFX::SubMesh* subMesh = mesh->GetSubMesh(static_cast(subMeshIndex)); const size_t vertexCount = subMesh->GetNumVertices(); // Skip empty sub-meshes and sub-meshes that would put the total vertex count beyond the supported range @@ -508,7 +508,7 @@ namespace AZ if (morphBufferAssetView) { - ProcessMorphsForLod(actor, morphBufferAssetView->GetBufferAsset(), lodIndex, fullFileName, skinnedMeshLod); + ProcessMorphsForLod(actor, morphBufferAssetView->GetBufferAsset(), static_cast(lodIndex), fullFileName, skinnedMeshLod); } // Set colors after morphs are set, so that we know whether or not they are dynamic (if they exist) @@ -593,7 +593,7 @@ namespace AZ descriptor.m_bufferData = boneTransforms.data(); descriptor.m_bufferName = AZStd::string::format("BoneTransformBuffer_%s", actorInstance->GetActor()->GetName()); descriptor.m_byteCount = boneTransforms.size() * sizeof(float); - descriptor.m_elementSize = floatsPerBone * sizeof(float); + descriptor.m_elementSize = static_cast(floatsPerBone * sizeof(float)); descriptor.m_poolType = RPI::CommonBufferPoolType::ReadOnly; return RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(descriptor); } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp index 2711ce2f76..0cb8cf5ccd 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp @@ -163,7 +163,7 @@ namespace AZ const AZ::Color skeletonColor(0.604f, 0.804f, 0.196f, 1.0f); RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments lineArgs; lineArgs.m_verts = m_auxVertices.data(); - lineArgs.m_vertCount = m_auxVertices.size(); + lineArgs.m_vertCount = static_cast(m_auxVertices.size()); lineArgs.m_colors = &skeletonColor; lineArgs.m_colorCount = 1; lineArgs.m_depthTest = RPI::AuxGeomDraw::DepthTest::Off; @@ -204,9 +204,9 @@ namespace AZ RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments lineArgs; lineArgs.m_verts = m_auxVertices.data(); - lineArgs.m_vertCount = m_auxVertices.size(); + lineArgs.m_vertCount = static_cast(m_auxVertices.size()); lineArgs.m_colors = m_auxColors.data(); - lineArgs.m_colorCount = m_auxColors.size(); + lineArgs.m_colorCount = static_cast(m_auxColors.size()); lineArgs.m_depthTest = RPI::AuxGeomDraw::DepthTest::Off; auxGeom->DrawLines(lineArgs); } @@ -812,7 +812,7 @@ namespace AZ for (size_t lodIndex = 0; lodIndex < m_skinnedMeshInputBuffers->GetLodCount(); ++lodIndex) { - EMotionFX::MorphSetup* morphSetup = actor->GetMorphSetup(lodIndex); + EMotionFX::MorphSetup* morphSetup = actor->GetMorphSetup(static_cast(lodIndex)); if (morphSetup) { const AZStd::vector& metaDatas = actor->GetMorphTargetMetaAsset()->GetMorphTargets(); @@ -862,7 +862,7 @@ namespace AZ // Set the weights for any active masks for (size_t i = 0; i < m_wrinkleMaskWeights.size(); ++i) { - wrinkleMaskObjectSrg->SetConstant(wrinkleMaskWeightsIndex, m_wrinkleMaskWeights[i], i); + wrinkleMaskObjectSrg->SetConstant(wrinkleMaskWeightsIndex, m_wrinkleMaskWeights[i], static_cast(i)); } AZ_Error("AtomActorInstance", m_wrinkleMaskWeights.size() <= s_maxActiveWrinkleMasks, "The skinning shader supports no more than %d active morph targets with wrinkle masks.", s_maxActiveWrinkleMasks); } diff --git a/Gems/AtomLyIntegration/ImguiAtom/Code/Source/DebugConsole.cpp b/Gems/AtomLyIntegration/ImguiAtom/Code/Source/DebugConsole.cpp index 73e0a61ad2..e47c8ba071 100644 --- a/Gems/AtomLyIntegration/ImguiAtom/Code/Source/DebugConsole.cpp +++ b/Gems/AtomLyIntegration/ImguiAtom/Code/Source/DebugConsole.cpp @@ -230,7 +230,7 @@ namespace AZ void DebugConsole::BrowseInputHistory(ImGuiInputTextCallbackData* data) { const int previousHistoryIndex = m_currentHistoryIndex; - const int maxHistoryIndex = m_textInputHistory.size() - 1; + const int maxHistoryIndex = static_cast(m_textInputHistory.size() - 1); switch (data->EventKey) { // Browse backwards through the history. diff --git a/Gems/BarrierInput/Code/Source/BarrierInputClient.cpp b/Gems/BarrierInput/Code/Source/BarrierInputClient.cpp index b1ca6cb7d7..495ef88467 100644 --- a/Gems/BarrierInput/Code/Source/BarrierInputClient.cpp +++ b/Gems/BarrierInput/Code/Source/BarrierInputClient.cpp @@ -54,7 +54,7 @@ namespace BarrierInput int ReadU8() { int ret = data[0]; data += 1; return ret; } void Eat(int len) { data += len; } - void InsertString(const char* str) { int len = strlen(str); memcpy(end, str, len); end += len; } + void InsertString(const char* str) { int len = static_cast(strlen(str)); memcpy(end, str, len); end += len; } void InsertU32(int a) { end[0] = a >> 24; end[1] = a >> 16; end[2] = a >> 8; end[3] = a; end += 4; } void InsertU16(int a) { end[0] = a >> 8; end[1] = a; end += 2; } void InsertU8(int a) { end[0] = a; end += 1; } @@ -93,7 +93,7 @@ namespace BarrierInput stream.InsertString("Barrier"); stream.InsertU16(1); stream.InsertU16(4); - stream.InsertU32(pContext->GetClientScreenName().length()); + stream.InsertU32(static_cast(pContext->GetClientScreenName().length())); stream.InsertString(pContext->GetClientScreenName().c_str()); stream.ClosePacket(); return barrierSendFunc(pContext, stream.GetBuffer(), stream.GetLength()); @@ -268,7 +268,7 @@ namespace BarrierInput int i; for (i = 0; i < numPackets; ++i) { - const int len = strlen(s_packets[i].pattern); + const int len = static_cast(strlen(s_packets[i].pattern)); if (packetLength >= len && memcmp(stream.GetData(), s_packets[i].pattern, len) == 0) { bool bDone = false; diff --git a/Gems/Blast/Code/Source/Asset/BlastChunksAsset.cpp b/Gems/Blast/Code/Source/Asset/BlastChunksAsset.cpp new file mode 100644 index 0000000000..1d0ce15241 --- /dev/null +++ b/Gems/Blast/Code/Source/Asset/BlastChunksAsset.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + +namespace Blast +{ + void BlastChunksAsset::SetModelAssetIds(const AZStd::vector& modelAssetIds) + { + m_modelAssetIds = modelAssetIds; + } + + const AZStd::vector& BlastChunksAsset::GetModelAssetIds() const + { + return m_modelAssetIds; + } + + void BlastChunksAsset::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(1) + ->Field("modelAssetIds", &BlastChunksAsset::m_modelAssetIds); + } + } + +} // namespace Blast diff --git a/Gems/Blast/Code/Source/Asset/BlastChunksAsset.h b/Gems/Blast/Code/Source/Asset/BlastChunksAsset.h new file mode 100644 index 0000000000..1f6442d8fd --- /dev/null +++ b/Gems/Blast/Code/Source/Asset/BlastChunksAsset.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include + +namespace Blast +{ + //! The product asset file from a .blast_chunks file product asset file + class BlastChunksAsset final + : public AZ::Data::AssetData + { + public: + AZ_RTTI(BlastChunksAsset, "{993F0B0F-37D9-48C6-9CC2-E27D3F3E343E}", AZ::Data::AssetData); + AZ_CLASS_ALLOCATOR(BlastChunksAsset, AZ::SystemAllocator, 0); + + BlastChunksAsset() = default; + ~BlastChunksAsset() override = default; + + void SetModelAssetIds(const AZStd::vector& modelAssetIds); + const AZStd::vector& GetModelAssetIds() const; + + static void Reflect(AZ::ReflectContext* context); + + private: + AZStd::vector m_modelAssetIds; + }; +} // namespace Blast diff --git a/Gems/Blast/Code/Source/Asset/BlastSliceAsset.cpp b/Gems/Blast/Code/Source/Asset/BlastSliceAsset.cpp deleted file mode 100644 index acb3043c19..0000000000 --- a/Gems/Blast/Code/Source/Asset/BlastSliceAsset.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include - -namespace Blast -{ - void BlastSliceAsset::SetMeshIdList(const AZStd::vector& meshAssetIdList) - { - m_meshAssetIdList = meshAssetIdList; - } - - const AZStd::vector& BlastSliceAsset::GetMeshIdList() const - { - return m_meshAssetIdList; - } - - void BlastSliceAsset::SetMaterialId(const AZ::Data::AssetId& materialAssetId) - { - m_materialAssetId = materialAssetId; - } - - const AZ::Data::AssetId& BlastSliceAsset::GetMaterialId() const - { - return m_materialAssetId; - } - - void BlastSliceAsset::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("meshAssetIdList", &BlastSliceAsset::m_meshAssetIdList) - ->Field("materialAssetId", &BlastSliceAsset::m_materialAssetId); - } - - if (AZ::BehaviorContext* behavior = azrtti_cast(context)) - { - behavior->Class("BlastSliceAsset") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) - ->Attribute(AZ::Script::Attributes::Module, "blast") - ->Method("SetMeshIdList", &BlastSliceAsset::SetMeshIdList) - ->Method("GetMeshIdList", &BlastSliceAsset::GetMeshIdList) - ->Method("SetMaterialId", &BlastSliceAsset::SetMaterialId) - ->Method("GetMaterialId", &BlastSliceAsset::GetMaterialId) - ->Method( - "GetAssetTypeId", - [](BlastSliceAsset*) - { - return azrtti_typeid(); - }); - } - } - -} // namespace Blast diff --git a/Gems/Blast/Code/Source/Asset/BlastSliceAsset.h b/Gems/Blast/Code/Source/Asset/BlastSliceAsset.h deleted file mode 100644 index cab51791cd..0000000000 --- a/Gems/Blast/Code/Source/Asset/BlastSliceAsset.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include - -namespace Blast -{ - //! The product asset file from a .blast_slice file product asset file - class BlastSliceAsset final : public AZ::Data::AssetData - { - public: - AZ_RTTI(BlastSliceAsset, "{D04AAF07-EB12-4E50-8964-114A9B9C1FD1}", AZ::Data::AssetData); - AZ_CLASS_ALLOCATOR(BlastSliceAsset, AZ::SystemAllocator, 0); - - BlastSliceAsset() = default; - ~BlastSliceAsset() override = default; - - void SetMeshIdList(const AZStd::vector& meshAssetIdList); - const AZStd::vector& GetMeshIdList() const; - - void SetMaterialId(const AZ::Data::AssetId& materialAssetId); - const AZ::Data::AssetId& GetMaterialId() const; - - static void Reflect(AZ::ReflectContext* context); - - private: - AZStd::vector m_meshAssetIdList; - AZ::Data::AssetId m_materialAssetId; - }; -} // namespace Blast diff --git a/Gems/Blast/Code/Source/BlastModule.cpp b/Gems/Blast/Code/Source/BlastModule.cpp index cbb93a86f7..70b3285d1d 100644 --- a/Gems/Blast/Code/Source/BlastModule.cpp +++ b/Gems/Blast/Code/Source/BlastModule.cpp @@ -16,7 +16,6 @@ #ifdef BLAST_EDITOR #include #include -#include #include #endif @@ -40,8 +39,7 @@ namespace Blast #ifdef BLAST_EDITOR EditorSystemComponent::CreateDescriptor(), EditorBlastFamilyComponent::CreateDescriptor(), - EditorBlastMeshDataComponent::CreateDescriptor(), - BlastSliceAssetStorageComponent::CreateDescriptor(), + EditorBlastMeshDataComponent::CreateDescriptor() #endif }); } diff --git a/Gems/Blast/Code/Source/Editor/EditorBlastChunksAssetHandler.cpp b/Gems/Blast/Code/Source/Editor/EditorBlastChunksAssetHandler.cpp new file mode 100644 index 0000000000..d3ae8222b1 --- /dev/null +++ b/Gems/Blast/Code/Source/Editor/EditorBlastChunksAssetHandler.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Blast +{ + // + // EditorBlastChunksAssetHandler + // + + EditorBlastChunksAssetHandler::~EditorBlastChunksAssetHandler() + { + Unregister(); + } + + AZ::Data::AssetPtr EditorBlastChunksAssetHandler::CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) + { + if (type != GetAssetType()) + { + AZ_Error("Blast", type == GetAssetType(), "Invalid asset type! We only handle 'BlastChunksAsset'"); + return {}; + } + + if (!CanHandleAsset(id)) + { + return nullptr; + } + + return aznew BlastChunksAsset; + } + + AZ::Data::AssetHandler::LoadResult EditorBlastChunksAssetHandler::LoadAssetData( + const AZ::Data::Asset& asset, + AZStd::shared_ptr stream, + [[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB) + { + BlastChunksAsset* blastChunksAsset = asset.GetAs(); + AZ_Error("blast", blastChunksAsset, + "This should be a BlastChunksAsset type, as this is the only type we process!"); + if (!blastChunksAsset) + { + return LoadResult::Error; + } + + // get all products from the source scene asset + bool found = false; + AZStd::vector productsAssetInfo; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult( + found, + &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetsProducedBySourceUUID, + asset.Get()->GetId().m_guid, + productsAssetInfo); + + if (!found) + { + AZ_Error("blast", + found, + "Could not find asset models produced by source asset ID %s, verify the output product model assets.", + asset.Get()->GetId().m_guid.ToString().c_str()); + return LoadResult::Error; + } + + // find all model assets + AZStd::vector modelAssetIdList; + for (const AZ::Data::AssetInfo& assetInfo : productsAssetInfo) + { + if (azrtti_typeid() == assetInfo.m_assetType) + { + modelAssetIdList.push_back(assetInfo.m_assetId); + } + } + blastChunksAsset->SetModelAssetIds(modelAssetIdList); + + return LoadResult::LoadComplete; + } + + void EditorBlastChunksAssetHandler::DestroyAsset(AZ::Data::AssetPtr ptr) + { + delete ptr; + } + + void EditorBlastChunksAssetHandler::GetHandledAssetTypes(AZStd::vector& assetTypes) + { + assetTypes.push_back(azrtti_typeid()); + } + + void EditorBlastChunksAssetHandler::Register() + { + AZ_Assert(AZ::Data::AssetManager::IsReady(), "Asset manager isn't ready!"); + AZ::Data::AssetManager::Instance().RegisterHandler(this, azrtti_typeid()); + AZ::AssetTypeInfoBus::Handler::BusConnect(azrtti_typeid()); + } + + void EditorBlastChunksAssetHandler::Unregister() + { + AZ::AssetTypeInfoBus::Handler::BusDisconnect(azrtti_typeid()); + if (AZ::Data::AssetManager::IsReady()) + { + AZ::Data::AssetManager::Instance().UnregisterHandler(this); + } + } + + AZ::Data::AssetType EditorBlastChunksAssetHandler::GetAssetType() const + { + return azrtti_typeid(); + } + + const char* EditorBlastChunksAssetHandler::GetAssetTypeDisplayName() const + { + return "Blast Chunks Asset"; + } + + const char* EditorBlastChunksAssetHandler::GetGroup() const + { + return "Blast"; + } + + const char* EditorBlastChunksAssetHandler::GetBrowserIcon() const + { + return "Icons/Components/Box.png"; + } + + void EditorBlastChunksAssetHandler::GetAssetTypeExtensions(AZStd::vector& extensions) + { + extensions.push_back("blast_chunks"); + } + +} // namespace Blast diff --git a/Gems/Blast/Code/Source/Editor/EditorBlastChunksAssetHandler.h b/Gems/Blast/Code/Source/Editor/EditorBlastChunksAssetHandler.h new file mode 100644 index 0000000000..baeb26a1ff --- /dev/null +++ b/Gems/Blast/Code/Source/Editor/EditorBlastChunksAssetHandler.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Blast +{ + class EditorBlastChunksAssetHandler final + : public AZ::Data::AssetHandler + , public AZ::AssetTypeInfoBus::Handler + { + public: + AZ_CLASS_ALLOCATOR(EditorBlastChunksAssetHandler, AZ::SystemAllocator, 0); + + ~EditorBlastChunksAssetHandler() override; + + // AZ::Data::AssetHandler + AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override; + LoadResult LoadAssetData( + const AZ::Data::Asset& asset, + AZStd::shared_ptr stream, + const AZ::Data::AssetFilterCB& assetLoadFilterCB) override; + void DestroyAsset(AZ::Data::AssetPtr ptr) override; + void GetHandledAssetTypes(AZStd::vector& assetTypes) override; + + // AZ::AssetTypeInfoBus::Handler + AZ::Data::AssetType GetAssetType() const override; + const char* GetAssetTypeDisplayName() const override; + const char* GetGroup() const override; + const char* GetBrowserIcon() const override; + void GetAssetTypeExtensions(AZStd::vector& extensions) override; + + void Register(); + void Unregister(); + }; +} // namespace Blast diff --git a/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp b/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp index 3c29d1498e..27e57a569e 100644 --- a/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp +++ b/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.cpp @@ -45,10 +45,10 @@ namespace Blast if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() - ->Version(4) + ->Version(5) ->Field("Show Mesh Assets", &EditorBlastMeshDataComponent::m_showMeshAssets) ->Field("Mesh Assets", &EditorBlastMeshDataComponent::m_meshAssets) - ->Field("Blast Slice", &EditorBlastMeshDataComponent::m_blastSliceAsset); + ->Field("Blast Chunks", &EditorBlastMeshDataComponent::m_blastChunksAsset); if (AZ::EditContext* ec = serialize->GetEditContext()) { @@ -77,9 +77,9 @@ namespace Blast ->Attribute(AZ::Edit::Attributes::AutoExpand, false) ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorBlastMeshDataComponent::OnMeshAssetsChanged) ->DataElement( - AZ::Edit::UIHandlers::Default, &EditorBlastMeshDataComponent::m_blastSliceAsset, "Blast Slice", - "Slice override to fill out meshes and material") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorBlastMeshDataComponent::OnSliceAssetChanged); + AZ::Edit::UIHandlers::Default, &EditorBlastMeshDataComponent::m_blastChunksAsset, "Blast Chunks", + "Manifest override to fill out meshes and material") + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorBlastMeshDataComponent::OnBlastChunksAssetChanged); } } } @@ -107,23 +107,27 @@ namespace Blast UnregisterModel(); } - void EditorBlastMeshDataComponent::OnSliceAssetChanged() + void EditorBlastMeshDataComponent::OnBlastChunksAssetChanged() { - if (!m_blastSliceAsset.GetId().IsValid()) + if (!m_blastChunksAsset.GetId().IsValid()) { return; } using namespace AZ::Data; + const AssetId blastAssetId = m_blastChunksAsset.GetId(); + m_blastChunksAsset = AssetManager::Instance().GetAsset(blastAssetId, AssetLoadBehavior::QueueLoad); + m_blastChunksAsset.BlockUntilLoadComplete(); - const AssetId blastAssetId = m_blastSliceAsset.GetId(); - m_blastSliceAsset = - AssetManager::Instance().GetAsset(blastAssetId, AssetLoadBehavior::QueueLoad); - m_blastSliceAsset.BlockUntilLoadComplete(); + if (!m_blastChunksAsset.Get() || m_blastChunksAsset.Get()->GetModelAssetIds().empty()) + { + AZ_Warning("blast", false, "Blast Chunk Asset does not contain any models.") + return; + } // load up the new mesh list m_meshAssets.clear(); - for (const auto& meshId : m_blastSliceAsset.Get()->GetMeshIdList()) + for (const auto& meshId : m_blastChunksAsset.Get()->GetModelAssetIds()) { auto meshAsset = AssetManager::Instance().GetAsset(meshId, AssetLoadBehavior::QueueLoad); if (meshAsset) @@ -135,8 +139,8 @@ namespace Blast UnregisterModel(); RegisterModel(); - AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( - &AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree); + using namespace AzToolsFramework; + ToolsApplicationEvents::Bus::Broadcast(&ToolsApplicationEvents::InvalidatePropertyDisplay, Refresh_EntireTree); } void EditorBlastMeshDataComponent::OnMeshAssetsChanged() @@ -205,9 +209,9 @@ namespace Blast gameEntity->CreateComponent(m_meshAssets); } - const AZ::Data::Asset& EditorBlastMeshDataComponent::GetBlastSliceAsset() const + const AZ::Data::Asset& EditorBlastMeshDataComponent::GetBlastChunksAsset() const { - return m_blastSliceAsset; + return m_blastChunksAsset; } const AZStd::vector>& EditorBlastMeshDataComponent::GetMeshAssets() const diff --git a/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.h b/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.h index 81818d3bf7..aed5155be7 100644 --- a/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.h +++ b/Gems/Blast/Code/Source/Editor/EditorBlastMeshDataComponent.h @@ -7,7 +7,7 @@ */ #pragma once -#include +#include #include #include #include @@ -43,14 +43,14 @@ namespace Blast // EditorComponentBase void BuildGameEntity(AZ::Entity* gameEntity) override; - const AZ::Data::Asset& GetBlastSliceAsset() const; + const AZ::Data::Asset& GetBlastChunksAsset() const; const AZStd::vector>& GetMeshAssets() const; void OnMaterialsUpdated(const AZ::Render::MaterialAssignmentMap& materials) override; void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; private: - void OnSliceAssetChanged(); + void OnBlastChunksAssetChanged(); void OnMeshAssetsChanged(); AZ::Crc32 GetMeshAssetsVisibility() const; void OnMeshAssetsVisibilityChanged(); @@ -62,7 +62,7 @@ namespace Blast ////////////////////////////////////////////////////////////////////////// // Reflected data bool m_showMeshAssets = false; - AZ::Data::Asset m_blastSliceAsset; + AZ::Data::Asset m_blastChunksAsset; AZStd::vector> m_meshAssets; ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Blast/Code/Source/Editor/EditorBlastSliceAssetHandler.cpp b/Gems/Blast/Code/Source/Editor/EditorBlastSliceAssetHandler.cpp deleted file mode 100644 index 52df273254..0000000000 --- a/Gems/Blast/Code/Source/Editor/EditorBlastSliceAssetHandler.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace Blast -{ - // BlastSliceAssetStorageComponent - - void BlastSliceAssetStorageComponent::Reflect(AZ::ReflectContext* context) - { - using namespace AZ::Edit; - - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(2) - ->Field("Mesh Data", &BlastSliceAssetStorageComponent::m_meshAssetIdList) - ->Field("Mesh Path List", &BlastSliceAssetStorageComponent::m_meshAssetPathList); - - if (AZ::EditContext* ec = serialize->GetEditContext()) - { - ec->Class( - "Blast Slice Storage Component", "Used process blast slice data") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Physics") - ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Box.png") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Box.png") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::AddableByUser, false) - ->DataElement( - AZ::Edit::UIHandlers::Default, &BlastSliceAssetStorageComponent::m_meshAssetIdList, "Mesh Data", - "Slice data to fill out the mesh list") - ->DataElement( - AZ::Edit::UIHandlers::Default, &BlastSliceAssetStorageComponent::m_meshAssetPathList, - "Mesh Paths", "The mesh path list"); - } - } - - if (AZ::BehaviorContext* behavior = azrtti_cast(context)) - { - behavior->Class("BlastSliceAssetStorageComponent") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) - ->Attribute(AZ::Script::Attributes::Module, "blast") - ->Method("GenerateAssetInfo", &BlastSliceAssetStorageComponent::GenerateAssetInfo) - ->Method("WriteMaterialFile", &BlastSliceAssetStorageComponent::WriteMaterialFile); - } - } - - bool BlastSliceAssetStorageComponent::GenerateAssetInfo( - const AZStd::vector& chunkNames, AZStd::string_view blastFilename, - AZStd::string_view assetinfoFilename) - { - AZ::SerializeContext* serializeContext = nullptr; - AZ::ComponentApplicationBus::BroadcastResult( - serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext); - if (serializeContext == nullptr) - { - return false; - } - using namespace AZ::SceneAPI::Containers; - using namespace AZ::SceneAPI::SceneData; - - AZStd::string filename; - AZ::StringFunc::Path::Split(blastFilename.data(), nullptr, nullptr, &filename, nullptr); - - AZStd::any sceneManifestPointer(serializeContext->CreateAny(azrtti_typeid())); - SceneManifest* sceneManifest = AZStd::any_cast(&sceneManifestPointer); - - AZStd::vector meshGroupData; - meshGroupData.reserve(chunkNames.size()); - - AZStd::vector materialRuleData; - materialRuleData.reserve(chunkNames.size()); - - for (const AZStd::string& chunkName : chunkNames) - { - meshGroupData.emplace_back(serializeContext->CreateAny(azrtti_typeid())); - AZStd::any& meshGroupPointer = meshGroupData.back(); - MeshGroup* meshGroup = AZStd::any_cast(&meshGroupPointer); - - // make selection list - meshGroup->GetSceneNodeSelectionList().RemoveSelectedNode("RootNode"); - for (const AZStd::string& node : chunkNames) - { - meshGroup->GetSceneNodeSelectionList().RemoveSelectedNode( - AZStd::string::format("RootNode.%s", node.c_str())); - } - meshGroup->GetSceneNodeSelectionList().AddSelectedNode( - AZStd::string::format("RootNode.%s", chunkName.c_str())); - - // create a default material for the mesh group - materialRuleData.emplace_back(serializeContext->CreateAny(azrtti_typeid())); - AZStd::any& materialRulePointer = materialRuleData.back(); - MaterialRule* materialRule = AZStd::any_cast(&materialRulePointer); - - // override the deleter since the AZStd::any will clean up later on - AZStd::shared_ptr materialRuleEntry = AZStd::shared_ptr( - materialRule, - [](auto) - { - }); - meshGroup->GetRuleContainer().AddRule(materialRuleEntry); - - // construct the asset name for the chunk's mesh group - AZStd::string meshGroupName(filename); - meshGroupName.append("-"); - meshGroupName.append(chunkName); - // TODO: Uncomment lines below as part of SPEC-3542 - // meshGroup->OverrideId(AZ::Uuid::CreateName(meshGroupName.c_str())); - // meshGroup->SetName(AZStd::move(meshGroupName)); - - // override the deleter since the AZStd::any will clean up later on - AZStd::shared_ptr meshGroupEntry = AZStd::shared_ptr( - meshGroup, - [](auto) - { - }); - sceneManifest->AddEntry(AZStd::move(meshGroupEntry)); - } - - return sceneManifest->SaveToFile(assetinfoFilename.data()); - } - - bool BlastSliceAssetStorageComponent::WriteMaterialFile( - AZStd::string_view materialGroupName, const AZStd::vector& materialNames, - AZStd::string_view materialFilename) - { - AZ::GFxFramework::MaterialGroup group; - for (const auto& texture : materialNames) - { - auto mat = AZStd::make_shared(); - mat->SetName(texture); - mat->SetTexture(AZ::GFxFramework::TextureMapType::Diffuse, "EngineAssets/Textures/white.dds"); - group.AddMaterial(mat); - } - group.SetMtlName(materialGroupName); - return group.WriteMtlFile(materialFilename.data()); - } - - // - // EditorBlastSliceAssetHandler - // - - EditorBlastSliceAssetHandler::~EditorBlastSliceAssetHandler() - { - Unregister(); - } - - AZ::Data::AssetPtr EditorBlastSliceAssetHandler::CreateAsset( - const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) - { - if (type != GetAssetType()) - { - AZ_Error("Blast", type == GetAssetType(), "Invalid asset type! We only handle 'BlastAsset'"); - return {}; - } - - if (!CanHandleAsset(id)) - { - return nullptr; - } - - return aznew BlastSliceAsset; - } - - AZ::Data::AssetHandler::LoadResult EditorBlastSliceAssetHandler::LoadAssetData( - const AZ::Data::Asset& asset, AZStd::shared_ptr stream, - const AZ::Data::AssetFilterCB& assetLoadFilterCB) - { - BlastSliceAsset* blastSliceAssetData = asset.GetAs(); - AZ_Error( - "blast", blastSliceAssetData, - "This should be a BlastSliceAsset type, as this is the only type we process!"); - AZ::SerializeContext* serializeContext = nullptr; - AZ::ComponentApplicationBus::BroadcastResult( - serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext); - if (blastSliceAssetData && serializeContext) - { - AZ::ObjectStream::FilterDescriptor filter(assetLoadFilterCB); - AZStd::unique_ptr baseEntity( - AZ::Utils::LoadObjectFromStream(*stream, serializeContext, filter)); - AZ_Error("Blast", baseEntity, "Could not load slice root entity {asset id}"); - if (!baseEntity) - { - return LoadResult::Error; - } - - auto&& sliceComponent = baseEntity->FindComponent(); - AZ_Error("Blast", sliceComponent, "blast_slice entity missing SliceComponent!"); - if (sliceComponent == nullptr) - { - return LoadResult::Error; - } - - AZStd::vector enityList; - sliceComponent->GetEntities(enityList); - for (auto&& entity : enityList) - { - // the base element type to store Blast mesh data is the BlastSliceAssetStorageComponent - auto&& blastSliceAssetStorage = entity->FindComponent(); - if (blastSliceAssetStorage) - { - if (blastSliceAssetStorage->GetMeshData().empty() == false) - { - blastSliceAssetData->SetMeshIdList(blastSliceAssetStorage->GetMeshData()); - return LoadResult::LoadComplete; - } - else if (blastSliceAssetStorage->GetMeshPathList().empty() == false) - { - AZStd::vector meshAssetIdList; - meshAssetIdList.reserve(blastSliceAssetStorage->GetMeshPathList().size()); - - for (auto&& assetPath : blastSliceAssetStorage->GetMeshPathList()) - { - AZ::Data::AssetId meshAssetId; - AZ::Data::AssetCatalogRequestBus::BroadcastResult( - meshAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, - assetPath.c_str(), AZ::Data::s_invalidAssetType, false); - - if (meshAssetId.IsValid()) - { - meshAssetIdList.emplace_back(meshAssetId); - } - } - blastSliceAssetData->SetMeshIdList(meshAssetIdList); - return LoadResult::LoadComplete; - } - } - - // back up logic to load blast data for the EditorBlastMeshDataComponent - auto&& meshDataComponent = entity->FindComponent(); - if (meshDataComponent) - { - auto&& innerBlastSliceAsset = meshDataComponent->GetBlastSliceAsset(); - if (innerBlastSliceAsset.IsReady()) - { - blastSliceAssetData->SetMeshIdList(innerBlastSliceAsset.Get()->GetMeshIdList()); - blastSliceAssetData->SetMaterialId(innerBlastSliceAsset.Get()->GetMaterialId()); - return LoadResult::LoadComplete; - } - else - { - auto&& meshDataList = meshDataComponent->GetMeshAssets(); - AZStd::vector meshAssetIdList; - meshAssetIdList.reserve(meshDataList.size()); - for (auto&& meshData : meshDataList) - { - AZ::RPI::ModelAsset* meshAsset = meshData.Get(); - if (meshAsset) - { - meshAssetIdList.push_back(meshAsset->GetId()); - } - } - blastSliceAssetData->SetMeshIdList(meshAssetIdList); - return LoadResult::LoadComplete; - } - } - } - AZ_Error( - "Blast", false, "blast_slice assetId:%s missing EditorBlastMeshDataComponent!", - asset->GetId().ToString().c_str()); - } - return LoadResult::Error; - } - - void EditorBlastSliceAssetHandler::DestroyAsset(AZ::Data::AssetPtr ptr) - { - delete ptr; - } - - void EditorBlastSliceAssetHandler::GetHandledAssetTypes(AZStd::vector& assetTypes) - { - assetTypes.push_back(azrtti_typeid()); - } - - void EditorBlastSliceAssetHandler::Register() - { - AZ_Assert(AZ::Data::AssetManager::IsReady(), "Asset manager isn't ready!"); - AZ::Data::AssetManager::Instance().RegisterHandler(this, azrtti_typeid()); - AZ::AssetTypeInfoBus::Handler::BusConnect(azrtti_typeid()); - } - - void EditorBlastSliceAssetHandler::Unregister() - { - AZ::AssetTypeInfoBus::Handler::BusDisconnect(azrtti_typeid()); - if (AZ::Data::AssetManager::IsReady()) - { - AZ::Data::AssetManager::Instance().UnregisterHandler(this); - } - } - - AZ::Data::AssetType EditorBlastSliceAssetHandler::GetAssetType() const - { - return azrtti_typeid(); - } - - const char* EditorBlastSliceAssetHandler::GetAssetTypeDisplayName() const - { - return "Blast Slice Asset"; - } - - const char* EditorBlastSliceAssetHandler::GetGroup() const - { - return "Blast"; - } - - const char* EditorBlastSliceAssetHandler::GetBrowserIcon() const - { - return "Icons/Components/Box.png"; - } - - void EditorBlastSliceAssetHandler::GetAssetTypeExtensions(AZStd::vector& extensions) - { - extensions.push_back("blast_slice"); - } - -} // namespace Blast diff --git a/Gems/Blast/Code/Source/Editor/EditorBlastSliceAssetHandler.h b/Gems/Blast/Code/Source/Editor/EditorBlastSliceAssetHandler.h deleted file mode 100644 index f33290f7f8..0000000000 --- a/Gems/Blast/Code/Source/Editor/EditorBlastSliceAssetHandler.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace Blast -{ - //! Used to create store asset references (i.e. ids) to fill out the EditorBlastMeshDataComponent - class BlastSliceAssetStorageComponent final : public AzToolsFramework::Components::EditorComponentBase - { - public: - AZ_COMPONENT( - BlastSliceAssetStorageComponent, "{696C7E62-1EA4-41E2-B4F6-7BD0D30888DC}", - AzToolsFramework::Components::EditorComponentBase); - - ~BlastSliceAssetStorageComponent() override = default; - - static void Reflect(AZ::ReflectContext* context); - - const AZStd::vector& GetMeshData() const - { - return m_meshAssetIdList; - } - - void SetMeshData(const AZStd::vector& meshAssetIdList) - { - m_meshAssetIdList = meshAssetIdList; - } - - const AZStd::vector& GetMeshPathList() const - { - return m_meshAssetPathList; - } - - void SetMeshPathList(const AZStd::vector& meshAssetPathList) - { - m_meshAssetPathList = meshAssetPathList; - } - - private: - // AZ::Component interface implementation - void Activate() override {} - void Deactivate() override {} - - // EditorComponentBase - void BuildGameEntity([[maybe_unused]] AZ::Entity* gameEntity) override {} - - // Script API - bool GenerateAssetInfo( - const AZStd::vector& chunkNames, - AZStd::string_view blastFilename, - AZStd::string_view assetinfoFilename); - - bool WriteMaterialFile( - AZStd::string_view materialGroupName, - const AZStd::vector& materialNames, - AZStd::string_view materialFilename); - - AZStd::vector m_meshAssetIdList; - AZStd::vector m_meshAssetPathList; - }; - - class EditorBlastSliceAssetHandler final - : public AZ::Data::AssetHandler - , public AZ::AssetTypeInfoBus::Handler - { - public: - AZ_CLASS_ALLOCATOR(EditorBlastSliceAssetHandler, AZ::SystemAllocator, 0); - - ~EditorBlastSliceAssetHandler() override; - - // AZ::Data::AssetHandler - AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override; - LoadResult LoadAssetData( - const AZ::Data::Asset& asset, AZStd::shared_ptr stream, - const AZ::Data::AssetFilterCB& assetLoadFilterCB) override; - void DestroyAsset(AZ::Data::AssetPtr ptr) override; - void GetHandledAssetTypes(AZStd::vector& assetTypes) override; - - // AZ::AssetTypeInfoBus::Handler - AZ::Data::AssetType GetAssetType() const override; - const char* GetAssetTypeDisplayName() const override; - const char* GetGroup() const override; - const char* GetBrowserIcon() const override; - void GetAssetTypeExtensions(AZStd::vector& extensions) override; - - void Register(); - void Unregister(); - }; -} // namespace Blast diff --git a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.cpp b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.cpp index d8d703e51f..dc1cb0fc98 100644 --- a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.cpp +++ b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.cpp @@ -6,7 +6,7 @@ * */ -#include +#include #include #include #include @@ -16,7 +16,7 @@ namespace Blast { void EditorSystemComponent::Reflect(AZ::ReflectContext* context) { - BlastSliceAsset::Reflect(context); + BlastChunksAsset::Reflect(context); if (auto serializeContext = azrtti_cast(context)) { @@ -26,14 +26,14 @@ namespace Blast void EditorSystemComponent::Activate() { - m_editorBlastSliceAssetHandler = AZStd::make_unique(); - m_editorBlastSliceAssetHandler->Register(); + m_editorBlastChunksAssetHandler = AZStd::make_unique(); + m_editorBlastChunksAssetHandler->Register(); auto assetCatalog = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); if (assetCatalog) { - assetCatalog->EnableCatalogForAsset(azrtti_typeid()); - assetCatalog->AddExtension("blast_slice"); + assetCatalog->EnableCatalogForAsset(azrtti_typeid()); + assetCatalog->AddExtension("blast_chunks"); } AzToolsFramework::EditorEvents::Bus::Handler::BusConnect(); @@ -46,7 +46,7 @@ namespace Blast void EditorSystemComponent::Deactivate() { AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); - m_editorBlastSliceAssetHandler.reset(); + m_editorBlastChunksAssetHandler.reset(); } // This will be called when the IEditor instance is ready diff --git a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h index 737a7d968d..31daae1a18 100644 --- a/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h +++ b/Gems/Blast/Code/Source/Editor/EditorSystemComponent.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace Blast { @@ -39,7 +39,7 @@ namespace Blast required.push_back(AZ_CRC("BlastService", 0x75beae2d)); } - AZStd::unique_ptr m_editorBlastSliceAssetHandler; + AZStd::unique_ptr m_editorBlastChunksAssetHandler; // AZ::Component void Activate() override; diff --git a/Gems/Blast/Code/Tests/Editor/EditorBlastChunksAssetHandlerTest.cpp b/Gems/Blast/Code/Tests/Editor/EditorBlastChunksAssetHandlerTest.cpp new file mode 100644 index 0000000000..80a0587b1b --- /dev/null +++ b/Gems/Blast/Code/Tests/Editor/EditorBlastChunksAssetHandlerTest.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#include +#include +#include + +#include +#include +#include + +#include + +namespace UnitTest +{ + MockComponentApplication::MockComponentApplication() + { + AZ::ComponentApplicationBus::Handler::BusConnect(); + AZ::Interface::Register(this); + } + + MockComponentApplication::~MockComponentApplication() + { + AZ::Interface::Unregister(this); + AZ::ComponentApplicationBus::Handler::BusDisconnect(); + } + + class MockAssetCatalogRequestBusHandler final + : public AZ::Data::AssetCatalogRequestBus::Handler + { + public: + MockAssetCatalogRequestBusHandler() + { + AZ::Data::AssetCatalogRequestBus::Handler::BusConnect(); + } + + virtual ~MockAssetCatalogRequestBusHandler() + { + AZ::Data::AssetCatalogRequestBus::Handler::BusDisconnect(); + } + + MOCK_METHOD3(GetAssetIdByPath, AZ::Data::AssetId(const char*, const AZ::Data::AssetType&, bool)); + MOCK_METHOD1(GetAssetInfoById, AZ::Data::AssetInfo(const AZ::Data::AssetId&)); + MOCK_METHOD1(AddAssetType, void(const AZ::Data::AssetType&)); + MOCK_METHOD1(AddDeltaCatalog, bool(AZStd::shared_ptr)); + MOCK_METHOD1(AddExtension, void(const char*)); + MOCK_METHOD0(ClearCatalog, void()); + MOCK_METHOD5(CreateBundleManifest, bool(const AZStd::string&, const AZStd::vector&, const AZStd::string&, int, const AZStd::vector&)); + MOCK_METHOD2(CreateDeltaCatalog, bool(const AZStd::vector&, const AZStd::string&)); + MOCK_METHOD0(DisableCatalog, void()); + MOCK_METHOD1(EnableCatalogForAsset, void(const AZ::Data::AssetType&)); + MOCK_METHOD3(EnumerateAssets, void(BeginAssetEnumerationCB, AssetEnumerationCB, EndAssetEnumerationCB)); + MOCK_METHOD1(GenerateAssetIdTEMP, AZ::Data::AssetId(const char*)); + MOCK_METHOD1(GetAllProductDependencies, AZ::Outcome, AZStd::string>(const AZ::Data::AssetId&)); + MOCK_METHOD3(GetAllProductDependenciesFilter, AZ::Outcome, AZStd::string>(const AZ::Data::AssetId&, const AZStd::unordered_set&, const AZStd::vector&)); + MOCK_METHOD1(GetAssetPathById, AZStd::string(const AZ::Data::AssetId&)); + MOCK_METHOD1(GetDirectProductDependencies, AZ::Outcome, AZStd::string>(const AZ::Data::AssetId&)); + MOCK_METHOD1(GetHandledAssetTypes, void(AZStd::vector&)); + MOCK_METHOD0(GetRegisteredAssetPaths, AZStd::vector()); + MOCK_METHOD2(InsertDeltaCatalog, bool(AZStd::shared_ptr, size_t)); + MOCK_METHOD2(InsertDeltaCatalogBefore, bool(AZStd::shared_ptr, AZStd::shared_ptr)); + MOCK_METHOD1(LoadCatalog, bool(const char*)); + MOCK_METHOD2(RegisterAsset, void(const AZ::Data::AssetId&, AZ::Data::AssetInfo&)); + MOCK_METHOD1(RemoveDeltaCatalog, bool(AZStd::shared_ptr)); + MOCK_METHOD1(SaveCatalog, bool(const char*)); + MOCK_METHOD0(StartMonitoringAssets, void()); + MOCK_METHOD0(StopMonitoringAssets, void()); + MOCK_METHOD1(UnregisterAsset, void(const AZ::Data::AssetId&)); + }; + + class MockAssetManager + : public AZ::Data::AssetManager + { + public: + MockAssetManager(const AZ::Data::AssetManager::Descriptor& desc) : + AssetManager(desc) + { + } + }; + + class EditorBlastChunkAssetHandlerTestFixture + : public AllocatorsTestFixture + { + public: + AZStd::unique_ptr m_mockComponentApplicationBusHandler; + AZStd::unique_ptr m_mockAssetCatalogRequestBusHandler; + AZStd::unique_ptr m_mockAssetManager; + + void SetUp() override final + { + AllocatorsTestFixture::SetUp(); + AZ::AllocatorInstance::Create(); + AZ::AllocatorInstance::Create(); + + m_mockComponentApplicationBusHandler = AZStd::make_unique(); + m_mockAssetCatalogRequestBusHandler = AZStd::make_unique(); + m_mockAssetManager = AZStd::make_unique(AZ::Data::AssetManager::Descriptor{}); + + AZ::Data::AssetManager::SetInstance(m_mockAssetManager.get()); + } + + void TearDown() override final + { + m_mockAssetManager.release(); + AZ::Data::AssetManager::Destroy(); + + m_mockAssetCatalogRequestBusHandler.reset(); + m_mockComponentApplicationBusHandler.reset(); + + AZ::AllocatorInstance::Destroy(); + AZ::AllocatorInstance::Destroy(); + AllocatorsTestFixture::TearDown(); + } + }; + + TEST_F(EditorBlastChunkAssetHandlerTestFixture, EditorBlastChunkAssetHandler_AssetManager_Registered) + { + Blast::EditorBlastChunksAssetHandler handler; + handler.Register(); + EXPECT_NE(nullptr, AZ::Data::AssetManager::Instance().GetHandler(azrtti_typeid())); + handler.Unregister(); + } + + TEST_F(EditorBlastChunkAssetHandlerTestFixture, EditorBlastChunkAssetHandler_AssetTypeInfoBus_Responds) + { + auto assetId = azrtti_typeid(); + + Blast::EditorBlastChunksAssetHandler handler; + handler.Register(); + + AZ::Data::AssetType assetType = AZ::Uuid::CreateNull(); + AZ::AssetTypeInfoBus::EventResult(assetType, assetId, &AZ::AssetTypeInfoBus::Events::GetAssetType); + EXPECT_NE(AZ::Uuid::CreateNull(), assetType); + + const char* displayName = nullptr; + AZ::AssetTypeInfoBus::EventResult(displayName, assetId, &AZ::AssetTypeInfoBus::Events::GetAssetTypeDisplayName); + EXPECT_STREQ("Blast Chunks Asset", displayName); + + const char* group = nullptr; + AZ::AssetTypeInfoBus::EventResult(group, assetId, &AZ::AssetTypeInfoBus::Events::GetGroup); + EXPECT_STREQ("Blast", group); + + const char* icon = nullptr; + AZ::AssetTypeInfoBus::EventResult(icon, assetId, &AZ::AssetTypeInfoBus::Events::GetBrowserIcon); + EXPECT_STREQ("Icons/Components/Box.png", icon); + + AZStd::vector extensions; + AZ::AssetTypeInfoBus::Event(assetId, &AZ::AssetTypeInfoBus::Events::GetAssetTypeExtensions, extensions); + ASSERT_EQ(1, extensions.size()); + ASSERT_EQ("blast_chunks", extensions[0]); + + handler.Unregister(); + } + + TEST_F(EditorBlastChunkAssetHandlerTestFixture, EditorBlastChunkAssetHandler_AssetHandler_Ready) + { + auto assetType = azrtti_typeid(); + auto&& assetManager = AZ::Data::AssetManager::Instance(); + + Blast::EditorBlastChunksAssetHandler handler; + handler.Register(); + EXPECT_EQ(&handler, assetManager.GetHandler(assetType)); + + // create and release an instance of the BlastChunkAsset asset type + { + using ::testing::Return; + using ::testing::_; + + EXPECT_CALL(*m_mockAssetCatalogRequestBusHandler, GetAssetInfoById(_)) + .Times(2) + .WillRepeatedly(Return(AZ::Data::AssetInfo{})); + + auto assetPtr = assetManager.CreateAsset(AZ::Data::AssetId(AZ::Uuid::CreateRandom(), 0)); + EXPECT_NE(nullptr, assetPtr.Get()); + EXPECT_EQ(azrtti_typeid(), assetPtr.GetType()); + } + + handler.Unregister(); + } + +} diff --git a/Gems/Blast/Code/Tests/Editor/EditorBlastSliceAssetHandlerTest.cpp b/Gems/Blast/Code/Tests/Editor/EditorBlastSliceAssetHandlerTest.cpp deleted file mode 100644 index 3df22d081f..0000000000 --- a/Gems/Blast/Code/Tests/Editor/EditorBlastSliceAssetHandlerTest.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include - -#include - -#include -#include -#include - -namespace UnitTest -{ - class MockComponentApplicationBusHandler final - //: public MockComponentApplication - : public AZ::ComponentApplicationBus::Handler - { - public: - MockComponentApplicationBusHandler() - { - AZ::ComponentApplicationBus::Handler::BusConnect(); - } - - virtual ~MockComponentApplicationBusHandler() - { - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - } - - MOCK_METHOD0(Destroy, void()); - MOCK_METHOD1(RegisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); - MOCK_METHOD1(UnregisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); - MOCK_METHOD1(RemoveEntity, bool(AZ::Entity*)); - MOCK_METHOD1(DeleteEntity, bool(const AZ::EntityId&)); - MOCK_METHOD1(GetEntityName, AZStd::string(const AZ::EntityId&)); - MOCK_METHOD1(AddEntity, bool(AZ::Entity*)); - MOCK_METHOD1(FindEntity, AZ::Entity*(const AZ::EntityId&)); - MOCK_METHOD1(EnumerateEntities, void(const ComponentApplicationRequests::EntityCallback&)); - MOCK_METHOD0(GetApplication, AZ::ComponentApplication* ()); - MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ()); - MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ()); - MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ()); - MOCK_METHOD0(GetAppRoot, const char* ()); - MOCK_CONST_METHOD0(GetExecutableFolder, const char* ()); - MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ()); - MOCK_METHOD0(GetTickDeltaTime, float()); - MOCK_METHOD1(Tick, void(float)); - MOCK_METHOD0(TickSystem, void()); - MOCK_CONST_METHOD0(GetRequiredSystemComponents, AZ::ComponentTypeList()); - MOCK_METHOD1(ResolveModulePath, void(AZ::OSString&)); - MOCK_METHOD0(CreateSerializeContext, void()); - MOCK_METHOD0(DestroySerializeContext, void()); - MOCK_METHOD0(CreateBehaviorContext, void()); - MOCK_METHOD0(DestroyBehaviorContext, void()); - MOCK_METHOD0(RegisterCoreComponents, void()); - MOCK_METHOD1(AddSystemComponents, void(AZ::Entity*)); - MOCK_METHOD0(ReflectSerialize, void()); - MOCK_METHOD1(Reflect, void(AZ::ReflectContext*)); - MOCK_CONST_METHOD0(GetBinFolder, const char* ()); - }; - - class MockAssetCatalogRequestBusHandler final - : public AZ::Data::AssetCatalogRequestBus::Handler - { - public: - MockAssetCatalogRequestBusHandler() - { - AZ::Data::AssetCatalogRequestBus::Handler::BusConnect(); - } - - virtual ~MockAssetCatalogRequestBusHandler() - { - AZ::Data::AssetCatalogRequestBus::Handler::BusDisconnect(); - } - - MOCK_METHOD3(GetAssetIdByPath, AZ::Data::AssetId(const char*, const AZ::Data::AssetType&, bool)); - MOCK_METHOD1(GetAssetInfoById, AZ::Data::AssetInfo(const AZ::Data::AssetId&)); - MOCK_METHOD1(AddAssetType, void(const AZ::Data::AssetType&)); - MOCK_METHOD1(AddDeltaCatalog, bool(AZStd::shared_ptr)); - MOCK_METHOD1(AddExtension, void(const char*)); - MOCK_METHOD0(ClearCatalog, void()); - MOCK_METHOD5(CreateBundleManifest, bool(const AZStd::string&, const AZStd::vector&, const AZStd::string&, int, const AZStd::vector&)); - MOCK_METHOD2(CreateDeltaCatalog, bool(const AZStd::vector&, const AZStd::string&)); - MOCK_METHOD0(DisableCatalog, void()); - MOCK_METHOD1(EnableCatalogForAsset, void(const AZ::Data::AssetType&)); - MOCK_METHOD3(EnumerateAssets, void(BeginAssetEnumerationCB, AssetEnumerationCB, EndAssetEnumerationCB)); - MOCK_METHOD1(GenerateAssetIdTEMP, AZ::Data::AssetId(const char*)); - MOCK_METHOD1(GetAllProductDependencies, AZ::Outcome, AZStd::string>(const AZ::Data::AssetId&)); - MOCK_METHOD3(GetAllProductDependenciesFilter, AZ::Outcome, AZStd::string>(const AZ::Data::AssetId&, const AZStd::unordered_set&, const AZStd::vector&)); - MOCK_METHOD1(GetAssetPathById, AZStd::string(const AZ::Data::AssetId&)); - MOCK_METHOD1(GetDirectProductDependencies, AZ::Outcome, AZStd::string>(const AZ::Data::AssetId&)); - MOCK_METHOD1(GetHandledAssetTypes, void(AZStd::vector&)); - MOCK_METHOD0(GetRegisteredAssetPaths, AZStd::vector()); - MOCK_METHOD2(InsertDeltaCatalog, bool(AZStd::shared_ptr, size_t)); - MOCK_METHOD2(InsertDeltaCatalogBefore, bool(AZStd::shared_ptr, AZStd::shared_ptr)); - MOCK_METHOD1(LoadCatalog, bool(const char*)); - MOCK_METHOD2(RegisterAsset, void(const AZ::Data::AssetId&, AZ::Data::AssetInfo&)); - MOCK_METHOD1(RemoveDeltaCatalog, bool(AZStd::shared_ptr)); - MOCK_METHOD1(SaveCatalog, bool(const char*)); - MOCK_METHOD0(StartMonitoringAssets, void()); - MOCK_METHOD0(StopMonitoringAssets, void()); - MOCK_METHOD1(UnregisterAsset, void(const AZ::Data::AssetId&)); - }; - - class MockAssetManager - : public AZ::Data::AssetManager - { - public: - MockAssetManager(const AZ::Data::AssetManager::Descriptor& desc) : - AssetManager(desc) - { - } - }; - - class EditorBlastSliceAssetHandlerTestFixture - : public AllocatorsTestFixture - { - public: - AZStd::unique_ptr m_mockComponentApplicationBusHandler; - //AZStd::unique_ptr m_mockComponentApplicationBusHandler; - AZStd::unique_ptr m_mockAssetCatalogRequestBusHandler; - AZStd::unique_ptr m_mockAssetManager; - AZStd::unique_ptr m_serializeContext; - const AZ::ComponentDescriptor* m_sliceComponentDescriptor = nullptr; - - void SetUpSliceComponents() - { - m_serializeContext = AZStd::make_unique(); - - AZ::Entity::Reflect(m_serializeContext.get()); - Blast::BlastSliceAssetStorageComponent::Reflect(m_serializeContext.get()); - AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); - - m_sliceComponentDescriptor = AZ::SliceComponent::CreateDescriptor(); - m_sliceComponentDescriptor->Reflect(m_serializeContext.get()); - } - - void TearDownSliceComponents() - { - delete m_sliceComponentDescriptor; - m_serializeContext.reset(); - } - - void SetUp() override final - { - AllocatorsTestFixture::SetUp(); - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - m_mockComponentApplicationBusHandler = AZStd::make_unique(); - m_mockAssetCatalogRequestBusHandler = AZStd::make_unique(); - m_mockAssetManager = AZStd::make_unique(AZ::Data::AssetManager::Descriptor{}); - - AZ::Data::AssetManager::SetInstance(m_mockAssetManager.get()); - } - - void TearDown() override final - { - AZ::Data::AssetManager::SetInstance(nullptr); - - m_mockAssetManager.reset(); - m_mockAssetCatalogRequestBusHandler.reset(); - m_mockComponentApplicationBusHandler.reset(); - - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - AllocatorsTestFixture::TearDown(); - } - - void SaveSliceAssetToStream(AZ::Entity* sliceAssetEntity, AZStd::vector& buffer) - { - buffer.clear(); - AZ::IO::ByteContainerStream> stream(&buffer); - AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&stream, *m_serializeContext.get(), AZ::ObjectStream::ST_XML); - objStream->WriteClass(sliceAssetEntity); - EXPECT_TRUE(objStream->Finalize()); - } - }; - - TEST_F(EditorBlastSliceAssetHandlerTestFixture, EditorBlastSliceAssetHandler_AssetManager_Registered) - { - Blast::EditorBlastSliceAssetHandler handler; - handler.Register(); - EXPECT_NE(nullptr, AZ::Data::AssetManager::Instance().GetHandler(azrtti_typeid())); - handler.Unregister(); - } - - TEST_F(EditorBlastSliceAssetHandlerTestFixture, BlastSliceAssetStorageComponent_Behavior_Registered) - { - AZ::BehaviorContext behaviorContext; - Blast::BlastSliceAssetStorageComponent::Reflect(&behaviorContext); - - auto classEntry = behaviorContext.m_classes.find("BlastSliceAssetStorageComponent"); - EXPECT_NE(behaviorContext.m_classes.end(), classEntry); - AZ::BehaviorClass* behaviorClass = classEntry->second; - auto methodEntry = behaviorClass->m_methods.find("GenerateAssetInfo"); - EXPECT_NE(behaviorClass->m_methods.end(), methodEntry); - AZ::BehaviorMethod* behaviorMethod = methodEntry->second; - EXPECT_EQ(4, behaviorMethod->GetNumArguments()); - EXPECT_EQ(behaviorMethod->GetArgument(0)->m_typeId, azrtti_typeid()); - EXPECT_EQ(behaviorMethod->GetArgument(1)->m_typeId, azrtti_typeid>()); - EXPECT_EQ(behaviorMethod->GetArgument(2)->m_typeId, azrtti_typeid()); - EXPECT_EQ(behaviorMethod->GetArgument(3)->m_typeId, azrtti_typeid()); - } - - TEST_F(EditorBlastSliceAssetHandlerTestFixture, BlastSliceAsset_Behavior_Registered) - { - AZ::BehaviorContext behaviorContext; - Blast::BlastSliceAsset::Reflect(&behaviorContext); - - auto classEntry = behaviorContext.m_classes.find("BlastSliceAsset"); - EXPECT_NE(behaviorContext.m_classes.end(), classEntry); - AZ::BehaviorClass* behaviorClass = classEntry->second; - - auto setMeshIdListEntry = behaviorClass->m_methods.find("SetMeshIdList"); - EXPECT_NE(behaviorClass->m_methods.end(), setMeshIdListEntry); - { - AZ::BehaviorMethod* behaviorMethod = setMeshIdListEntry->second; - EXPECT_EQ(2, behaviorMethod->GetNumArguments()); - EXPECT_EQ(behaviorMethod->GetArgument(0)->m_typeId, azrtti_typeid()); - EXPECT_EQ(behaviorMethod->GetArgument(1)->m_typeId, azrtti_typeid>()); - } - - auto getMeshIdListEntry = behaviorClass->m_methods.find("GetMeshIdList"); - EXPECT_NE(behaviorClass->m_methods.end(), getMeshIdListEntry); - { - AZ::BehaviorMethod* behaviorMethod = getMeshIdListEntry->second; - EXPECT_EQ(1, behaviorMethod->GetNumArguments()); - EXPECT_EQ(behaviorMethod->GetArgument(0)->m_typeId, azrtti_typeid()); - EXPECT_EQ(behaviorMethod->GetResult()->m_typeId, azrtti_typeid>()); - } - - auto setMaterialIdEntry = behaviorClass->m_methods.find("SetMaterialId"); - EXPECT_NE(behaviorClass->m_methods.end(), setMaterialIdEntry); - { - AZ::BehaviorMethod* behaviorMethod = setMaterialIdEntry->second; - EXPECT_EQ(2, behaviorMethod->GetNumArguments()); - EXPECT_EQ(behaviorMethod->GetArgument(0)->m_typeId, azrtti_typeid()); - EXPECT_EQ(behaviorMethod->GetArgument(1)->m_typeId, azrtti_typeid()); - } - - auto getMaterialIdEntry = behaviorClass->m_methods.find("GetMaterialId"); - EXPECT_NE(behaviorClass->m_methods.end(), getMaterialIdEntry); - { - AZ::BehaviorMethod* behaviorMethod = getMaterialIdEntry->second; - EXPECT_EQ(1, behaviorMethod->GetNumArguments()); - EXPECT_EQ(behaviorMethod->GetArgument(0)->m_typeId, azrtti_typeid()); - EXPECT_EQ(behaviorMethod->GetResult()->m_typeId, azrtti_typeid()); - } - - auto getAssetTypeIdEntry = behaviorClass->m_methods.find("GetAssetTypeId"); - EXPECT_NE(behaviorClass->m_methods.end(), getAssetTypeIdEntry); - { - AZ::BehaviorMethod* behaviorMethod = getAssetTypeIdEntry->second; - EXPECT_EQ(1, behaviorMethod->GetNumArguments()); - EXPECT_EQ(behaviorMethod->GetArgument(0)->m_typeId, azrtti_typeid()); - EXPECT_EQ(behaviorMethod->GetResult()->m_typeId, azrtti_typeid()); - } - } - - TEST_F(EditorBlastSliceAssetHandlerTestFixture, EditorBlastSliceAssetHandler_AssetTypeInfoBus_Responds) - { - auto assetId = azrtti_typeid(); - - Blast::EditorBlastSliceAssetHandler handler; - handler.Register(); - - AZ::Data::AssetType assetType = AZ::Uuid::CreateNull(); - AZ::AssetTypeInfoBus::EventResult(assetType, assetId, &AZ::AssetTypeInfoBus::Events::GetAssetType); - EXPECT_NE(AZ::Uuid::CreateNull(), assetType); - - const char* displayName = nullptr; - AZ::AssetTypeInfoBus::EventResult(displayName, assetId, &AZ::AssetTypeInfoBus::Events::GetAssetTypeDisplayName); - EXPECT_STREQ("Blast Slice Asset", displayName); - - const char* group = nullptr; - AZ::AssetTypeInfoBus::EventResult(group, assetId, &AZ::AssetTypeInfoBus::Events::GetGroup); - EXPECT_STREQ("Blast", group); - - const char* icon = nullptr; - AZ::AssetTypeInfoBus::EventResult(icon, assetId, &AZ::AssetTypeInfoBus::Events::GetBrowserIcon); - EXPECT_STREQ("Editor/Icons/Components/Box.png", icon); - - AZStd::vector extensions; - AZ::AssetTypeInfoBus::Event(assetId, &AZ::AssetTypeInfoBus::Events::GetAssetTypeExtensions, extensions); - ASSERT_EQ(1, extensions.size()); - ASSERT_EQ("blast_slice", extensions[0]); - - handler.Unregister(); - } - - TEST_F(EditorBlastSliceAssetHandlerTestFixture, EditorBlastSliceAssetHandler_AssetHandler_Ready) - { - auto assetType = azrtti_typeid(); - auto&& assetManager = AZ::Data::AssetManager::Instance(); - - Blast::EditorBlastSliceAssetHandler handler; - handler.Register(); - EXPECT_EQ(&handler, assetManager.GetHandler(assetType)); - - // create and release an instance of the BlastSliceAsset asset type - { - using ::testing::Return; - using ::testing::_; - - EXPECT_CALL(*m_mockAssetCatalogRequestBusHandler, GetAssetInfoById(_)) - .Times(1) - .WillRepeatedly(Return(AZ::Data::AssetInfo{})); - - auto assetPtr = assetManager.CreateAsset(AZ::Data::AssetId(AZ::Uuid::CreateRandom(), 0)); - EXPECT_NE(nullptr, assetPtr.Get()); - EXPECT_EQ(azrtti_typeid(), assetPtr.GetType()); - } - - handler.Unregister(); - } - - TEST_F(EditorBlastSliceAssetHandlerTestFixture, EditorBlastSliceAssetHandler_AssetHandler_LoadsAssetData) - { - SetUpSliceComponents(); - - AZStd::vector meshAssetPathList = { "/foo/path/thing.cgf", "/foo/path/that.cgf" }; - AZ::Entity* storageEntity = aznew AZ::Entity(); - auto* blastStorage = storageEntity->CreateComponent(); - blastStorage->SetMeshPathList(meshAssetPathList); - - AZ::Entity sliceEntity; - AZ::SliceComponent* slice = sliceEntity.CreateComponent(); - slice->AddEntity(storageEntity); - - AZStd::vector buffer; - SaveSliceAssetToStream(&sliceEntity, buffer); - - // Load a slice with the BlastSliceAssetStorageComponent - Blast::EditorBlastSliceAssetHandler handler; - handler.Register(); - { - using ::testing::Return; - using ::testing::_; - - EXPECT_CALL(*m_mockComponentApplicationBusHandler, GetSerializeContext) - .Times(1) - .WillOnce(Return(m_serializeContext.get())); - - EXPECT_CALL(*m_mockComponentApplicationBusHandler, FindEntity(_)) - .Times(1) - .WillOnce(Return(&sliceEntity)); - - EXPECT_CALL(*m_mockAssetCatalogRequestBusHandler, GetAssetIdByPath(_,_,_)) - .Times(2) - .WillRepeatedly(Return(AZ::Data::AssetId(AZ::Uuid::CreateRandom(), 0))); - - EXPECT_CALL(*m_mockAssetCatalogRequestBusHandler, GetAssetInfoById(_)) - .Times(2) - .WillRepeatedly(Return(AZ::Data::AssetInfo{})); - - auto&& assetManager = AZ::Data::AssetManager::Instance(); - auto assetPtr = assetManager.CreateAsset(AZ::Data::AssetId(AZ::Uuid::CreateRandom(), 0)); - - AZ::IO::ByteContainerStream> stream(&buffer); - stream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN); - - const AZ::Data::AssetFilterCB assetLoadFilterCB{}; - bool loaded = handler.LoadAssetData(assetPtr, &stream, assetLoadFilterCB); - EXPECT_TRUE(loaded); - } - handler.Unregister(); - - TearDownSliceComponents(); - } -} diff --git a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h index 6975573a73..0733862e25 100644 --- a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h +++ b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h @@ -68,7 +68,7 @@ namespace Blast uint32_t getChunkCount() const override { - return m_chunks.size(); + return static_cast(m_chunks.size()); } const Nv::Blast::ExtPxChunk* getChunks() const override @@ -78,7 +78,7 @@ namespace Blast uint32_t getSubchunkCount() const override { - return m_subchunks.size(); + return static_cast(m_subchunks.size()); } const Nv::Blast::ExtPxSubchunk* getSubchunks() const override diff --git a/Gems/Blast/Code/blast_editor_files.cmake b/Gems/Blast/Code/blast_editor_files.cmake index 7d417176a2..dc991fb8a9 100644 --- a/Gems/Blast/Code/blast_editor_files.cmake +++ b/Gems/Blast/Code/blast_editor_files.cmake @@ -11,8 +11,8 @@ set(FILES Source/Editor/EditorBlastFamilyComponent.cpp Source/Editor/EditorBlastMeshDataComponent.cpp Source/Editor/EditorBlastMeshDataComponent.h - Source/Editor/EditorBlastSliceAssetHandler.h - Source/Editor/EditorBlastSliceAssetHandler.cpp + Source/Editor/EditorBlastChunksAssetHandler.h + Source/Editor/EditorBlastChunksAssetHandler.cpp Source/Editor/EditorSystemComponent.h Source/Editor/EditorSystemComponent.cpp Editor/ConfigurationWidget.h diff --git a/Gems/Blast/Code/blast_editor_tests_files.cmake b/Gems/Blast/Code/blast_editor_tests_files.cmake index 4e2a63d75c..10d2377ccf 100644 --- a/Gems/Blast/Code/blast_editor_tests_files.cmake +++ b/Gems/Blast/Code/blast_editor_tests_files.cmake @@ -7,6 +7,6 @@ # set(FILES - # Tests/Editor/EditorBlastSliceAssetHandlerTest.cpp + # Disabled until SPEC-7904 is fixed Tests/Editor/EditorBlastChunksAssetHandlerTest.cpp Tests/Editor/EditorTestMain.cpp ) diff --git a/Gems/Blast/Code/blast_files.cmake b/Gems/Blast/Code/blast_files.cmake index 1707ec46a0..530d9cf7ca 100644 --- a/Gems/Blast/Code/blast_files.cmake +++ b/Gems/Blast/Code/blast_files.cmake @@ -26,8 +26,8 @@ set(FILES Source/Asset/BlastAsset.cpp Source/Asset/BlastAssetHandler.h Source/Asset/BlastAssetHandler.cpp - Source/Asset/BlastSliceAsset.h - Source/Asset/BlastSliceAsset.cpp + Source/Asset/BlastChunksAsset.h + Source/Asset/BlastChunksAsset.cpp Source/Components/BlastFamilyComponent.h Source/Components/BlastFamilyComponent.cpp Source/Components/BlastFamilyComponentNotificationBusHandler.h diff --git a/Gems/Blast/Editor/Scripts/asset_builder_blast.py b/Gems/Blast/Editor/Scripts/asset_builder_blast.py deleted file mode 100755 index beb455e335..0000000000 --- a/Gems/Blast/Editor/Scripts/asset_builder_blast.py +++ /dev/null @@ -1,323 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" -def install_user_site(): - import os - import sys - import azlmbr.paths - executableBinFolder = azlmbr.paths.executableFolder - - # the PyAssImp module checks the Windows PATH for the assimp DLL file - if os.name == "nt": - os.environ['PATH'] = os.environ['PATH'] + os.pathsep + executableBinFolder - - # PyAssImp module needs to find the shared library for assimp to load; "posix" handles Mac and Linux - if os.name == "posix": - if 'LD_LIBRARY_PATH' in os.environ: - os.environ['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH'] + os.pathsep + executableBinFolder - else: - os.environ['LD_LIBRARY_PATH'] = executableBinFolder - - # add the user site packages folder to find the pyassimp egg link - import site - for item in sys.path: - if (item.find('site-packages') != -1): - site.addsitedir(item) - -install_user_site() -import pyassimp - -import azlmbr.asset -import azlmbr.asset.builder -import azlmbr.asset.entity -import azlmbr.blast -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.entity -import azlmbr.math -import os -import traceback -import binascii -import sys - -# the UUID must be unique amongst all the asset builders in Python or otherwise -# a collision of builders will happen preventing one from running -busIdString = '{CF5C74D1-9ED4-4851-85B1-9B15090DBEC7}' -busId = azlmbr.math.Uuid_CreateString(busIdString, 0) -handler = None -jobKeyName = 'Blast Chunk Assets' -sceneManifestType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0) -dccMaterialType = azlmbr.math.Uuid_CreateString('{C88469CF-21E7-41EB-96FD-BF14FBB05EDC}', 0) - - -def log_exception_traceback(): - exc_type, exc_value, exc_tb = sys.exc_info() - data = traceback.format_exception(exc_type, exc_value, exc_tb) - print(str(data)) - - -def get_source_fbx_filename(request): - fullPath = os.path.join(request.watchFolder, request.sourceFile) - basePath, filePart = os.path.split(fullPath) - filename = os.path.splitext(filePart)[0] + '.fbx' - filename = os.path.join(basePath, filename) - return filename - - -def raise_error(message): - raise RuntimeError(f'[ERROR]: {message}') - - -def generate_asset_info(chunkNames, request): - import azlmbr.blast - - # write out an object stream with the extension of .fbx.assetinfo.generated - basePath, sceneFile = os.path.split(request.sourceFile) - assetinfoFilename = os.path.splitext(sceneFile)[0] + '.fbx.assetinfo.generated' - assetinfoFilename = os.path.join(basePath, assetinfoFilename) - assetinfoFilename = assetinfoFilename.replace('\\', '/').lower() - outputFilename = os.path.join(request.tempDirPath, assetinfoFilename) - - storage = azlmbr.blast.BlastSliceAssetStorageComponent() - if (storage.GenerateAssetInfo(chunkNames, request.sourceFile, outputFilename)): - product = azlmbr.asset.builder.JobProduct(assetinfoFilename, sceneManifestType, 1) - product.dependenciesHandled = True - return product - raise_error('Failed to generate assetinfo.generated') - - -def export_fbx_manifest(request): - output = [] - fbxFilename = get_source_fbx_filename(request) - sceneAsset = pyassimp.load(fbxFilename) - with sceneAsset as scene: - rootNode = scene.mRootNode.contents - for index in range(0, rootNode.mNumChildren): - child = rootNode.mChildren[index] - childNode = child.contents - childNodeName = bytes.decode(childNode.mName.data) - output.append(str(childNodeName)) - return output - - -def convert_to_asset_paths(fbxFilename, gameRoot, chunkNameList): - realtivePath = fbxFilename[len(gameRoot) + 1:] - realtivePath = os.path.splitext(realtivePath)[0] - output = [] - for chunk in chunkNameList: - assetPath = realtivePath + '-' + chunk + '.cgf' - assetPath = assetPath.replace('\\', '/') - assetPath = assetPath.lower() - output.append(assetPath) - return output - - -# creates a single job to compile for each platform -def create_jobs(request): - fbxSidecarFilename = get_source_fbx_filename(request) - if (os.path.exists(fbxSidecarFilename) is False): - print('[WARN] Sidecar FBX file {} is missing for blast file {}'.format(fbxSidecarFilename, request.sourceFile)) - return azlmbr.asset.builder.CreateJobsResponse() - - # see if the FBX file already has a .assetinfo source asset, if so then do not create a job - if (os.path.exists(f'{fbxSidecarFilename}.assetinfo')): - response = azlmbr.asset.builder.CreateJobsResponse() - response.result = azlmbr.asset.builder.CreateJobsResponse_ResultSuccess - return response - - # create job descriptor for each platform - jobDescriptorList = [] - for platformInfo in request.enabledPlatforms: - jobDesc = azlmbr.asset.builder.JobDescriptor() - jobDesc.jobKey = jobKeyName - jobDesc.priority = 12 # higher than the 'Scene compilation' or 'fbx' - jobDesc.set_platform_identifier(platformInfo.identifier) - jobDescriptorList.append(jobDesc) - - response = azlmbr.asset.builder.CreateJobsResponse() - response.result = azlmbr.asset.builder.CreateJobsResponse_ResultSuccess - response.createJobOutputs = jobDescriptorList - return response - -# handler to create jobs for a source asset - - -def on_create_jobs(args): - try: - request = args[0] - return create_jobs(request) - except: - log_exception_traceback() - return azlmbr.asset.builder.CreateJobsResponse() - - -def generate_blast_slice_asset(chunkNameList, request): - # get list of relative chunk paths - fbxFilename = get_source_fbx_filename(request) - assetPaths = convert_to_asset_paths(fbxFilename, request.watchFolder, chunkNameList) - - outcome = azlmbr.asset.entity.PythonBuilderRequestBus(bus.Broadcast, 'CreateEditorEntity', 'BlastData') - if (outcome.IsSuccess() is False): - raise_error('could not create an editor entity') - blastDataEntityId = outcome.GetValue() - - # create a component for the editor entity - gameType = azlmbr.entity.EntityType().Game - blastMeshDataTypeIdList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Blast Slice Storage Component"], gameType) - componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', blastDataEntityId, blastMeshDataTypeIdList[0]) - if (componentOutcome.IsSuccess() is False): - raise_error('failed to add component (Blast Slice Storage Component) to the blast_slice') - - # build the blast slice using the chunk asset paths - blastMeshComponentId = componentOutcome.GetValue()[0] - outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyTreeEditor', blastMeshComponentId) - if(outcome.IsSuccess() is False): - raise_error(f'failed to create Property Tree Editor for component ({blastMeshComponentId})') - pte = outcome.GetValue() - pte.set_visible_enforcement(True) - pte.set_value('Mesh Paths', assetPaths) - - # write out an object stream with the extension of .blast_slice - basePath, sceneFile = os.path.split(request.sourceFile) - blastFilename = os.path.splitext(sceneFile)[0] + '.blast_slice' - blastFilename = os.path.join(basePath, blastFilename) - blastFilename = blastFilename.replace('\\', '/').lower() - tempFilename = os.path.join(request.tempDirPath, blastFilename) - entityList = [blastDataEntityId] - makeDynamic = False - outcome = azlmbr.asset.entity.PythonBuilderRequestBus(bus.Broadcast, 'WriteSliceFile', tempFilename, entityList, makeDynamic) - if (outcome.IsSuccess() is False): - raise_error(f'WriteSliceFile failed for blast_slice file ({blastFilename})') - - # return a job product - blastSliceAsset = azlmbr.blast.BlastSliceAsset() - subId = binascii.crc32(blastFilename.encode('utf8')) - product = azlmbr.asset.builder.JobProduct(blastFilename, blastSliceAsset.GetAssetTypeId(), subId) - product.dependenciesHandled = True - return product - - -def read_in_string(data, dataLength): - stringData = '' - for idx in range(4, dataLength - 1): - char = bytes.decode(data[idx]) - if (str.isascii(char)): - stringData += char - return stringData - - -def import_material_info(fbxFilename): - _, group_name = os.path.split(fbxFilename) - group_name = os.path.splitext(group_name)[0] - output = {} - output['group_name'] = group_name - output['material_name_list'] = [] - sceneAsset = pyassimp.load(fbxFilename) - with sceneAsset as scene: - for materialIndex in range(0, scene.mNumMaterials): - material = scene.mMaterials[materialIndex].contents - for materialPropertyIdx in range(0, material.mNumProperties): - materialProperty = material.mProperties[materialPropertyIdx].contents - materialPropertyName = bytes.decode(materialProperty.mKey.data) - if (materialPropertyName.endswith('mat.name') and materialProperty.mType is 3): - stringData = read_in_string(materialProperty.mData, materialProperty.mDataLength) - output['material_name_list'].append(stringData) - return output - - -def write_material_file(sourceFile, destFolder): - # preserve source MTL files - rootPath, materialSourceFile = os.path.split(sourceFile) - materialSourceFile = os.path.splitext(materialSourceFile)[0] + '.mtl' - materialSourceFile = os.path.join(rootPath, materialSourceFile) - if (os.path.exists(materialSourceFile)): - print(f'{materialSourceFile} source already exists') - return None - - # auto-generate a DCC material file - info = import_material_info(sourceFile) - materialGroupName = info['group_name'] - materialNames = info['material_name_list'] - materialFilename = materialGroupName + '.dccmtl.generated' - subId = binascii.crc32(materialFilename.encode('utf8')) - materialFilename = os.path.join(destFolder, materialFilename) - storage = azlmbr.blast.BlastSliceAssetStorageComponent() - storage.WriteMaterialFile(materialGroupName, materialNames, materialFilename) - product = azlmbr.asset.builder.JobProduct(materialFilename, dccMaterialType, subId) - product.dependenciesHandled = True - return product - - -def process_fbx_file(request): - # fill out response object - response = azlmbr.asset.builder.ProcessJobResponse() - productOutputs = [] - - # write out DCCMTL file as a product (if needed) - materialProduct = write_material_file(get_source_fbx_filename(request), request.tempDirPath) - if (materialProduct is not None): - productOutputs.append(materialProduct) - - # prepare output folder - basePath, _ = os.path.split(request.sourceFile) - outputPath = os.path.join(request.tempDirPath, basePath) - os.makedirs(outputPath) - - # parse FBX for chunk names - chunkNameList = export_fbx_manifest(request) - - # create assetinfo generated (is product) - productOutputs.append(generate_asset_info(chunkNameList, request)) - - # write out the blast_slice object stream - productOutputs.append(generate_blast_slice_asset(chunkNameList, request)) - - response.outputProducts = productOutputs - response.resultCode = azlmbr.asset.builder.ProcessJobResponse_Success - response.dependenciesHandled = True - return response - - -# using the incoming 'request' find the type of job via 'jobKey' to determine what to do -def on_process_job(args): - try: - request = args[0] - if (request.jobDescription.jobKey.startswith(jobKeyName)): - return process_fbx_file(request) - - return azlmbr.asset.builder.ProcessJobResponse() - except: - log_exception_traceback() - return azlmbr.asset.builder.ProcessJobResponse() - -# register asset builder -def register_asset_builder(): - assetPattern = azlmbr.asset.builder.AssetBuilderPattern() - assetPattern.pattern = '*.blast' - assetPattern.type = azlmbr.asset.builder.AssetBuilderPattern_Wildcard - - builderDescriptor = azlmbr.asset.builder.AssetBuilderDesc() - builderDescriptor.name = "Blast Gem" - builderDescriptor.patterns = [assetPattern] - builderDescriptor.busId = busId - builderDescriptor.version = 5 - - outcome = azlmbr.asset.builder.PythonAssetBuilderRequestBus(azlmbr.bus.Broadcast, 'RegisterAssetBuilder', builderDescriptor) - if outcome.IsSuccess(): - # created the asset builder to hook into the notification bus - handler = azlmbr.asset.builder.PythonBuilderNotificationBusHandler() - handler.connect(busId) - handler.add_callback('OnCreateJobsRequest', on_create_jobs) - handler.add_callback('OnProcessJobRequest', on_process_job) - return handler - - -# create the asset builder handler -try: - handler = register_asset_builder() -except: - handler = None - log_exception_traceback() diff --git a/Gems/Blast/Editor/Scripts/blast_asset_builder.py b/Gems/Blast/Editor/Scripts/blast_asset_builder.py new file mode 100644 index 0000000000..06dc15f5c1 --- /dev/null +++ b/Gems/Blast/Editor/Scripts/blast_asset_builder.py @@ -0,0 +1,290 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + +""" +This a Python Asset Builder script examines each .blast file to see if an +associated .fbx file needs to be processed by exporting all of its chunks +into a scene manifest + +This is also a SceneAPI script that executes from a foo.fbx.assetinfo scene +manifest that writes out asset chunk data for .blast files +""" +import os, traceback, binascii, sys, json, pathlib +import azlmbr.math +import azlmbr.asset +import azlmbr.asset.entity +import azlmbr.asset.builder +import azlmbr.bus + +# +# Python Asset Builder +# +busId = azlmbr.math.Uuid_CreateString('{D4FA20E3-8EF4-44A3-A045-AAE6C1CCAAAB}', 0) +jobKeyName = 'Blast Chunk Assets' + +def log_exception_traceback(): + exc_type, exc_value, exc_tb = sys.exc_info() + data = traceback.format_exception(exc_type, exc_value, exc_tb) + print(str(data)) + +def raise_error(message): + print (f'ERROR - {message}'); + raise RuntimeError(f'[ERROR]: {message}'); + +# creates a single job to compile for each platform +def get_source_fbx_filename(request): + fullPath = os.path.join(request.watchFolder, request.sourceFile) + basePath, filePart = os.path.split(fullPath) + filename = os.path.splitext(filePart)[0] + '.fbx' + filename = os.path.join(basePath, filename) + return filename + +def create_jobs(request): + fbxSidecarFilename = get_source_fbx_filename(request) + if (os.path.exists(fbxSidecarFilename) is False): + print('[WARN] Sidecar FBX file {} is missing for blast file {}'.format(fbxSidecarFilename, request.sourceFile)) + return azlmbr.asset.builder.CreateJobsResponse() + + # see if the FBX file already has a .assetinfo source asset, if so then do not create a job + establishedAssetInfo = f'{fbxSidecarFilename}.assetinfo'; + if (os.path.exists(establishedAssetInfo)): + response = azlmbr.asset.builder.CreateJobsResponse() + response.result = azlmbr.asset.builder.CreateJobsResponse_ResultSuccess + return response + + # create job descriptor for each platform + jobDescriptorList = [] + for platformInfo in request.enabledPlatforms: + sourceFileDependency = azlmbr.asset.builder.SourceFileDependency() + sourceFileDependency.sourceFileDependencyPath = fbxSidecarFilename + + jobDependency = azlmbr.asset.builder.JobDependency() + jobDependency.sourceFile = sourceFileDependency + jobDependency.jobKey = jobKeyName + jobDependency.platformIdentifier = platformInfo.identifier + + jobDesc = azlmbr.asset.builder.JobDescriptor() + jobDesc.jobKey = jobKeyName + jobDesc.set_platform_identifier(platformInfo.identifier) + jobDesc.jobDependencyList = [jobDependency] + jobDescriptorList.append(jobDesc) + + response = azlmbr.asset.builder.CreateJobsResponse() + response.result = azlmbr.asset.builder.CreateJobsResponse_ResultSuccess + response.createJobOutputs = jobDescriptorList + return response + +# to create jobs for a source asset +def on_create_jobs(args): + try: + request = args[0] + return create_jobs(request) + except: + log_exception_traceback() + return azlmbr.asset.builder.CreateJobsResponse() + +def generate_assetinfo_product(request): + # write out a product asset file with the extension of .fbx.assetinfo.generated + basePath, sceneFile = os.path.split(request.sourceFile) + assetinfoFilename = os.path.splitext(sceneFile)[0] + '.fbx.assetinfo.generated' + assetinfoFilename = os.path.join(basePath, assetinfoFilename) + assetinfoFilename = assetinfoFilename.replace('\\', '/').lower() + outputFilename = os.path.join(request.tempDirPath, assetinfoFilename) + + # the only rule in it is to run this file again as a scene processor + currentScript = pathlib.Path(__file__).resolve() + aDict = {"values": [{"$type": "ScriptProcessorRule", "scriptFilename": f"{currentScript}"}]} + jsonString = json.dumps(aDict) + jsonFile = open(outputFilename, "w") + jsonFile.write(jsonString) + jsonFile.close() + + # return a job product for the generated assetinfo file + sceneManifestType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0) + subId = 1 + product = azlmbr.asset.builder.JobProduct(outputFilename, sceneManifestType, subId) + product.dependenciesHandled = True + return product + +def process_fbx_file(request): + # fill out response object + response = azlmbr.asset.builder.ProcessJobResponse() + productOutputs = [] + + # prepare output folder + basePath, _ = os.path.split(request.sourceFile) + outputPath = os.path.join(request.tempDirPath, basePath) + os.makedirs(outputPath) + + # create assetinfo generated file + productOutputs.append(generate_assetinfo_product(request)) + + response.outputProducts = productOutputs + response.resultCode = azlmbr.asset.builder.ProcessJobResponse_Success + response.dependenciesHandled = True + return response + +# using the incoming 'request' find the type of job via 'jobKey' to determine what to do +def on_process_job(args): + try: + request = args[0] + if (request.jobDescription.jobKey.startswith(jobKeyName)): + return process_fbx_file(request) + + return azlmbr.asset.builder.ProcessJobResponse() + except: + log_exception_traceback() + return azlmbr.asset.builder.ProcessJobResponse() + +# register asset builder +def register_asset_builder(): + assetPattern = azlmbr.asset.builder.AssetBuilderPattern() + assetPattern.pattern = '*.blast' + assetPattern.type = azlmbr.asset.builder.AssetBuilderPattern_Wildcard + + builderDescriptor = azlmbr.asset.builder.AssetBuilderDesc() + builderDescriptor.name = "Blast Scene Builder" + builderDescriptor.patterns = [assetPattern] + builderDescriptor.busId = busId + builderDescriptor.version = 1 + + outcome = azlmbr.asset.builder.PythonAssetBuilderRequestBus(azlmbr.bus.Broadcast, 'RegisterAssetBuilder', builderDescriptor) + if outcome.IsSuccess(): + # created the asset builder to hook into the notification bus + handler = azlmbr.asset.builder.PythonBuilderNotificationBusHandler() + handler.connect(busId) + handler.add_callback('OnCreateJobsRequest', on_create_jobs) + handler.add_callback('OnProcessJobRequest', on_process_job) + return handler + +# create the asset builder handler +pythonAssetBuilderHandler = None +try: + if (pythonAssetBuilderHandler == None): + pythonAssetBuilderHandler = register_asset_builder() +except: + pythonAssetBuilderHandler = None + +# +# SceneAPI Processor +# +blastChunksAssetType = azlmbr.math.Uuid_CreateString('{993F0B0F-37D9-48C6-9CC2-E27D3F3E343E}', 0) + +def export_chunk_asset(scene, outputDirectory, platformIdentifier, productList): + import azlmbr.scene + import azlmbr.object + import azlmbr.paths + import json, os + + jsonFilename = os.path.basename(scene.sourceFilename) + jsonFilename = os.path.join(outputDirectory, jsonFilename + '.blast_chunks') + + # prepare output folder + basePath, _ = os.path.split(jsonFilename) + outputPath = os.path.join(outputDirectory, basePath) + if not os.path.exists(outputPath): + os.makedirs(outputPath, False) + + # write out a JSON file with the chunk file info + with open(jsonFilename, "w") as jsonFile: + jsonFile.write(scene.manifest.ExportToJson()) + + exportProduct = azlmbr.scene.ExportProduct() + exportProduct.filename = jsonFilename + exportProduct.sourceId = scene.sourceGuid + exportProduct.assetType = blastChunksAssetType + exportProduct.subId = 101 + + exportProductList = azlmbr.scene.ExportProductList() + exportProductList.AddProduct(exportProduct) + return exportProductList + +def on_prepare_for_export(args): + try: + scene = args[0] # azlmbr.scene.Scene + outputDirectory = args[1] # string + platformIdentifier = args[2] # string + productList = args[3] # azlmbr.scene.ExportProductList + return export_chunk_asset(scene, outputDirectory, platformIdentifier, productList) + except: + log_exception_traceback() + +def get_mesh_node_names(sceneGraph): + import azlmbr.scene as sceneApi + import azlmbr.scene.graph + from scene_api import scene_data as sceneData + + meshDataList = [] + node = sceneGraph.get_root() + children = [] + + while node.IsValid(): + # store children to process after siblings + if sceneGraph.has_node_child(node): + children.append(sceneGraph.get_node_child(node)) + + # store any node that has mesh data content + nodeContent = sceneGraph.get_node_content(node) + if nodeContent is not None and nodeContent.CastWithTypeName('MeshData'): + if sceneGraph.is_node_end_point(node) is False: + nodeName = sceneData.SceneGraphName(sceneGraph.get_node_name(node)) + nodePath = nodeName.get_path() + if (len(nodeName.get_path())): + meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node))) + + # advance to next node + if sceneGraph.has_node_sibling(node): + node = sceneGraph.get_node_sibling(node) + elif children: + node = children.pop() + else: + node = azlmbr.scene.graph.NodeIndex() + + return meshDataList + +def update_manifest(scene): + import uuid, os + import azlmbr.scene as sceneApi + import azlmbr.scene.graph + from scene_api import scene_data as sceneData + + graph = sceneData.SceneGraph(scene.graph) + meshNameList = get_mesh_node_names(graph) + sceneManifest = sceneData.SceneManifest() + sourceFilenameOnly = os.path.basename(scene.sourceFilename) + sourceFilenameOnly = sourceFilenameOnly.replace('.','_') + + for activeMeshIndex in range(len(meshNameList)): + chunkName = meshNameList[activeMeshIndex] + chunkPath = chunkName.get_path() + meshGroupName = '{}_{}'.format(sourceFilenameOnly, chunkName.get_name()) + meshGroup = sceneManifest.add_mesh_group(meshGroupName) + meshGroup['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, sourceFilenameOnly + chunkPath)) + '}' + sceneManifest.mesh_group_select_node(meshGroup, chunkPath) + + return sceneManifest.export() + +sceneJobHandler = None + +def on_update_manifest(args): + try: + scene = args[0] + return update_manifest(scene) + except: + global sceneJobHandler + sceneJobHandler = None + log_exception_traceback() + +# try to create SceneAPI handler for processing +try: + import azlmbr.scene as sceneApi + if (sceneJobHandler == None): + sceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler() + sceneJobHandler.connect() + sceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest) + sceneJobHandler.add_callback('OnPrepareForExport', on_prepare_for_export) +except: + sceneJobHandler = None diff --git a/Gems/Blast/Editor/Scripts/bootstrap.py b/Gems/Blast/Editor/Scripts/bootstrap.py index d9687bb85b..93004d474f 100755 --- a/Gems/Blast/Editor/Scripts/bootstrap.py +++ b/Gems/Blast/Editor/Scripts/bootstrap.py @@ -4,6 +4,13 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ - -# LYN-652 to re-enable once the Blast gem tests are stable -# import asset_builder_blast +try: + import azlmbr.asset + import azlmbr.asset.entity + import azlmbr.asset.builder + import blast_asset_builder +except: + # this script only runs in an asset processing environment + # like the AssetProcessor or an AssetBuilder + # plus the Blast gem needs to be enabled for the project + pass diff --git a/Gems/Camera/Code/Source/ViewportCameraSelectorWindow.cpp b/Gems/Camera/Code/Source/ViewportCameraSelectorWindow.cpp index 9644aa76f9..f664d78c0e 100644 --- a/Gems/Camera/Code/Source/ViewportCameraSelectorWindow.cpp +++ b/Gems/Camera/Code/Source/ViewportCameraSelectorWindow.cpp @@ -102,7 +102,7 @@ namespace Camera int CameraListModel::rowCount([[maybe_unused]] const QModelIndex& parent) const { - return m_cameraItems.size(); + return static_cast(m_cameraItems.size()); } QVariant CameraListModel::data(const QModelIndex& index, int role) const diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeCommands.cpp index f72833df56..fe41312701 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeCommands.cpp @@ -11,6 +11,7 @@ #include "CommandManager.h" #include +#include #include #include #include @@ -858,8 +859,16 @@ namespace CommandSystem // add it to the old node group if it was assigned to one before if (!mNodeGroupName.empty()) { - commandString = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %i -name \"%s\" -nodeNames \"%s\" -nodeAction \"add\"", animGraph->GetID(), mNodeGroupName.c_str(), mName.c_str()); - if (GetCommandManager()->ExecuteCommandInsideCommand(commandString.c_str(), outResult) == false) + auto* command = aznew CommandSystem::CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ animGraph->GetID(), + /*name = */ mNodeGroupName, + /*visible = */ AZStd::nullopt, + /*newName = */ AZStd::nullopt, + /*nodeNames = */ {{mName}}, + /*nodeAction = */ CommandSystem::CommandAnimGraphAdjustNodeGroup::NodeAction::Add + ); + if (GetCommandManager()->ExecuteCommandInsideCommand(command, outResult) == false) { if (outResult.size() > 0) { @@ -1363,11 +1372,16 @@ namespace CommandSystem EMotionFX::AnimGraphNodeGroup* nodeGroup = node->GetAnimGraph()->FindNodeGroupForNode(node); if (nodeGroup && !cutMode) { - commandString = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %d -name \"%s\" -nodeNames \"%s\" -nodeAction \"add\"", - targetAnimGraph->GetID(), - nodeGroup->GetName(), - nodeName.c_str()); - commandGroup->AddCommandString(commandString); + auto* command = aznew CommandSystem::CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ targetAnimGraph->GetID(), + /*name = */ nodeGroup->GetNameString(), + /*visible = */ AZStd::nullopt, + /*newName = */ AZStd::nullopt, + /*nodeNames = */ {{nodeName}}, + /*nodeAction = */ CommandSystem::CommandAnimGraphAdjustNodeGroup::NodeAction::Add + ); + commandGroup->AddCommand(command); } // Recurse through the child nodes. diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.cpp index 29ee45312b..f5f913f0ca 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.cpp @@ -6,6 +6,7 @@ * */ +#include #include #include "AnimGraphNodeGroupCommands.h" #include "AnimGraphConnectionCommands.h" @@ -22,45 +23,46 @@ namespace CommandSystem { + AZ_CLASS_ALLOCATOR_IMPL(CommandAnimGraphAdjustNodeGroup, EMotionFX::CommandAllocator, 0) + //-------------------------------------------------------------------------------- // CommandAnimGraphAdjustNodeGroup //-------------------------------------------------------------------------------- - CommandAnimGraphAdjustNodeGroup::CommandAnimGraphAdjustNodeGroup(MCore::Command* orgCommand) - : MCore::Command("AnimGraphAdjustNodeGroup", orgCommand) + CommandAnimGraphAdjustNodeGroup::CommandAnimGraphAdjustNodeGroup( + MCore::Command* orgCommand, + AZ::u32 animGraphId, + AZStd::string name, + AZStd::optional visible, + AZStd::optional newName, + AZStd::optional> nodeNames, + AZStd::optional nodeAction, + AZStd::optional color, + AZStd::optional updateUI + ) + : MCore::Command(s_commandName, orgCommand) + , ParameterMixinAnimGraphId(animGraphId) + , m_name(AZStd::move(name)) + , m_isVisible(visible) + , m_newName(AZStd::move(newName)) + , m_nodeNames(AZStd::move(nodeNames)) + , m_nodeAction(nodeAction) + , m_color(color) + , m_updateUI(updateUI) { } - - CommandAnimGraphAdjustNodeGroup::~CommandAnimGraphAdjustNodeGroup() + AZStd::vector CommandAnimGraphAdjustNodeGroup::GenerateNodeNameVector(EMotionFX::AnimGraph* animGraph, const AZStd::vector& nodeIDs) { - } - - - AZStd::string CommandAnimGraphAdjustNodeGroup::GenerateNodeNameString(EMotionFX::AnimGraph* animGraph, const AZStd::vector& nodeIDs) - { - if (nodeIDs.empty()) + AZStd::vector result; + for (const auto& nodeID : nodeIDs) { - return ""; - } - - AZStd::string result; - - const size_t numNodes = nodeIDs.size(); - for (size_t i = 0; i < numNodes; ++i) - { - EMotionFX::AnimGraphNode* animGraphNode = animGraph->RecursiveFindNodeById(nodeIDs[i]); + const EMotionFX::AnimGraphNode* animGraphNode = animGraph->RecursiveFindNodeById(nodeID); if (!animGraphNode) { continue; } - - result += animGraphNode->GetName(); - if (i < numNodes - 1) - { - result += ';'; - } + result.emplace_back(animGraphNode->GetName()); } - return result; } @@ -80,78 +82,51 @@ namespace CommandSystem } - bool CommandAnimGraphAdjustNodeGroup::Execute(const MCore::CommandLine& parameters, AZStd::string& outResult) + bool CommandAnimGraphAdjustNodeGroup::Execute(const MCore::CommandLine&, AZStd::string& outResult) { - EMotionFX::AnimGraph* animGraph = CommandsGetAnimGraph(parameters, this, outResult); + EMotionFX::AnimGraph* animGraph = EMotionFX::GetAnimGraphManager().FindAnimGraphByID(m_animGraphId); if (!animGraph) { return false; } - // get the node group name - AZStd::string groupName; - parameters.GetValue("name", this, groupName); - // find the node group index - const uint32 groupIndex = animGraph->FindNodeGroupIndexByName(groupName.c_str()); + const uint32 groupIndex = animGraph->FindNodeGroupIndexByName(m_name.c_str()); if (groupIndex == MCORE_INVALIDINDEX32) { - outResult = AZStd::string::format("Node group \"%s\" can not be found.", groupName.c_str()); + outResult = AZStd::string::format("Node group \"%s\" can not be found.", m_name.c_str()); return false; } - // get a pointer to the node group and keep the old name EMotionFX::AnimGraphNodeGroup* nodeGroup = animGraph->GetNodeGroup(groupIndex); - mOldName = nodeGroup->GetName(); - // is visible? - if (parameters.CheckIfHasParameter("isVisible")) + if (m_isVisible.has_value()) { - const bool isVisible = parameters.GetValueAsBool("isVisible", this); - mOldIsVisible = nodeGroup->GetIsVisible(); - nodeGroup->SetIsVisible(isVisible); + m_oldIsVisible = nodeGroup->GetIsVisible(); + nodeGroup->SetIsVisible(*m_isVisible); } - // background color - if (parameters.CheckIfHasParameter("color")) + if (m_color.has_value()) { - const AZ::Vector4 colorVector4 = parameters.GetValueAsVector4("color", this); - const AZ::u32 color = AZ::Color(static_cast(colorVector4.GetX()), static_cast(colorVector4.GetY()), static_cast(colorVector4.GetZ()), static_cast(colorVector4.GetW())).ToU32(); - mOldColor = nodeGroup->GetColor(); - nodeGroup->SetColor(color); + m_oldColor = nodeGroup->GetColor(); + nodeGroup->SetColor(*m_color); } - // set the new name - // if the new name is empty, the name is not changed - AZStd::string newGroupName; - parameters.GetValue("newName", this, newGroupName); - if (!newGroupName.empty()) + if (m_newName.has_value()) { - nodeGroup->SetName(newGroupName.c_str()); + nodeGroup->SetName(m_newName->c_str()); } // check if parametes nodeNames is set - if (parameters.CheckIfHasParameter("nodeNames")) + if (m_nodeNames.has_value()) { // keep the old nodes IDs - mOldNodeIds = CollectNodeIdsFromGroup(nodeGroup); - - // get the node action - AZStd::string nodeAction; - parameters.GetValue("nodeAction", this, nodeAction); - - // get the node names and split the string - AZStd::string nodeNamesString; - parameters.GetValue("nodeNames", this, nodeNamesString); - - - AZStd::vector nodeNames; - AzFramework::StringFunc::Tokenize(nodeNamesString.c_str(), nodeNames, ";", false, true); + m_oldNodeIds = CollectNodeIdsFromGroup(nodeGroup); // remove the selected nodes from the given node group - if (AzFramework::StringFunc::Equal(nodeAction.c_str(), "remove")) + if (*m_nodeAction == NodeAction::Remove) { - for (const AZStd::string& nodeName : nodeNames) + for (const AZStd::string& nodeName : *m_nodeNames) { EMotionFX::AnimGraphNode* animGraphNode = animGraph->RecursiveFindNodeByName(nodeName.c_str()); if (!animGraphNode) @@ -163,9 +138,9 @@ namespace CommandSystem nodeGroup->RemoveNodeById(animGraphNode->GetId()); } } - else if (AzFramework::StringFunc::Equal(nodeAction.c_str(), "add")) // add the selected nodes to the given node group + else if (*m_nodeAction == NodeAction::Add) { - for (const AZStd::string& nodeName : nodeNames) + for (const AZStd::string& nodeName : *m_nodeNames) { EMotionFX::AnimGraphNode* animGraphNode = animGraph->RecursiveFindNodeByName(nodeName.c_str()); if (!animGraphNode) @@ -184,12 +159,12 @@ namespace CommandSystem nodeGroup->AddNode(animGraphNode->GetId()); } } - else if (AzFramework::StringFunc::Equal(nodeAction.c_str(), "replace")) // clear the node group and then add the selected nodes to the given node group + else if (*m_nodeAction == NodeAction::Replace) { // clear the node group upfront nodeGroup->RemoveAllNodes(); - for (const AZStd::string& nodeName : nodeNames) + for (const AZStd::string& nodeName : *m_nodeNames) { EMotionFX::AnimGraphNode* animGraphNode = animGraph->RecursiveFindNodeByName(nodeName.c_str()); if (!animGraphNode) @@ -211,68 +186,40 @@ namespace CommandSystem } // save the current dirty flag and tell the anim graph that something got changed - mOldDirtyFlag = animGraph->GetDirtyFlag(); + m_oldDirtyFlag = animGraph->GetDirtyFlag(); animGraph->SetDirtyFlag(true); return true; } // undo the command - bool CommandAnimGraphAdjustNodeGroup::Undo(const MCore::CommandLine& parameters, AZStd::string& outResult) + bool CommandAnimGraphAdjustNodeGroup::Undo(const MCore::CommandLine&, AZStd::string& outResult) { - EMotionFX::AnimGraph* animGraph = CommandsGetAnimGraph(parameters, this, outResult); + EMotionFX::AnimGraph* animGraph = EMotionFX::GetAnimGraphManager().FindAnimGraphByID(m_animGraphId); if (!animGraph) { return false; } - AZStd::string commandString = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %i", animGraph->GetID()); - - // set the old name or simply set the name if the name is not changed - if (parameters.CheckIfHasParameter("newName")) - { - AZStd::string newName; - parameters.GetValue("newName", this, newName); - - commandString += AZStd::string::format(" -name \"%s\"", newName.c_str()); - commandString += AZStd::string::format(" -newName \"%s\"", mOldName.c_str()); - } - else - { - commandString += AZStd::string::format(" -name \"%s\"", mOldName.c_str()); - } - - // set the old visible flag - if (parameters.CheckIfHasParameter("isVisible")) - { - commandString += AZStd::string::format(" -isVisible %i", mOldIsVisible); - } - - // set the old color - if (parameters.CheckIfHasParameter("color")) - { - AZ::Color oldColor; - oldColor.FromU32(mOldColor); - const AZStd::string oldColorString = AZStd::string::format("%.8f,%.8f,%.8f,%.8f", static_cast(oldColor.GetR()), static_cast(oldColor.GetG()), static_cast(oldColor.GetB()), static_cast(oldColor.GetA())); - - commandString += AZStd::string::format(" -color \"%s\"", oldColorString.c_str()); - } - - // set the old nodes - if (parameters.CheckIfHasParameter("nodeNames")) - { - const AZStd::string nodeNamesString = CommandAnimGraphAdjustNodeGroup::GenerateNodeNameString(animGraph, mOldNodeIds); - commandString += AZStd::string::format(" -nodeNames \"%s\" -nodeAction \"replace\"", nodeNamesString.c_str()); - } + CommandAnimGraphAdjustNodeGroup* command = aznew CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ m_animGraphId, + /*name = */ m_newName.has_value() ? *m_newName : m_name, + /*visible = */ m_isVisible.has_value() ? AZStd::optional(m_oldIsVisible) : AZStd::nullopt, + /*newName = */ m_newName.has_value() ? AZStd::optional(m_name) : AZStd::nullopt, + /*nodeNames = */ m_nodeNames.has_value() ? AZStd::optional>(GenerateNodeNameVector(animGraph, m_oldNodeIds)) : AZStd::nullopt, + /*nodeAction = */ m_nodeNames.has_value() ? AZStd::optional(NodeAction::Replace) : AZStd::nullopt, + /*color = */ m_color.has_value() ? AZStd::optional(m_oldColor) : AZStd::nullopt + ); // execute the command - if (!GetCommandManager()->ExecuteCommandInsideCommand(commandString, outResult)) + if (!GetCommandManager()->ExecuteCommandInsideCommand(command, outResult)) { AZ_Error("EMotionFX", false, outResult.c_str()); } // set the dirty flag back to the old value - animGraph->SetDirtyFlag(mOldDirtyFlag); + animGraph->SetDirtyFlag(m_oldDirtyFlag); return true; } @@ -282,7 +229,7 @@ namespace CommandSystem { GetSyntax().ReserveParameters(8); GetSyntax().AddRequiredParameter("name", "The name of the node group to adjust.", MCore::CommandSyntax::PARAMTYPE_STRING); - GetSyntax().AddParameter("animGraphID", "The id of the blend set the node group belongs to.", MCore::CommandSyntax::PARAMTYPE_INT, "-1"); + EMotionFX::ParameterMixinAnimGraphId::InitSyntax(GetSyntax(), /*isParameterRequired=*/ false); GetSyntax().AddParameter("isVisible", "The visibility flag of the node group.", MCore::CommandSyntax::PARAMTYPE_BOOLEAN, "true"); GetSyntax().AddParameter("newName", "The new name of the node group.", MCore::CommandSyntax::PARAMTYPE_STRING, ""); GetSyntax().AddParameter("nodeNames", "A list of node names that should be added/removed to/from the node group.", MCore::CommandSyntax::PARAMTYPE_STRING, ""); @@ -291,6 +238,51 @@ namespace CommandSystem GetSyntax().AddParameter("updateUI", "Setting this to true will trigger a refresh of the node groups UI.", MCore::CommandSyntax::PARAMTYPE_BOOLEAN, "true"); } + bool CommandAnimGraphAdjustNodeGroup::SetCommandParameters(const MCore::CommandLine& parameters) + { + EMotionFX::ParameterMixinAnimGraphId::SetCommandParameters(parameters); + m_name = parameters.GetValue("name", this); + + if (parameters.CheckIfHasParameter("isVisible")) + { + m_isVisible = parameters.GetValueAsBool("isVisible", this); + } + if (parameters.CheckIfHasParameter("newName")) + { + m_newName = parameters.GetValue("newName", this); + } + if (parameters.CheckIfHasParameter("nodeNames")) + { + m_nodeNames.emplace(); + AzFramework::StringFunc::Tokenize(parameters.GetValue("nodeNames", this), m_nodeNames.value(), ";", false, true); + } + if (parameters.CheckIfHasValue("nodeAction")) + { + const AZStd::string& nodeActionStr = parameters.GetValue("nodeAction", this); + if (nodeActionStr == "add") + { + m_nodeAction = NodeAction::Add; + } + else if (nodeActionStr == "remove") + { + m_nodeAction = NodeAction::Remove; + } + else if (nodeActionStr == "replace") + { + m_nodeAction = NodeAction::Replace; + } + } + if (parameters.CheckIfHasParameter("color")) + { + m_color = AZ::Color(parameters.GetValueAsVector4("color", this)).ToU32(); + } + if (parameters.CheckIfHasParameter("updateUI")) + { + m_updateUI = parameters.GetValueAsBool("updateUI", this); + } + + return true; + } const char* CommandAnimGraphAdjustNodeGroup::GetDescription() const { @@ -447,21 +439,20 @@ namespace CommandSystem MCore::CommandGroup commandGroup; - AZStd::string commandString = AZStd::string::format("AnimGraphAddNodeGroup -animGraphID %i -name \"%s\" -updateUI %s",animGraph->GetID(), mOldName.c_str(), updateWindow.c_str()); - commandGroup.AddCommandString(commandString); + commandGroup.AddCommandString(AZStd::string::format("AnimGraphAddNodeGroup -animGraphID %i -name \"%s\" -updateUI %s",animGraph->GetID(), mOldName.c_str(), updateWindow.c_str())); - const AZStd::string nodeNamesString = CommandAnimGraphAdjustNodeGroup::GenerateNodeNameString(animGraph, mOldNodeIds); + auto* command = aznew CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ animGraph->GetID(), + /*name = */ mOldName, + /*visible = */ mOldIsVisible, + /*newName = */ AZStd::nullopt, + /*nodeNames = */ CommandAnimGraphAdjustNodeGroup::GenerateNodeNameVector(animGraph, mOldNodeIds), + /*nodeAction = */ CommandAnimGraphAdjustNodeGroup::NodeAction::Add, + /*color = */ mOldColor + ); - AZ::Color oldColor; - oldColor.FromU32(mOldColor); - const AZStd::string oldColorString = AZStd::string::format("%.8f,%.8f,%.8f,%.8f", - static_cast(oldColor.GetR()), static_cast(oldColor.GetG()), static_cast(oldColor.GetB()), static_cast(oldColor.GetA())); - - commandString = AZStd::string::format( - "AnimGraphAdjustNodeGroup -animGraphID %i -name \"%s\" -isVisible %s -color \"%s\" -nodeNames \"%s\" -nodeAction \"add\" -updateUI %s", - animGraph->GetID(), mOldName.c_str(), AZStd::to_string(mOldIsVisible).c_str(), oldColorString.c_str(), nodeNamesString.c_str(), updateWindow.c_str()); - - commandGroup.AddCommandString(commandString); + commandGroup.AddCommand(command); AZStd::string result; if (!GetCommandManager()->ExecuteCommandGroupInsideCommand(commandGroup, result)) diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.h b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.h index 85bd92f970..0fc497d2f1 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.h +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphNodeGroupCommands.h @@ -13,22 +13,73 @@ #include #include #include +#include namespace CommandSystem { // adjust a node group - MCORE_DEFINECOMMAND_START(CommandAnimGraphAdjustNodeGroup, "Adjust anim graph node group", true) -public: - static AZStd::string GenerateNodeNameString(EMotionFX::AnimGraph* animGraph, const AZStd::vector& nodeIDs); - static AZStd::vector CollectNodeIdsFromGroup(EMotionFX::AnimGraphNodeGroup* nodeGroup); + class CommandAnimGraphAdjustNodeGroup + : public MCore::Command + , public EMotionFX::ParameterMixinAnimGraphId + { + public: + AZ_CLASS_ALLOCATOR_DECL - AZStd::string mOldName; - bool mOldIsVisible; - AZ::u32 mOldColor; - AZStd::vector mOldNodeIds; - bool mOldDirtyFlag; - MCORE_DEFINECOMMAND_END + static constexpr inline AZStd::string_view s_commandName = "AnimGraphAdjustNodeGroup"; + enum class NodeAction + { + Add, + Remove, + Replace + }; + + explicit CommandAnimGraphAdjustNodeGroup( + MCore::Command* orgCommand = nullptr, + AZ::u32 animGraphId = MCORE_INVALIDINDEX32, + AZStd::string name = AZStd::string{}, + AZStd::optional visible = AZStd::nullopt, + AZStd::optional newName = AZStd::nullopt, + AZStd::optional> nodeNames = AZStd::nullopt, + AZStd::optional nodeAction = AZStd::nullopt, + AZStd::optional color = AZStd::nullopt, + AZStd::optional updateUI = AZStd::nullopt + ); + bool Execute(const MCore::CommandLine& parameters, AZStd::string& outResult) override; + bool Undo(const MCore::CommandLine& parameters, AZStd::string& outResult) override; + void InitSyntax() override; + bool SetCommandParameters(const MCore::CommandLine& parameters) override; + bool GetIsUndoable() const override + { + return true; + } + const char* GetHistoryName() const override + { + return "Adjust anim graph node group"; + } + const char* GetDescription() const override; + MCore::Command* Create() override + { + return new CommandAnimGraphAdjustNodeGroup(this); + } + + static AZStd::vector GenerateNodeNameVector(EMotionFX::AnimGraph* animGraph, const AZStd::vector& nodeIDs); + static AZStd::vector CollectNodeIdsFromGroup(EMotionFX::AnimGraphNodeGroup* nodeGroup); + + private: + AZStd::string m_name; + AZStd::optional m_isVisible; + AZStd::optional m_newName; + AZStd::optional> m_nodeNames; + AZStd::optional m_nodeAction; + AZStd::optional m_color; + AZStd::optional m_updateUI; + + bool m_oldIsVisible; + AZ::u32 m_oldColor; + AZStd::vector m_oldNodeIds; + bool m_oldDirtyFlag; + }; // add node group MCORE_DEFINECOMMAND_START(CommandAnimGraphAddNodeGroup, "Add anim graph node group", true) diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp index fe4a3e1ca9..ea83d90d4b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.cpp @@ -9,7 +9,7 @@ // include the required headers #include "NodeGroupCommands.h" #include "CommandManager.h" -#include +#include #include #include #include @@ -20,230 +20,147 @@ namespace CommandSystem //-------------------------------------------------------------------------------- // CommandAdjustNodeGroup //-------------------------------------------------------------------------------- + AZ_CLASS_ALLOCATOR_IMPL(CommandAdjustNodeGroup, EMotionFX::CommandAllocator, 0) - // constructor - CommandAdjustNodeGroup::CommandAdjustNodeGroup(MCore::Command* orgCommand) - : MCore::Command("AdjustNodeGroup", orgCommand) - , mOldNodeGroup(nullptr) + CommandAdjustNodeGroup::CommandAdjustNodeGroup( + MCore::Command* orgCommand, + uint32 actorId, + const AZStd::string& name, + AZStd::optional newName, + AZStd::optional enabledOnDefault, + AZStd::optional> nodeNames, + AZStd::optional nodeAction + ) + : MCore::Command(s_commandName.data(), orgCommand) + , EMotionFX::ParameterMixinActorId(actorId) + , m_name(name) + , m_newName(AZStd::move(newName)) + , m_enabledOnDefault(enabledOnDefault) + , m_nodeNames(AZStd::move(nodeNames)) + , m_nodeAction(nodeAction) { } - // destructor - CommandAdjustNodeGroup::~CommandAdjustNodeGroup() - { - if (mOldNodeGroup) - { - mOldNodeGroup->Destroy(); - } - } - - // execute - bool CommandAdjustNodeGroup::Execute(const MCore::CommandLine& parameters, AZStd::string& outResult) + bool CommandAdjustNodeGroup::Execute(const MCore::CommandLine&, AZStd::string& outResult) { - AZStd::string valueString; - - // get the motion id and the corresponding motion pointer - const int32 actorID = parameters.GetValueAsInt("actorID", this); - parameters.GetValue("name", this, &valueString); - // get the actor - EMotionFX::Actor* actor = EMotionFX::GetActorManager().FindActorByID(actorID); + EMotionFX::Actor* actor = EMotionFX::GetActorManager().FindActorByID(m_actorId); if (actor == nullptr) { - outResult = AZStd::string::format("Cannot adjust node group. Actor with id='%i' does not exist.", actorID); + outResult = AZStd::string::format("Cannot adjust node group. Actor with id='%i' does not exist.", m_actorId); return false; } // get the node group - EMotionFX::NodeGroup* nodeGroup = actor->FindNodeGroupByNameNoCase(valueString.c_str()); + EMotionFX::NodeGroup* nodeGroup = actor->FindNodeGroupByNameNoCase(m_name.c_str()); if (nodeGroup == nullptr) { - outResult = AZStd::string::format("Cannot adjust node group. Node group with name='%s' does not exist.", valueString.c_str()); + outResult = AZStd::string::format("Cannot adjust node group. Node group with name='%s' does not exist.", m_name.c_str()); return false; } - // copy the old node group for undo - if (mOldNodeGroup) - { - mOldNodeGroup->Destroy(); - } - - mOldNodeGroup = aznew EMotionFX::NodeGroup(*nodeGroup); + m_oldNodeGroup = AZStd::make_unique(*nodeGroup); // check if newName is set and apply new name - if (parameters.CheckIfHasParameter("newName")) + if (m_newName.has_value()) { - parameters.GetValue("newName", this, &valueString); - nodeGroup->SetName(valueString.c_str()); + nodeGroup->SetName(*m_newName); } // check if parameter disabledOnDefault is set and adjust it - if (parameters.CheckIfHasParameter("enabledOnDefault")) + if (m_enabledOnDefault.has_value()) { - const bool enabledOnDefault = parameters.GetValueAsBool("enabledOnDefault", this); - nodeGroup->SetIsEnabledOnDefault(enabledOnDefault); + nodeGroup->SetIsEnabledOnDefault(*m_enabledOnDefault); } // check if parametes nodeNames is set - if (parameters.CheckIfHasParameter("nodeNames")) + if (m_nodeNames.has_value()) { - // get the node action - AZStd::string nodeAction; - parameters.GetValue("nodeAction", this, &valueString); - - // get the node names and split the string - AZStd::string nodeNameString; - parameters.GetValue("nodeNames", this, &nodeNameString); - - // get the individual node names - AZStd::vector nodeNames; - AzFramework::StringFunc::Tokenize(nodeNameString.c_str(), nodeNames, MCore::CharacterConstants::semiColon, true /* keep empty strings */, true /* keep space strings */); - - // get the number of nodes - const size_t numNodes = nodeNames.size(); - - // remove the selected nodes from the node group - if (AzFramework::StringFunc::Equal(valueString.c_str(), "remove", false /* no case */)) + if (*m_nodeAction == NodeAction::Replace) { - for (size_t i = 0; i < numNodes; ++i) - { - // get the node - EMotionFX::Node* node = actor->GetSkeleton()->FindNodeByName(nodeNames[i].c_str()); - if (node == nullptr) - { - continue; - } - - // remove the node - nodeGroup->RemoveNodeByNodeIndex((uint16)node->GetNodeIndex()); - } - } - else if (AzFramework::StringFunc::Equal(valueString.c_str(), "add", false /* no case */)) // add the selected nodes to the node group - { - for (size_t i = 0; i < numNodes; ++i) - { - // get the node - EMotionFX::Node* node = actor->GetSkeleton()->FindNodeByName(nodeNames[i].c_str()); - if (node == nullptr) - { - continue; - } - - // add the node - uint16 nodeIndex = (uint16)node->GetNodeIndex(); - nodeGroup->RemoveNodeByNodeIndex(nodeIndex); - nodeGroup->AddNode(nodeIndex); - } - } - else // selected nodes form the new node group - { - // clear previous nodes nodeGroup->GetNodeArray().Clear(); - - // add all nodes to the group - for (size_t i = 0; i < numNodes; ++i) + } + for (const AZStd::string& nodeName : *m_nodeNames) + { + EMotionFX::Node* node = actor->GetSkeleton()->FindNodeByName(nodeName); + if (!node) { - // get the node - EMotionFX::Node* node = actor->GetSkeleton()->FindNodeByName(nodeNames[i].c_str()); + continue; + } - // check if node exists - if (node == nullptr) - { - continue; - } - - // add the node - nodeGroup->AddNode((uint16)node->GetNodeIndex()); + uint16 nodeIndex = (uint16)node->GetNodeIndex(); + nodeGroup->RemoveNodeByNodeIndex(nodeIndex); + if (*m_nodeAction == NodeAction::Add || *m_nodeAction == NodeAction::Replace) + { + nodeGroup->AddNode(nodeIndex); } } } // save the current dirty flag and tell the actor that something got changed - mOldDirtyFlag = actor->GetDirtyFlag(); + m_oldDirtyFlag = actor->GetDirtyFlag(); actor->SetDirtyFlag(true); return true; } // undo the command - bool CommandAdjustNodeGroup::Undo(const MCore::CommandLine& parameters, AZStd::string& outResult) + bool CommandAdjustNodeGroup::Undo(const MCore::CommandLine&, AZStd::string& outResult) { // return if no information about the previous node group was stored - if (!mOldNodeGroup) + if (!m_oldNodeGroup) { return false; } - // get the motion id and the corresponding motion pointer - int32 actorID = parameters.GetValueAsInt("actorID", this); - - // get the name - AZStd::string name; - if (parameters.CheckIfHasParameter("newName")) - { - parameters.GetValue("newName", this, &name); - } - else - { - parameters.GetValue("name", this, &name); - } - - // get the actor - EMotionFX::Actor* actor = EMotionFX::GetActorManager().FindActorByID(actorID); + EMotionFX::Actor* actor = EMotionFX::GetActorManager().FindActorByID(m_actorId); // return error if actor was not found if (actor == nullptr) { - outResult = AZStd::string::format("Cannot adjust node group. Actor with id='%i' does not exist.", actorID); + outResult = AZStd::string::format("Cannot adjust node group. Actor with id='%i' does not exist.", m_actorId); return false; } - // get the node group - EMotionFX::NodeGroup* nodeGroup = actor->FindNodeGroupByNameNoCase(name.c_str()); + EMotionFX::NodeGroup* nodeGroup = actor->FindNodeGroupByNameNoCase(m_newName.has_value() ? m_newName->c_str() : m_name.c_str()); - // return error if node group name is not set - if (nodeGroup == nullptr) + if (!nodeGroup) { - outResult = AZStd::string::format("Cannot adjust node group. Node group with name='%s' does not exist.", name.c_str()); + outResult = AZStd::string::format("Cannot adjust node group. Node group with name='%s' does not exist.", m_newName.has_value() ? m_newName->c_str() : m_name.c_str()); return false; } // reset the old values - if (parameters.CheckIfHasParameter("enabledOnDefault")) + if (m_enabledOnDefault.has_value()) { - nodeGroup->SetIsEnabledOnDefault(mOldNodeGroup->GetIsEnabledOnDefault()); + nodeGroup->SetIsEnabledOnDefault(m_oldNodeGroup->GetIsEnabledOnDefault()); } - if (parameters.CheckIfHasParameter("newName")) + if (m_newName.has_value()) { - nodeGroup->SetName(mOldNodeGroup->GetName()); + nodeGroup->SetName(m_oldNodeGroup->GetName()); } - if (parameters.CheckIfHasParameter("nodeNames")) + if (m_nodeNames.has_value()) { // clear previous nodes nodeGroup->GetNodeArray().Clear(); - const uint32 numNodes = mOldNodeGroup->GetNumNodes(); - nodeGroup->SetNumNodes(static_cast(numNodes)); + const uint16 numNodes = m_oldNodeGroup->GetNumNodes(); + nodeGroup->SetNumNodes(numNodes); // add all nodes to the group - for (uint32 i = 0; i < numNodes; ++i) + for (uint16 i = 0; i < numNodes; ++i) { - nodeGroup->SetNode(static_cast(i), mOldNodeGroup->GetNode(static_cast(i))); + nodeGroup->SetNode(i, m_oldNodeGroup->GetNode(i)); } } - // delete the old node group - if (mOldNodeGroup) - { - mOldNodeGroup->Destroy(); - } - mOldNodeGroup = nullptr; + m_oldNodeGroup = nullptr; // set the dirty flag back to the old value - actor->SetDirtyFlag(mOldDirtyFlag); + actor->SetDirtyFlag(m_oldDirtyFlag); return true; } @@ -252,7 +169,7 @@ namespace CommandSystem void CommandAdjustNodeGroup::InitSyntax() { GetSyntax().ReserveParameters(6); - GetSyntax().AddRequiredParameter("actorID", "The id of the actor the node group belongs to.", MCore::CommandSyntax::PARAMTYPE_INT); + EMotionFX::ParameterMixinActorId::InitSyntax(GetSyntax(), /*isParameterRequired=*/ true); GetSyntax().AddRequiredParameter("name", "The name of the node group to adjust.", MCore::CommandSyntax::PARAMTYPE_STRING); GetSyntax().AddParameter("newName", "The new name of the node group.", MCore::CommandSyntax::PARAMTYPE_STRING, ""); GetSyntax().AddParameter("enabledOnDefault", "The enabled on default flag.", MCore::CommandSyntax::PARAMTYPE_BOOLEAN, "false"); @@ -261,6 +178,45 @@ namespace CommandSystem } + bool CommandAdjustNodeGroup::SetCommandParameters(const MCore::CommandLine& parameters) + { + EMotionFX::ParameterMixinActorId::SetCommandParameters(parameters); + + m_name = parameters.GetValue("name", this); + if (parameters.CheckIfHasParameter("newName")) + { + m_newName = parameters.GetValue("newName", this); + } + if (parameters.CheckIfHasParameter("enabledOnDefault")) + { + m_enabledOnDefault = parameters.GetValueAsBool("enabledOnDefault", this); + } + if (parameters.CheckIfHasParameter("nodeNames")) + { + m_nodeNames.emplace(); + AzFramework::StringFunc::Tokenize(parameters.GetValue("nodeNames", this), m_nodeNames.value(), ";", false, true); + } + if (parameters.CheckIfHasParameter("nodeAction")) + { + const AZStd::string& nodeActionStr = parameters.GetValue("nodeAction", this); + if (nodeActionStr == "add") + { + m_nodeAction = NodeAction::Add; + } + else if (nodeActionStr == "remove") + { + m_nodeAction = NodeAction::Remove; + } + else if (nodeActionStr == "replace") + { + m_nodeAction = NodeAction::Replace; + } + } + + return true; + } + + // get the description const char* CommandAdjustNodeGroup::GetDescription() const { @@ -304,7 +260,7 @@ namespace CommandSystem } // add new node group to the actor - EMotionFX::NodeGroup* nodeGroup = EMotionFX::NodeGroup::Create(name.c_str()); + EMotionFX::NodeGroup* nodeGroup = aznew EMotionFX::NodeGroup(name); actor->AddNodeGroup(nodeGroup); // save the current dirty flag and tell the actor that something got changed @@ -374,10 +330,7 @@ namespace CommandSystem // destructor CommandRemoveNodeGroup::~CommandRemoveNodeGroup() { - if (mOldNodeGroup) - { - mOldNodeGroup->Destroy(); - } + delete mOldNodeGroup; } @@ -407,11 +360,7 @@ namespace CommandSystem } // copy the old node group for undo - if (mOldNodeGroup) - { - mOldNodeGroup->Destroy(); - } - + delete mOldNodeGroup; mOldNodeGroup = aznew EMotionFX::NodeGroup(*nodeGroup); // remove the node group diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.h b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.h index e87ce2d62d..d29918822d 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.h +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/NodeGroupCommands.h @@ -9,10 +9,13 @@ #pragma once // include the required headers +#include #include "CommandSystemConfig.h" #include #include #include +#include +#include EMFX_FORWARD_DECLARE(Actor); EMFX_FORWARD_DECLARE(NodeGroup); @@ -20,20 +23,68 @@ EMFX_FORWARD_DECLARE(NodeGroup); namespace CommandSystem { // adjust a node group - MCORE_DEFINECOMMAND_START(CommandAdjustNodeGroup, "Adjust node group", true) - bool mOldDirtyFlag; - EMotionFX::NodeGroup* mOldNodeGroup; - MCORE_DEFINECOMMAND_END + class CommandAdjustNodeGroup + : public MCore::Command + , public EMotionFX::ParameterMixinActorId + { + public: + AZ_CLASS_ALLOCATOR_DECL + enum class NodeAction + { + Add, + Remove, + Replace + }; + + static constexpr inline AZStd::string_view s_commandName = "AdjustNodeGroup"; + + CommandAdjustNodeGroup( + MCore::Command* orgCommand = nullptr, + uint32 actorId = MCORE_INVALIDINDEX32, + const AZStd::string& name = {}, + AZStd::optional newName = AZStd::nullopt, + AZStd::optional enabledOnDefault = AZStd::nullopt, + AZStd::optional> nodeNames = AZStd::nullopt, + AZStd::optional nodeAction = AZStd::nullopt + ); + bool Execute(const MCore::CommandLine& parameters, AZStd::string& outResult) override; + bool Undo(const MCore::CommandLine& parameters, AZStd::string& outResult) override; + void InitSyntax() override; + bool SetCommandParameters(const MCore::CommandLine& parameters) override; + bool GetIsUndoable() const override + { + return true; + } + const char* GetHistoryName() const override + { + return "Adjust node group"; + } + const char* GetDescription() const override; + MCore::Command* Create() override + { + return new CommandAdjustNodeGroup(this); + } + + private: + AZStd::string m_name; + AZStd::optional m_newName; + AZStd::optional m_enabledOnDefault; + AZStd::optional> m_nodeNames; + AZStd::optional m_nodeAction; + + bool m_oldDirtyFlag = false; + AZStd::unique_ptr m_oldNodeGroup = nullptr; + }; // add node group - MCORE_DEFINECOMMAND_START(CommandAddNodeGroup, "Add node group", true) + MCORE_DEFINECOMMAND_START(CommandAddNodeGroup, "Add node group", true) bool mOldDirtyFlag; MCORE_DEFINECOMMAND_END // remove a node group - MCORE_DEFINECOMMAND_START(CommandRemoveNodeGroup, "Remove node group", true) + MCORE_DEFINECOMMAND_START(CommandRemoveNodeGroup, "Remove node group", true) EMotionFX::NodeGroup * mOldNodeGroup; bool mOldDirtyFlag; MCORE_DEFINECOMMAND_END diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ParameterMixins.h b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ParameterMixins.h index eb5de65f13..6461921160 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ParameterMixins.h +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ParameterMixins.h @@ -80,6 +80,8 @@ namespace EMotionFX AZ_RTTI(ParameterMixinAnimGraphId, "{3F48199E-6566-471F-A7EA-ADF67CAC4DCD}") AZ_CLASS_ALLOCATOR_DECL + ParameterMixinAnimGraphId() = default; + ParameterMixinAnimGraphId(AZ::u32 id) : m_animGraphId(id) {} virtual ~ParameterMixinAnimGraphId() = default; static void Reflect(AZ::ReflectContext* context); diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp index 973d8eb460..833f8a14f3 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp @@ -193,7 +193,7 @@ namespace EMotionFX const size_t numLodLevels = m_meshLodData.m_lodLevels.size(); MeshLODData& resultMeshLodData = result->m_meshLodData; - result->SetNumLODLevels(numLodLevels); + result->SetNumLODLevels(static_cast(numLodLevels)); for (size_t lodLevel = 0; lodLevel < numLodLevels; ++lodLevel) { const MCore::Array& nodeInfos = m_meshLodData.m_lodLevels[lodLevel].mNodeInfos; @@ -320,10 +320,10 @@ namespace EMotionFX // get the number of nodes, iterate through them, create a new LOD level and copy over the meshes from the last LOD level for (size_t i = 0; i < numNodes; ++i) { - NodeLODInfo& newLODInfo = lodLevels[lodIndex].mNodeInfos[i]; + NodeLODInfo& newLODInfo = lodLevels[lodIndex].mNodeInfos[static_cast(i)]; if (copyFromLastLODLevel && lodIndex > 0) { - const NodeLODInfo& prevLODInfo = lodLevels[lodIndex - 1].mNodeInfos[i]; + const NodeLODInfo& prevLODInfo = lodLevels[lodIndex - 1].mNodeInfos[static_cast(i)]; newLODInfo.mMesh = (prevLODInfo.mMesh) ? prevLODInfo.mMesh->Clone() : nullptr; newLODInfo.mStack = (prevLODInfo.mStack) ? prevLODInfo.mStack->Clone(newLODInfo.mMesh) : nullptr; } @@ -335,8 +335,8 @@ namespace EMotionFX } // create a new material array for the new LOD level - mMaterials.Resize(lodLevels.size()); - mMaterials[lodIndex].SetMemoryCategory(EMFX_MEMCATEGORY_ACTORS); + mMaterials.Resize(static_cast(lodLevels.size())); + mMaterials[static_cast(lodIndex)].SetMemoryCategory(EMFX_MEMCATEGORY_ACTORS); // create an empty morph setup for the new LOD level mMorphSetups.Add(nullptr); @@ -344,7 +344,7 @@ namespace EMotionFX // copy data from the previous LOD level if wanted if (copyFromLastLODLevel && numLODs > 0) { - CopyLODLevel(this, lodIndex - 1, numLODs - 1, true); + CopyLODLevel(this, static_cast(lodIndex - 1), static_cast(numLODs - 1), true); } } @@ -1015,7 +1015,7 @@ namespace EMotionFX const uint32 numGroups = mNodeGroups.GetLength(); for (uint32 i = 0; i < numGroups; ++i) { - mNodeGroups[i]->Destroy(); + delete mNodeGroups[i]; } mNodeGroups.Clear(); } @@ -1210,7 +1210,7 @@ namespace EMotionFX Node* node = mSkeleton->GetNode(n); // check if this node has a mesh, if not we can skip it - Mesh* mesh = GetMesh(geomLod, n); + Mesh* mesh = GetMesh(static_cast(geomLod), n); if (mesh == nullptr) { continue; @@ -1246,10 +1246,10 @@ namespace EMotionFX { // if the bone is disabled SkinInfluence* influence = layer->GetInfluence(orgVertex, i); - if (mSkeleton->GetNode(influence->GetNodeNr())->GetSkeletalLODStatus(geomLod) == false) + if (mSkeleton->GetNode(influence->GetNodeNr())->GetSkeletalLODStatus(static_cast(geomLod)) == false) { // find the first parent bone that is enabled in this LOD - const uint32 newNodeIndex = FindFirstActiveParentBone(geomLod, influence->GetNodeNr()); + const uint32 newNodeIndex = FindFirstActiveParentBone(static_cast(geomLod), influence->GetNodeNr()); if (newNodeIndex == MCORE_INVALIDINDEX32) { MCore::LogWarning("EMotionFX::Actor::MakeGeomLODsCompatibleWithSkeletalLODs() - Failed to find an enabled parent for node '%s' in skeletal LOD %d of actor '%s' (0x%x)", node->GetName(), geomLod, GetFileName(), this); @@ -1274,10 +1274,10 @@ namespace EMotionFX } // for all submeshes // reinit the mesh deformer stacks - MeshDeformerStack* stack = GetMeshDeformerStack(geomLod, node->GetNodeIndex()); + MeshDeformerStack* stack = GetMeshDeformerStack(static_cast(geomLod), node->GetNodeIndex()); if (stack) { - stack->ReinitializeDeformers(this, node, geomLod); + stack->ReinitializeDeformers(this, node, static_cast(geomLod)); } } // for all nodes } @@ -1520,7 +1520,7 @@ namespace EMotionFX { // Optional, not all actors have morph targets. const size_t numLODLevels = m_meshAsset->GetLodAssets().size(); - mMorphSetups.Resize(numLODLevels); + mMorphSetups.Resize(static_cast(numLODLevels)); for (AZ::u32 i = 0; i < numLODLevels; ++i) { mMorphSetups[i] = nullptr; @@ -1589,7 +1589,7 @@ namespace EMotionFX const uint32 orgVertex = orgVertices[startVertex + vertexIndex]; // for all skinning influences of the vertex - const uint32 numInfluences = layer->GetNumInfluences(orgVertex); + const uint32 numInfluences = static_cast(layer->GetNumInfluences(orgVertex)); float maxWeight = 0.0f; uint32 maxWeightNodeIndex = 0; for (uint32 i = 0; i < numInfluences; ++i) @@ -2085,7 +2085,7 @@ namespace EMotionFX { if (delFromMem) { - mNodeGroups[index]->Destroy(); + delete mNodeGroups[index]; } mNodeGroups.Remove(index); @@ -2097,7 +2097,7 @@ namespace EMotionFX mNodeGroups.RemoveByValue(group); if (delFromMem) { - group->Destroy(); + delete group; } } @@ -2787,13 +2787,13 @@ namespace EMotionFX const size_t numLODLevels = lodAssets.size(); lodLevels.clear(); - SetNumLODLevels(numLODLevels, /*adjustMorphSetup=*/false); + SetNumLODLevels(static_cast(numLODLevels), /*adjustMorphSetup=*/false); const uint32 numNodes = mSkeleton->GetNumNodes(); // Remove all the materials and add them back based on the meshAsset. Eventually we will remove all the material from Actor and // GLActor. RemoveAllMaterials(); - mMaterials.Resize(numLODLevels); + mMaterials.Resize(static_cast(numLODLevels)); for (size_t lodLevel = 0; lodLevel < numLODLevels; ++lodLevel) { @@ -2846,19 +2846,19 @@ namespace EMotionFX DualQuatSkinDeformer* skinDeformer = DualQuatSkinDeformer::Create(mesh); jointInfo.mStack->AddDeformer(skinDeformer); skinDeformer->ReserveLocalBones(numLocalJoints); - skinDeformer->Reinitialize(this, meshJoint, lodLevel); + skinDeformer->Reinitialize(this, meshJoint, static_cast(lodLevel)); } else { SoftSkinDeformer* skinDeformer = GetSoftSkinManager().CreateDeformer(mesh); jointInfo.mStack->AddDeformer(skinDeformer); skinDeformer->ReserveLocalBones(numLocalJoints); // pre-alloc data to prevent reallocs - skinDeformer->Reinitialize(this, meshJoint, lodLevel); + skinDeformer->Reinitialize(this, meshJoint, static_cast(lodLevel)); } } // Add material for this mesh - AddMaterial(lodLevel, Material::Create(GetName())); + AddMaterial(static_cast(lodLevel), Material::Create(GetName())); } } @@ -2920,7 +2920,7 @@ namespace EMotionFX const AZ::Data::Asset& lodAsset = lodAssets[lodLevel]; const AZStd::array_view& sourceMeshes = lodAsset->GetMeshes(); - MorphSetup* morphSetup = mMorphSetups[lodLevel]; + MorphSetup* morphSetup = mMorphSetups[static_cast(lodLevel)]; if (!morphSetup) { continue; @@ -3030,7 +3030,7 @@ namespace EMotionFX } // Sync the deformer passes with the morph target deform datas. - morphTargetDeformer->Reinitialize(this, meshJoint, lodLevel); + morphTargetDeformer->Reinitialize(this, meshJoint, static_cast(lodLevel)); } } } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/DualQuatSkinDeformer.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/DualQuatSkinDeformer.cpp index 8c28a84698..2daaac6a85 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/DualQuatSkinDeformer.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/DualQuatSkinDeformer.cpp @@ -327,7 +327,7 @@ namespace EMotionFX AZ::Outcome boneIndexOutcome = FindLocalBoneIndex(influence->GetNodeNr()); if (boneIndexOutcome.IsSuccess()) { - influence->SetBoneNr(boneIndexOutcome.GetValue()); + influence->SetBoneNr(static_cast(boneIndexOutcome.GetValue())); } else { diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp index 7e7a9ae1c2..3cec3b599c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp @@ -1469,7 +1469,7 @@ namespace EMotionFX } // create the new group inside the actor - NodeGroup* newGroup = NodeGroup::Create(groupName, fileGroup.mNumNodes, fileGroup.mDisabledOnDefault ? false : true); + NodeGroup* newGroup = aznew NodeGroup(groupName, fileGroup.mNumNodes, fileGroup.mDisabledOnDefault ? false : true); // read the node numbers uint16 nodeIndex; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/KeyTrackLinearDynamic.inl b/Gems/EMotionFX/Code/EMotionFX/Source/KeyTrackLinearDynamic.inl index 5d06291a92..b28c9973fc 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/KeyTrackLinearDynamic.inl +++ b/Gems/EMotionFX/Code/EMotionFX/Source/KeyTrackLinearDynamic.inl @@ -170,7 +170,7 @@ MCORE_INLINE void KeyTrackLinearDynamic::AddKey(float t template MCORE_INLINE uint32 KeyTrackLinearDynamic::FindKeyNumber(float curTime) const { - return KeyFrameFinder::FindKey(curTime, &mKeys.front(), mKeys.size()); + return KeyFrameFinder::FindKey(curTime, &mKeys.front(), static_cast(mKeys.size())); } @@ -355,7 +355,7 @@ void KeyTrackLinearDynamic::AddKeySorted(float time, co { if (mKeys.capacity() == mKeys.size()) { - const uint32 numToReserve = mKeys.size() / 4; + const uint32 numToReserve = static_cast(mKeys.size() / 4); mKeys.reserve(mKeys.capacity() + numToReserve); } } @@ -385,7 +385,7 @@ void KeyTrackLinearDynamic::AddKeySorted(float time, co } // quickly find the location to insert, and insert it - const uint32 place = KeyFrameFinder::FindKey(keyTime, &mKeys.front(), mKeys.size()); + const uint32 place = KeyFrameFinder::FindKey(keyTime, &mKeys.front(), static_cast(mKeys.size())); mKeys.insert(mKeys.begin() + place + 1, KeyFrame(time, value)); } diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Mesh.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Mesh.cpp index 51486c39b5..993426f4c4 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Mesh.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Mesh.cpp @@ -266,7 +266,7 @@ namespace EMotionFX { // Atom stores the skin indices as uint16, but the buffer itself is a buffer of uint32 with two id's per element size_t influenceCount = elementCountInBytes / sizeof(AZ::u16); - maxSkinInfluences = influenceCount / modelVertexCount; + maxSkinInfluences = static_cast(influenceCount / modelVertexCount); AZ_Assert(maxSkinInfluences > 0 && maxSkinInfluences < 100, "Expect max skin influences in a reasonable value range."); AZ_Assert(influenceCount % modelVertexCount == 0, "Expect an equal number of influences for each vertex."); AZ_Assert(bufferAssetViewDescriptor.m_elementSize == 4, "Expect skin joint indices to be stored in a raw 32-bit per element buffer"); @@ -279,7 +279,7 @@ namespace EMotionFX { // Atom stores joint weights as float (range 0 - 1) size_t influenceCount = elementCountInBytes / sizeof(float); - maxSkinInfluences = influenceCount / modelVertexCount; + maxSkinInfluences = static_cast(influenceCount / modelVertexCount); AZ_Assert(maxSkinInfluences > 0 && maxSkinInfluences < 100, "Expect max skin influences in a reasonable value range."); skinWeights = static_cast(bufferData) + bufferAssetViewDescriptor.m_elementOffset; } @@ -290,7 +290,7 @@ namespace EMotionFX AZ::u32* originalVertexDataRaw = static_cast(originalVertexData->GetData()); for (size_t i = 0; i < modelVertexCount; ++i) { - originalVertexDataRaw[i] = i; + originalVertexDataRaw[i] = static_cast(i); } mesh->AddVertexAttributeLayer(originalVertexData); diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp index d73926a166..e22ad5f064 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.cpp @@ -17,63 +17,16 @@ namespace EMotionFX AZ_CLASS_ALLOCATOR_IMPL(NodeGroup, NodeAllocator, 0) - // default constructor - NodeGroup::NodeGroup() - : BaseObject() + NodeGroup::NodeGroup(const AZStd::string& groupName, uint16 numNodes, bool enabledOnDefault) + : mName(groupName) + , mNodes(numNodes) + , mEnabledOnDefault(enabledOnDefault) { - SetIsEnabledOnDefault(true); - } - - - // extended constructor - NodeGroup::NodeGroup(const char* groupName, bool enabledOnDefault) - : BaseObject() - { - SetName(groupName); - SetIsEnabledOnDefault(enabledOnDefault); - } - - - // another extended constructor - NodeGroup::NodeGroup(const char* groupName, uint16 numNodes, bool enabledOnDefault) - : BaseObject() - { - SetName(groupName); - SetNumNodes(numNodes); - SetIsEnabledOnDefault(enabledOnDefault); - } - - - // destructor - NodeGroup::~NodeGroup() - { - mNodes.Clear(); - } - - - // create - NodeGroup* NodeGroup::Create() - { - return aznew NodeGroup(); - } - - - // create - NodeGroup* NodeGroup::Create(const char* groupName, bool enabledOnDefault) - { - return aznew NodeGroup(groupName, enabledOnDefault); - } - - - // create - NodeGroup* NodeGroup::Create(const char* groupName, uint16 numNodes, bool enabledOnDefault) - { - return aznew NodeGroup(groupName, numNodes, enabledOnDefault); } // set the name of the group - void NodeGroup::SetName(const char* groupName) + void NodeGroup::SetName(const AZStd::string& groupName) { mName = groupName; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h index c6dc86273b..dfe876c86a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/NodeGroup.h @@ -30,38 +30,19 @@ namespace EMotionFX * might contain incorrect or even uninitialized data. */ class EMFX_API NodeGroup - : public BaseObject { public: AZ_CLASS_ALLOCATOR_DECL - /** - * The default creation method. - * This does not assign a name and there will be nodes inside this group on default. - * Also the default enabled state is set to true. - */ - static NodeGroup* Create(); - /** - * Extended creation. - * @param groupName The name of the group. Please keep in mind that it is not allowed to have two groups with the same name inside an Actor. - * @param enabledOnDefault Set to true (default) when the nodes inside this group should be enabled on default. - */ - static NodeGroup* Create(const char* groupName, bool enabledOnDefault = true); - - /** - * Another extended constructor. - * @param groupName The name of the group. Please keep in mind that it is not allowed to have two groups with the same name inside an Actor. - * @param numNodes The number of nodes to create inside the group. This will have all uninitialized values for the node indices in the group, so be sure that you - * set them all to some valid node index using the NodeGroup::SetNode(...) method. This method automatically calls the SetNumNodes(...) method. - * @param enabledOnDefault Set to true (default) when the nodes inside this group should be enabled on default. - */ - static NodeGroup* Create(const char* groupName, uint16 numNodes, bool enabledOnDefault = true); + NodeGroup(const AZStd::string& groupName = {}, uint16 numNodes = 0, bool enabledOnDefault = true); + NodeGroup(const NodeGroup& aOther); + NodeGroup& operator=(const NodeGroup& aOther); /** * Set the name of the group. Please keep in mind that group names must be unique inside the Actor objects. So you should not have two or more groups with the same name. * @param groupName The name of the group. */ - void SetName(const char* groupName); + void SetName(const AZStd::string& groupName); /** * Get the name of the group as null terminated character buffer. @@ -172,37 +153,6 @@ namespace EMotionFX */ void SetIsEnabledOnDefault(bool enabledOnDefault); - /** - * The default constructor. - * This does not assign a name and there will be nodes inside this group on default. - * Also the default enabled state is set to true. - */ - NodeGroup(); - - /** - * Extended constructor. - * @param groupName The name of the group. Please keep in mind that it is not allowed to have two groups with the same name inside an Actor. - * @param enabledOnDefault Set to true (default) when the nodes inside this group should be enabled on default. - */ - NodeGroup(const char* groupName, bool enabledOnDefault = true); - - /** - * Another extended constructor. - * @param groupName The name of the group. Please keep in mind that it is not allowed to have two groups with the same name inside an Actor. - * @param numNodes The number of nodes to create inside the group. This will have all uninitialized values for the node indices in the group, so be sure that you - * set them all to some valid node index using the NodeGroup::SetNode(...) method. This method automatically calls the SetNumNodes(...) method. - * @param enabledOnDefault Set to true (default) when the nodes inside this group should be enabled on default. - */ - NodeGroup(const char* groupName, uint16 numNodes, bool enabledOnDefault = true); - - /** - * The destructor. - */ - ~NodeGroup(); - - NodeGroup(const NodeGroup& aOther); - NodeGroup& operator=(const NodeGroup& aOther); - private: AZStd::string mName; /**< The name of the group. */ MCore::SmallArray mNodes; /**< The node index numbers that are inside this group. */ diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/SkinningInfoVertexAttributeLayer.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/SkinningInfoVertexAttributeLayer.cpp index 9c241a6773..3ccfa85ca8 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/SkinningInfoVertexAttributeLayer.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/SkinningInfoVertexAttributeLayer.cpp @@ -317,7 +317,7 @@ namespace EMotionFX // now we have located the skinning information for this vertex, we can see if our bones array // already contains the bone it uses by traversing all influences for this vertex, and checking // if the bone of that influence already is in the array with used bones - const uint32 numInfluences = GetNumInfluences(i); + const uint32 numInfluences = static_cast(GetNumInfluences(i)); for (uint32 a = 0; a < numInfluences; ++a) { EMotionFX::SkinInfluence* influence = GetInfluence(i, a); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp index 9ec28d2e21..8a4a338b6e 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -1208,7 +1209,7 @@ namespace EMStudio MCore::CommandGroup commandGroup("Adjust anim graph node group"); - AZStd::string nodeNames; + AZStd::vector nodeNames; for (const QModelIndex& selectedIndex : selectionList) { // Skip transitions and blend tree connections. @@ -1221,12 +1222,19 @@ namespace EMStudio EMotionFX::AnimGraphNodeGroup* nodeGroup = animGraph->FindNodeGroupForNode(selectedNode); if (nodeGroup) { - const AZStd::string command = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %i -name \"%s\" -nodeNames \"%s\" -nodeAction \"remove\"", animGraph->GetID(), nodeGroup->GetName(), selectedNode->GetName()); - commandGroup.AddCommandString(command); + auto* command = aznew CommandSystem::CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ animGraph->GetID(), + /*name = */ nodeGroup->GetNameString(), + /*visible = */ AZStd::nullopt, + /*newName = */ AZStd::nullopt, + /*nodeNames = */ {{selectedNode->GetNameString()}}, + /*nodeAction = */ CommandSystem::CommandAnimGraphAdjustNodeGroup::NodeAction::Remove + ); + commandGroup.AddCommand(command); } - nodeNames += selectedNode->GetName(); - nodeNames += ";"; + nodeNames.emplace_back(selectedNode->GetName()); } if (!nodeNames.empty()) { @@ -1235,8 +1243,16 @@ namespace EMStudio if (newNodeGroup) { - const AZStd::string command = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %i -name \"%s\" -nodeNames \"%s\" -nodeAction \"add\"", animGraph->GetID(), newNodeGroup->GetName(), nodeNames.c_str()); - commandGroup.AddCommandString(command); + auto* command = aznew CommandSystem::CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ animGraph->GetID(), + /*name = */ newNodeGroup->GetNameString(), + /*visible = */ AZStd::nullopt, + /*newName = */ AZStd::nullopt, + /*nodeNames = */ nodeNames, + /*nodeAction = */ CommandSystem::CommandAnimGraphAdjustNodeGroup::NodeAction::Add + ); + commandGroup.AddCommand(command); } AZStd::string outResult; diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameControllerWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameControllerWindow.cpp index bc8d874547..47bb9660a8 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameControllerWindow.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameControllerWindow.cpp @@ -327,7 +327,7 @@ namespace EMStudio EMotionFX::AnimGraphGameControllerSettings& gameControllerSettings = animGraph->GetGameControllerSettings(); // in case there is no preset yet create a default one - uint32 numPresets = gameControllerSettings.GetNumPresets(); + uint32 numPresets = static_cast(gameControllerSettings.GetNumPresets()); if (numPresets == 0) { EMotionFX::AnimGraphGameControllerSettings::Preset* preset = aznew EMotionFX::AnimGraphGameControllerSettings::Preset("Default"); @@ -374,7 +374,7 @@ namespace EMStudio QLabel* label = new QLabel(labelString.c_str()); label->setToolTip(parameter->GetDescription().c_str()); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - mParameterGridLayout->addWidget(label, parameterIndex, 0); + mParameterGridLayout->addWidget(label, static_cast(parameterIndex), 0); // add the axis combo box to the layout QComboBox* axesComboBox = new QComboBox(); @@ -434,7 +434,7 @@ namespace EMStudio // select the given axis in the combo box or select none if there is no assignment yet or the assigned axis wasn't found on the current game controller axesComboBox->setCurrentIndex(selectedComboItem); - mParameterGridLayout->addWidget(axesComboBox, parameterIndex, 1); + mParameterGridLayout->addWidget(axesComboBox, static_cast(parameterIndex), 1); // add the mode combo box to the layout QComboBox* modeComboBox = new QComboBox(); @@ -447,7 +447,7 @@ namespace EMStudio modeComboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); connect(modeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &GameControllerWindow::OnParameterModeComboBox); modeComboBox->setCurrentIndex(settingsInfo->m_mode); - mParameterGridLayout->addWidget(modeComboBox, parameterIndex, 2); + mParameterGridLayout->addWidget(modeComboBox, static_cast(parameterIndex), 2); // add the invert checkbox to the layout QHBoxLayout* invertCheckBoxLayout = new QHBoxLayout(); @@ -460,7 +460,7 @@ namespace EMStudio connect(invertCheckbox, &QCheckBox::stateChanged, this, &GameControllerWindow::OnInvertCheckBoxChanged); invertCheckbox->setCheckState(settingsInfo->m_invert ? Qt::Checked : Qt::Unchecked); invertCheckBoxLayout->addWidget(invertCheckbox); - mParameterGridLayout->addLayout(invertCheckBoxLayout, parameterIndex, 3); + mParameterGridLayout->addLayout(invertCheckBoxLayout, static_cast(parameterIndex), 3); // add the current value edit field to the layout QLineEdit* valueEdit = new QLineEdit(); @@ -469,7 +469,7 @@ namespace EMStudio valueEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); valueEdit->setMinimumWidth(70); valueEdit->setMaximumWidth(70); - mParameterGridLayout->addWidget(valueEdit, parameterIndex, 4); + mParameterGridLayout->addWidget(valueEdit, static_cast(parameterIndex), 4); // create the parameter info and add it to the array ParameterInfo paramInfo; @@ -1053,7 +1053,7 @@ namespace EMStudio // get the game controller settings from the current anim graph EMotionFX::AnimGraphGameControllerSettings& gameControllerSettings = mAnimGraph->GetGameControllerSettings(); - uint32 presetNumber = gameControllerSettings.GetNumPresets(); + uint32 presetNumber = static_cast(gameControllerSettings.GetNumPresets()); mString = AZStd::string::format("Preset %d", presetNumber); while (gameControllerSettings.FindPresetIndexByName(mString.c_str()) != MCORE_INVALIDINDEX32) { @@ -1123,7 +1123,7 @@ namespace EMStudio // get the currently selected preset uint32 presetIndex = mPresetComboBox->currentIndex(); - uint32 newValueIndex = gameControllerSettings.FindPresetIndexByName(newValue.c_str()); + uint32 newValueIndex = static_cast(gameControllerSettings.FindPresetIndexByName(newValue.c_str())); if (newValueIndex == MCORE_INVALIDINDEX32) { EMotionFX::AnimGraphGameControllerSettings::Preset* preset = gameControllerSettings.GetPreset(presetIndex); @@ -1139,7 +1139,7 @@ namespace EMStudio EMotionFX::AnimGraphGameControllerSettings& gameControllerSettings = mAnimGraph->GetGameControllerSettings(); // check if there already is a preset with the currently entered name - uint32 presetIndex = gameControllerSettings.FindPresetIndexByName(FromQtString(text).c_str()); + uint32 presetIndex = static_cast(gameControllerSettings.FindPresetIndexByName(FromQtString(text).c_str())); if (presetIndex != MCORE_INVALIDINDEX32 && presetIndex != gameControllerSettings.GetActivePresetIndex()) { GetManager()->SetWidgetAsInvalidInput(mPresetNameLineEdit); @@ -1362,7 +1362,7 @@ namespace EMStudio } // find the corresponding attribute - MCore::Attribute* attribute = animGraphInstance->GetParameterValue(parameterIndex); + MCore::Attribute* attribute = animGraphInstance->GetParameterValue(static_cast(parameterIndex)); if (attribute->GetType() == MCore::AttributeFloat::TYPE_ID) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGroupWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGroupWindow.cpp index ecb9a227af..8ab7aa8d72 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGroupWindow.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGroupWindow.cpp @@ -74,11 +74,6 @@ namespace EMStudio mLineEdit->setText(nodeGroup.c_str()); mLineEdit->selectAll(); - // create add the error message - /*mErrorMsg = new QLabel("Error: Duplicate name found"); - mErrorMsg->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); - mErrorMsg->setVisible(false);*/ - // create the button layout QHBoxLayout* buttonLayout = new QHBoxLayout(); mOKButton = new QPushButton("OK"); @@ -139,10 +134,16 @@ namespace EMStudio void NodeGroupRenameWindow::Accepted() { // Execute the command - AZStd::string commandString, outResult; + AZStd::string outResult; const AZStd::string convertedNewName = FromQtString(mLineEdit->text()); - commandString = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %i -name \"%s\" -newName \"%s\"", mAnimGraph->GetID(), mNodeGroup.c_str(), convertedNewName.c_str()); - if (GetCommandManager()->ExecuteCommand(commandString.c_str(), outResult) == false) + auto* command = aznew CommandSystem::CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName), + mAnimGraph->GetID(), + /*name = */ mNodeGroup, + /*visible = */ AZStd::nullopt, + /*newName = */ convertedNewName + ); + if (!GetCommandManager()->ExecuteCommand(command, outResult)) { MCore::LogError(outResult.c_str()); } @@ -167,7 +168,7 @@ namespace EMStudio mAdjustCallback = new CommandAnimGraphAdjustNodeGroupCallback(false); GetCommandManager()->RegisterCommandCallback("AnimGraphAddNodeGroup", mCreateCallback); GetCommandManager()->RegisterCommandCallback("AnimGraphRemoveNodeGroup", mRemoveCallback); - GetCommandManager()->RegisterCommandCallback("AnimGraphAdjustNodeGroup", mAdjustCallback); + GetCommandManager()->RegisterCommandCallback(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName.data(), mAdjustCallback); // add the add button mAddAction = new QAction(MysticQt::GetMysticQt()->FindIcon("Images/Icons/Plus.svg"), tr("Add new node group"), this); @@ -486,13 +487,16 @@ namespace EMStudio bool isVisible = state == Qt::Checked; - // construct the command - AZStd::string commandString; - commandString = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %i -name \"%s\" -isVisible %s", animGraph->GetID(), nodeGroup->GetName(), AZStd::to_string(isVisible).c_str()); + auto* command = aznew CommandSystem::CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ animGraph->GetID(), + /*name = */ nodeGroup->GetNameString(), + /*visible = */ isVisible + ); // execute the command AZStd::string resultString; - if (GetCommandManager()->ExecuteCommand(commandString.c_str(), resultString) == false) + if (GetCommandManager()->ExecuteCommand(command, resultString) == false) { if (resultString.size() > 0) { @@ -519,16 +523,21 @@ namespace EMStudio // get a pointer to the node group EMotionFX::AnimGraphNodeGroup* nodeGroup = animGraph->GetNodeGroup(groupIndex); - // get the color - AZ::Vector4 finalColor = color.GetAsVector4(); - // construct the command - AZStd::string commandString; - commandString = AZStd::string::format("AnimGraphAdjustNodeGroup -animGraphID %i -name \"%s\" -color \"%s\"", animGraph->GetID(), nodeGroup->GetName(), AZStd::to_string(finalColor).c_str()); + auto* command = aznew CommandSystem::CommandAnimGraphAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAnimGraphAdjustNodeGroup::s_commandName), + /*animGraphId = */ animGraph->GetID(), + /*name = */ nodeGroup->GetName(), + /*visible = */ AZStd::nullopt, + /*newName = */ AZStd::nullopt, + /*nodeNames = */ AZStd::nullopt, + /*nodeAction = */ AZStd::nullopt, + /*color = */ color.ToU32() + ); // execute the command AZStd::string resultString; - if (GetCommandManager()->ExecuteCommand(commandString.c_str(), resultString) == false) + if (GetCommandManager()->ExecuteCommand(command, resultString) == false) { if (resultString.size() > 0) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp index 1624b9d9ea..84c281a18f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupManagementWidget.cpp @@ -112,8 +112,13 @@ namespace EMStudio // execute the command AZStd::string outResult; - AZStd::string command = AZStd::string::format("AdjustNodeGroup -actorID %i -name \"%s\" -newName \"%s\"", mActor->GetID(), mNodeGroupName.c_str(), convertedNewName.c_str()); - if (GetCommandManager()->ExecuteCommand(command.c_str(), outResult) == false) + auto* command = aznew CommandSystem::CommandAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAdjustNodeGroup::s_commandName), + /*actorId=*/ mActor->GetID(), + /*name=*/ mNodeGroupName, + /*newName=*/ convertedNewName + ); + if (GetCommandManager()->ExecuteCommand(command, outResult) == false) { AZ_Error("EMotionFX", false, outResult.c_str()); } @@ -362,98 +367,6 @@ namespace EMStudio mSelectedRow = MCORE_INVALIDINDEX32; } } - /*void NodeGroupManagementWidget::UpdateNodeGroupWidget(QTableWidgetItem* current, QTableWidgetItem* previous) - { - MCORE_UNUSED(previous); - - // return if no node group widget is set - if (mNodeGroupWidget == nullptr) - return; - - // set the node group widget to the actual selection - mNodeGroupWidget->SetActor( mActor ); - - if (current) - { - // set the current row - mSelectedRow = current->row(); - - // set the node group - NodeGroup* nodeGroup = mActor->FindNodeGroupByName( FromQtString(mNodeGroupsTable->item(current->row(), 1)->text()).c_str() ); - mNodeGroupWidget->SetNodeGroup( nodeGroup ); - } - else - { - mNodeGroupWidget->SetNodeGroup( nullptr ); - mSelectedRow = MCORE_INVALIDINDEX32; - } - }*/ - - - // called whenever a cell is changed - /*void NodeGroupManagementWidget::NodeGroupNamesChanged(const QString& text) - { - // get the sender widget - QWidget* senderWidget = (QWidget*)sender(); - - // check for duplicates - const int duplicateFound = SearchTableForString( mNodeGroupsTable, text ); - - // mark edit field in red, if entry already exists - if (duplicateFound >= 0) - GetManager()->SetWidgetAsInvalidInput( senderWidget ); - else - senderWidget->setStyleSheet(""); - }*/ - - - // starts editing - /*void NodeGroupManagementWidget::NodeGroupeNameDoubleClicked(QTableWidgetItem* item) - { - // add new line edit for the selected widget - QLineEdit* lineEdit = new QLineEdit( mNodeGroupsTable->item(item->row(), 0)->text() ); - mNodeGroupsTable->setCellWidget( item->row(), 0, lineEdit ); - - // jump into the edit field - lineEdit->selectAll(); - lineEdit->setFocus(); - mNodeGroupsTable->setCurrentCell( item->row(), 0 ); - - // connect slots for edit finishing and text change - connect( lineEdit, SIGNAL(editingFinished()), this, SLOT(NodeGroupNameEditingFinished()) ); - connect( lineEdit, SIGNAL(textChanged(QString)), this, SLOT(NodeGroupNamesChanged(QString)) ); - }*/ - - - // called when editing is finished - /*void NodeGroupManagementWidget::NodeGroupNameEditingFinished() - { - // get the current item - QTableWidgetItem* item = mNodeGroupsTable->currentItem(); - - // get the sender widget - QLineEdit* senderWidget = (QLineEdit*)sender(); - - // return if one of the widgets does not exist - if (item == nullptr || senderWidget == nullptr) - return; - - // call commands for name change if name does not exist yet - if (senderWidget->styleSheet() == "") - { - // call command for adding a new node group - String outResult; - String command; - command.Format( "AdjustNodeGroup -actorID %i -name \"%s\" -newName \"%s\"", mActor->GetID(), FromQtString(item->text()).c_str(), FromQtString(senderWidget->text()).c_str() ); - if (EMStudio::GetCommandManager()->ExecuteCommand( command.c_str(), outResult ) == false) - LogError( outResult.c_str() ); - } - else - { - // delete the line edit - mNodeGroupsTable->setCellWidget(item->row(), item->column(), nullptr); - } - }*/ // function to add a new node group with the specified name @@ -562,16 +475,20 @@ namespace EMStudio if (rowChechbox == senderCheckbox) { nodeGroupName = mNodeGroupsTable->item(i, 1)->text().toUtf8().data(); + break; } } // execute the command AZStd::string outResult; - const AZStd::string command = AZStd::string::format("AdjustNodeGroup -actorID %i -name \"%s\" -enabledOnDefault \"%s\"", - mActor->GetID(), - nodeGroupName.c_str(), - AZStd::to_string(checked).c_str()); - if (EMStudio::GetCommandManager()->ExecuteCommand(command.c_str(), outResult) == false) + auto* command = aznew CommandSystem::CommandAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAdjustNodeGroup::s_commandName), + /*actorId=*/ mActor->GetID(), + /*name=*/ nodeGroupName, + /*newName=*/ AZStd::nullopt, + /*enabledOnDefault=*/ checked + ); + if (EMStudio::GetCommandManager()->ExecuteCommand(command, outResult) == false) { AZ_Error("EMotionFX", false, outResult.c_str()); } diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp index 31d704a1d5..39ee1c4f5b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.cpp @@ -35,7 +35,6 @@ namespace EMStudio mNodeTable = nullptr; mSelectNodesButton = nullptr; mNodeGroup = nullptr; - mNodeAction = ""; // init the widget Init(); @@ -254,11 +253,11 @@ namespace EMStudio QWidget* senderWidget = (QWidget*)sender(); if (senderWidget == mAddNodesButton) { - mNodeAction = "add"; + mNodeAction = CommandSystem::CommandAdjustNodeGroup::NodeAction::Add; } else { - mNodeAction = "select"; + mNodeAction = CommandSystem::CommandAdjustNodeGroup::NodeAction::Replace; } // get the selected actorinstance @@ -293,46 +292,37 @@ namespace EMStudio // remove nodes void NodeGroupWidget::RemoveNodesButtonPressed() { - // generate node list string - AZStd::string nodeList; - uint32 lowestSelectedRow = MCORE_INVALIDINDEX32; - const uint32 numTableRows = mNodeTable->rowCount(); - for (uint32 i = 0; i < numTableRows; ++i) - { - // get the current table item - QTableWidgetItem* item = mNodeTable->item(i, 0); - if (item == nullptr) - { - continue; - } - - // add the item to remove list, if it's selected - if (item->isSelected()) - { - nodeList += AZStd::string::format("%s;", item->text().toUtf8().data()); - if ((uint32)item->row() < lowestSelectedRow) - { - lowestSelectedRow = (uint32)item->row(); - } - } - } - - // stop here if nothing selected - if (nodeList.empty()) + if (mNodeTable->selectedItems().empty()) { return; } - // call command for adjusting disable on default flag + // generate node list string + AZStd::vector nodeList; + int lowestSelectedRow = AZStd::numeric_limits::max(); + for (const QTableWidgetItem* item : mNodeTable->selectedItems()) + { + nodeList.emplace_back(FromQtString(item->text())); + lowestSelectedRow = AZStd::min(lowestSelectedRow, item->row()); + } + AZStd::string outResult; - AZStd::string command = AZStd::string::format("AdjustNodeGroup -actorID %i -name \"%s\" -nodeAction \"remove\" -nodeNames \"%s\"", mActor->GetID(), mNodeGroup->GetName(), nodeList.c_str()); + auto* command = aznew CommandSystem::CommandAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAdjustNodeGroup::s_commandName), + /*actorId=*/ mActor->GetID(), + /*name=*/ mNodeGroup->GetName(), + /*newName=*/ AZStd::nullopt, + /*enabledOnDefault=*/ AZStd::nullopt, + /*nodeNames=*/ AZStd::move(nodeList), + /*nodeAction=*/ CommandSystem::CommandAdjustNodeGroup::NodeAction::Remove + ); if (EMStudio::GetCommandManager()->ExecuteCommand(command, outResult) == false) { AZ_Error("EMotionFX", false, outResult.c_str()); } // selected the next row - if (lowestSelectedRow > ((uint32)mNodeTable->rowCount() - 1)) + if (lowestSelectedRow > (mNodeTable->rowCount() - 1)) { mNodeTable->selectRow(lowestSelectedRow - 1); } @@ -353,19 +343,23 @@ namespace EMStudio } // generate node list string - AZStd::string nodeList; - nodeList.reserve(16448); - const uint32 numSelectedNodes = selectionList.GetLength(); - for (uint32 i = 0; i < numSelectedNodes; ++i) + AZStd::vector nodeList; + const uint32 selectionListSize = selectionList.GetLength(); + for (uint32 i = 0; i < selectionListSize; ++i) { - nodeList += selectionList[i].GetNodeName(); - nodeList += ";"; + nodeList.emplace_back(selectionList[i].GetNodeName()); } - AzFramework::StringFunc::Strip(nodeList, MCore::CharacterConstants::semiColon, true /* case sensitive */, false /* beginning */, true /* ending */); - // call command for adjusting disable on default flag AZStd::string outResult; - AZStd::string command = AZStd::string::format("AdjustNodeGroup -actorID %i -name \"%s\" -nodeAction \"%s\" -nodeNames \"%s\"", mActor->GetID(), mNodeGroup->GetName(), mNodeAction.c_str(), nodeList.c_str()); + auto* command = aznew CommandSystem::CommandAdjustNodeGroup( + GetCommandManager()->FindCommand(CommandSystem::CommandAdjustNodeGroup::s_commandName), + /*actorId=*/ mActor->GetID(), + /*name=*/ mNodeGroup->GetName(), + /*newName=*/ AZStd::nullopt, + /*enabledOnDefault=*/ AZStd::nullopt, + /*nodeNames=*/ AZStd::move(nodeList), + /*nodeAction=*/ mNodeAction + ); if (EMStudio::GetCommandManager()->ExecuteCommand(command, outResult) == false) { AZ_Error("EMotionFX", false, outResult.c_str()); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.h index ebef94b05c..2b4cad06de 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupWidget.h @@ -13,6 +13,7 @@ #include #include "../../../../EMStudioSDK/Source/DockWidgetPlugin.h" #include "../../../../EMStudioSDK/Source/NodeSelectionWindow.h" +#include #endif QT_FORWARD_DECLARE_CLASS(QLineEdit) @@ -58,7 +59,7 @@ namespace EMStudio CommandSystem::SelectionList mNodeSelectionList; EMotionFX::NodeGroup* mNodeGroup; uint16 mNodeGroupIndex; - AZStd::string mNodeAction; + CommandSystem::CommandAdjustNodeGroup::NodeAction mNodeAction; // widgets QTableWidget* mNodeTable; diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupsPlugin.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupsPlugin.cpp index 91a96ef39d..218035dc30 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupsPlugin.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/NodeGroups/NodeGroupsPlugin.cpp @@ -11,6 +11,7 @@ #include "../../../../EMStudioSDK/Source/EMStudioCore.h" #include #include +#include #include "../../../../EMStudioSDK/Source/EMStudioManager.h" // include qt headers @@ -99,7 +100,7 @@ namespace EMStudio GetCommandManager()->RegisterCommandCallback("Select", mSelectCallback); GetCommandManager()->RegisterCommandCallback("Unselect", mUnselectCallback); GetCommandManager()->RegisterCommandCallback("ClearSelection", mClearSelectionCallback); - GetCommandManager()->RegisterCommandCallback("AdjustNodeGroup", mAdjustNodeGroupCallback); + GetCommandManager()->RegisterCommandCallback(CommandSystem::CommandAdjustNodeGroup::s_commandName.data(), mAdjustNodeGroupCallback); GetCommandManager()->RegisterCommandCallback("AddNodeGroup", mAddNodeGroupCallback); GetCommandManager()->RegisterCommandCallback("RemoveNodeGroup", mRemoveNodeGroupCallback); diff --git a/Gems/EMotionFX/Code/MCore/Source/Command.cpp b/Gems/EMotionFX/Code/MCore/Source/Command.cpp index b358a28546..39e9fde965 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Command.cpp +++ b/Gems/EMotionFX/Code/MCore/Source/Command.cpp @@ -28,10 +28,10 @@ namespace MCore // constructor - Command::Command(const char* commandName, Command* originalCommand) + Command::Command(AZStd::string commandName, Command* originalCommand) + : mOrgCommand(originalCommand) + , mCommandName(AZStd::move(commandName)) { - mCommandName = commandName; - mOrgCommand = originalCommand; } diff --git a/Gems/EMotionFX/Code/MCore/Source/Command.h b/Gems/EMotionFX/Code/MCore/Source/Command.h index 6ad10ff559..7309c5dc91 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Command.h +++ b/Gems/EMotionFX/Code/MCore/Source/Command.h @@ -185,7 +185,7 @@ namespace MCore * @param commandName The unique identifier for the command. * @param originalCommand The original command, or nullptr when this is the original command. */ - Command(const char* commandName, Command* originalCommand); + Command(AZStd::string commandName, Command* originalCommand); /** * Destructor. diff --git a/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp b/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp index 8f871d0d42..8fa5850407 100644 --- a/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp +++ b/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp @@ -163,7 +163,7 @@ namespace MysticQt // iterate through the groups and save all actions for them for (const AZStd::unique_ptr& group : m_groups) { - settings->beginGroup(QString::fromUtf8(group->GetName().data(), group->GetName().size())); + settings->beginGroup(QString::fromUtf8(group->GetName().data(), static_cast(group->GetName().size()))); // iterate through the actions and save them for (const AZStd::unique_ptr& action : group->GetActions()) diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphComponent.cpp index ade713efa6..10046728ab 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphComponent.cpp @@ -873,7 +873,7 @@ namespace EMotionFX AZ_Warning("EmotionFX", false, "Invalid anim graph parameter name: %s", parameterName); return; } - SetParameterFloat(parameterIndex.GetValue(), value); + SetParameterFloat(static_cast(parameterIndex.GetValue()), value); } } @@ -888,7 +888,7 @@ namespace EMotionFX AZ_Warning("EmotionFX", false, "Invalid anim graph parameter name: %s", parameterName); return; } - SetParameterBool(parameterIndex.GetValue(), value); + SetParameterBool(static_cast(parameterIndex.GetValue()), value); } } @@ -903,7 +903,7 @@ namespace EMotionFX AZ_Warning("EmotionFX", false, "Invalid anim graph parameter name: %s", parameterName); return; } - SetParameterString(parameterIndex.GetValue(), value); + SetParameterString(static_cast(parameterIndex.GetValue()), value); } } @@ -918,7 +918,7 @@ namespace EMotionFX AZ_Warning("EmotionFX", false, "Invalid anim graph parameter name: %s", parameterName); return; } - SetParameterVector2(parameterIndex.GetValue(), value); + SetParameterVector2(static_cast(parameterIndex.GetValue()), value); } } @@ -933,7 +933,7 @@ namespace EMotionFX AZ_Warning("EmotionFX", false, "Invalid anim graph parameter name: %s", parameterName); return; } - SetParameterVector3(parameterIndex.GetValue(), value); + SetParameterVector3(static_cast(parameterIndex.GetValue()), value); } } @@ -948,7 +948,7 @@ namespace EMotionFX AZ_Warning("EmotionFX", false, "Invalid anim graph parameter name: %s", parameterName); return; } - SetParameterRotationEuler(parameterIndex.GetValue(), value); + SetParameterRotationEuler(static_cast(parameterIndex.GetValue()), value); } } @@ -963,7 +963,7 @@ namespace EMotionFX AZ_Warning("EmotionFX", false, "Invalid anim graph parameter name: %s", parameterName); return; } - SetParameterRotation(parameterIndex.GetValue(), value); + SetParameterRotation(static_cast(parameterIndex.GetValue()), value); } } @@ -1119,7 +1119,7 @@ namespace EMotionFX const AZ::Outcome parameterIndex = m_animGraphInstance->FindParameterIndex(parameterName); if (parameterIndex.IsSuccess()) { - return GetParameterFloat(parameterIndex.GetValue()); + return GetParameterFloat(static_cast(parameterIndex.GetValue())); } } return 0.f; @@ -1133,7 +1133,7 @@ namespace EMotionFX const AZ::Outcome parameterIndex = m_animGraphInstance->FindParameterIndex(parameterName); if (parameterIndex.IsSuccess()) { - return GetParameterBool(parameterIndex.GetValue()); + return GetParameterBool(static_cast(parameterIndex.GetValue())); } } return false; @@ -1147,7 +1147,7 @@ namespace EMotionFX const AZ::Outcome parameterIndex = m_animGraphInstance->FindParameterIndex(parameterName); if (parameterIndex.IsSuccess()) { - return GetParameterString(parameterIndex.GetValue()); + return GetParameterString(static_cast(parameterIndex.GetValue())); } } return AZStd::string(); @@ -1161,7 +1161,7 @@ namespace EMotionFX const AZ::Outcome parameterIndex = m_animGraphInstance->FindParameterIndex(parameterName); if (parameterIndex.IsSuccess()) { - return GetParameterVector2(parameterIndex.GetValue()); + return GetParameterVector2(static_cast(parameterIndex.GetValue())); } } return AZ::Vector2::CreateZero(); @@ -1175,7 +1175,7 @@ namespace EMotionFX const AZ::Outcome parameterIndex = m_animGraphInstance->FindParameterIndex(parameterName); if (parameterIndex.IsSuccess()) { - return GetParameterVector3(parameterIndex.GetValue()); + return GetParameterVector3(static_cast(parameterIndex.GetValue())); } } return AZ::Vector3::CreateZero(); @@ -1189,7 +1189,7 @@ namespace EMotionFX const AZ::Outcome parameterIndex = m_animGraphInstance->FindParameterIndex(parameterName); if (parameterIndex.IsSuccess()) { - return GetParameterRotationEuler(parameterIndex.GetValue()); + return GetParameterRotationEuler(static_cast(parameterIndex.GetValue())); } } return AZ::Vector3::CreateZero(); @@ -1203,7 +1203,7 @@ namespace EMotionFX const AZ::Outcome parameterIndex = m_animGraphInstance->FindParameterIndex(parameterName); if (parameterIndex.IsSuccess()) { - return GetParameterRotation(parameterIndex.GetValue()); + return GetParameterRotation(static_cast(parameterIndex.GetValue())); } } return AZ::Quaternion::CreateIdentity(); diff --git a/Gems/EMotionFX/Code/Tests/AnimGraphNodeEventFilterTests.cpp b/Gems/EMotionFX/Code/Tests/AnimGraphNodeEventFilterTests.cpp index ed44be78a7..67f6fa860e 100644 --- a/Gems/EMotionFX/Code/Tests/AnimGraphNodeEventFilterTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AnimGraphNodeEventFilterTests.cpp @@ -86,7 +86,7 @@ namespace EMotionFX AnimGraphMotionNode* motionNode = aznew AnimGraphMotionNode(); motionNode->SetName(AZStd::string::format("MotionNode%zu", i).c_str()); m_blendTree->AddChildNode(motionNode); - m_blend2Node->AddConnection(motionNode, AnimGraphMotionNode::PORTID_OUTPUT_POSE, i); + m_blend2Node->AddConnection(motionNode, AnimGraphMotionNode::PORTID_OUTPUT_POSE, static_cast(i)); m_motionNodes.push_back(motionNode); } diff --git a/Gems/EMotionFX/Code/Tests/AnimGraphNodeProcessingTests.cpp b/Gems/EMotionFX/Code/Tests/AnimGraphNodeProcessingTests.cpp index a185b4a452..4a85d452a3 100644 --- a/Gems/EMotionFX/Code/Tests/AnimGraphNodeProcessingTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AnimGraphNodeProcessingTests.cpp @@ -69,7 +69,7 @@ namespace EMotionFX AnimGraphMotionNode* motionNode = aznew AnimGraphMotionNode(); motionNode->SetName(AZStd::string::format("MotionNode%zu", i).c_str()); m_blendTree->AddChildNode(motionNode); - m_blendNNode->AddConnection(motionNode, AnimGraphMotionNode::PORTID_OUTPUT_POSE, i); + m_blendNNode->AddConnection(motionNode, AnimGraphMotionNode::PORTID_OUTPUT_POSE, static_cast(i)); m_motionNodes.push_back(motionNode); } m_blendNNode->UpdateParamWeights(); diff --git a/Gems/EMotionFX/Code/Tests/AnimGraphReferenceNodeTests.cpp b/Gems/EMotionFX/Code/Tests/AnimGraphReferenceNodeTests.cpp index 57e8a6a90d..2c595c8b6c 100644 --- a/Gems/EMotionFX/Code/Tests/AnimGraphReferenceNodeTests.cpp +++ b/Gems/EMotionFX/Code/Tests/AnimGraphReferenceNodeTests.cpp @@ -260,7 +260,7 @@ namespace EMotionFX GetEMotionFX().Update(0.0f); EXPECT_EQ(Transform::CreateIdentity(), GetOutputTransform()); - static_cast(m_animGraphInstance->GetParameterValue(m_animGraph->FindParameterIndex(m_parameter).GetValue()))->SetValue(1.0f); + static_cast(m_animGraphInstance->GetParameterValue(static_cast(m_animGraph->FindParameterIndex(m_parameter).GetValue())))->SetValue(1.0f); GetEMotionFX().Update(0.0f); EXPECT_EQ(Transform::CreateIdentity() * AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 0.0f, 0.0f)), GetOutputTransform()); @@ -313,7 +313,7 @@ namespace EMotionFX // Changing this one parameter value should change it through all 3 // layers of reference nodes, down to the referenced Transform node - static_cast(m_animGraphInstance->GetParameterValue(m_animGraph->FindParameterIndex(m_topLevelParameter).GetValue()))->SetValue(1.0f); + static_cast(m_animGraphInstance->GetParameterValue(static_cast(m_animGraph->FindParameterIndex(m_topLevelParameter).GetValue())))->SetValue(1.0f); GetEMotionFX().Update(0.0f); EXPECT_EQ(Transform::CreateIdentity() * AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 0.0f, 0.0f)), GetOutputTransform()); diff --git a/Gems/EMotionFX/Code/Tests/Editor/ParametersGroupDefaultValues.cpp b/Gems/EMotionFX/Code/Tests/Editor/ParametersGroupDefaultValues.cpp index 7b7bf011a9..4219966d72 100644 --- a/Gems/EMotionFX/Code/Tests/Editor/ParametersGroupDefaultValues.cpp +++ b/Gems/EMotionFX/Code/Tests/Editor/ParametersGroupDefaultValues.cpp @@ -153,7 +153,7 @@ namespace EMotionFX TestInequality(defaultValueParameter->GetDefaultValue(), expectedValue); AnimGraphInstance* animGraphInstance = animGraph->GetAnimGraphInstance(0); - auto instanceValue = static_cast(animGraphInstance->GetParameterValue(animGraph->FindValueParameterIndex(valueParameter).GetValue())); + auto instanceValue = static_cast(animGraphInstance->GetParameterValue(static_cast(animGraph->FindValueParameterIndex(valueParameter).GetValue()))); ASSERT_EQ(instanceValue->GetType(), AttributeT::TYPE_ID); // Set the parameter's current value diff --git a/Gems/EMotionFX/Code/Tests/UI/CanAddMotionToMotionSet.cpp b/Gems/EMotionFX/Code/Tests/UI/CanAddMotionToMotionSet.cpp index a568431931..0e20d220d4 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanAddMotionToMotionSet.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanAddMotionToMotionSet.cpp @@ -56,7 +56,7 @@ namespace EMotionFX motionSetPlugin->SetSelectedSet(motionSet); // It should be empty at the moment. - int numMotions = motionSet->GetNumMotionEntries(); + int numMotions = static_cast(motionSet->GetNumMotionEntries()); EXPECT_EQ(numMotions, 0); // Find the action to add a motion to the set and press it. @@ -65,7 +65,7 @@ namespace EMotionFX QTest::mouseClick(addMotionButton, Qt::LeftButton); // There should now be a motion. - int numMotionsAfterCreate = motionSet->GetNumMotionEntries(); + int numMotionsAfterCreate = static_cast(motionSet->GetNumMotionEntries()); ASSERT_EQ(numMotionsAfterCreate, 1); AZStd::unordered_map motions = motionSet->GetMotionEntries(); diff --git a/Gems/EMotionFX/Code/Tests/UI/CanEditParameters.cpp b/Gems/EMotionFX/Code/Tests/UI/CanEditParameters.cpp index e1ea78083a..82f509965c 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanEditParameters.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanEditParameters.cpp @@ -74,7 +74,7 @@ namespace EMotionFX QTest::mouseClick(createButton, Qt::LeftButton); // Check we only have the one Parameter - int numParameters = newGraph->GetNumParameters(); + int numParameters = static_cast(newGraph->GetNumParameters()); EXPECT_EQ(numParameters, 1) << "Not just 1 parameter"; const RangedValueParameter* parameter = reinterpret_cast* >(newGraph->FindValueParameter(0)); diff --git a/Gems/EMotionFX/Code/Tests/UI/CanRemoveMotionFromMotionSet.cpp b/Gems/EMotionFX/Code/Tests/UI/CanRemoveMotionFromMotionSet.cpp index 8a13f35fbf..c6bec666b1 100644 --- a/Gems/EMotionFX/Code/Tests/UI/CanRemoveMotionFromMotionSet.cpp +++ b/Gems/EMotionFX/Code/Tests/UI/CanRemoveMotionFromMotionSet.cpp @@ -59,7 +59,7 @@ namespace EMotionFX motionSetPlugin->SetSelectedSet(motionSet); // It should be empty at the moment. - const int numMotions = motionSet->GetNumMotionEntries(); + const int numMotions = static_cast(motionSet->GetNumMotionEntries()); EXPECT_EQ(numMotions, 0); // Find the action to add a motion to the set and press it. @@ -68,7 +68,7 @@ namespace EMotionFX QTest::mouseClick(addMotionButton, Qt::LeftButton); // There should now be a motion. - const int numMotionsAfterCreate = motionSet->GetNumMotionEntries(); + const int numMotionsAfterCreate = static_cast(motionSet->GetNumMotionEntries()); ASSERT_EQ(numMotionsAfterCreate, 1); AZStd::unordered_map motions = motionSet->GetMotionEntries(); @@ -140,7 +140,7 @@ namespace EMotionFX motionSetPlugin->SetSelectedSet(motionSet); // It should be empty at the moment. - const int numMotions = motionSet->GetNumMotionEntries(); + const int numMotions = static_cast(motionSet->GetNumMotionEntries()); EXPECT_EQ(numMotions, 0); // Find the action to add a motion to the set and press it twice. @@ -150,7 +150,7 @@ namespace EMotionFX QTest::mouseClick(addMotionButton, Qt::LeftButton); // There should now be two motion. - const int numMotionsAfterCreate = motionSet->GetNumMotionEntries(); + const int numMotionsAfterCreate = static_cast(motionSet->GetNumMotionEntries()); ASSERT_EQ(numMotionsAfterCreate, 2); AZStd::unordered_map motions = motionSet->GetMotionEntries(); diff --git a/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStateMainMenu.inl b/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStateMainMenu.inl index 919b8c9449..41ee034844 100644 --- a/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStateMainMenu.inl +++ b/Gems/GameStateSamples/Code/Include/GameStateSamples/GameStateMainMenu.inl @@ -300,7 +300,7 @@ namespace GameStateSamples // Add all the levels into the UI as buttons - UiDynamicLayoutBus::Event(dynamicLayoutElementId, &UiDynamicLayoutInterface::SetNumChildElements, levelNames.size()); + UiDynamicLayoutBus::Event(dynamicLayoutElementId, &UiDynamicLayoutInterface::SetNumChildElements, static_cast(levelNames.size())); for (int i = 0; i < levelNames.size(); ++i) { AZ::IO::PathView level(levelNames[i].c_str()); @@ -334,7 +334,7 @@ namespace GameStateSamples { // Get the level name (strip folder names from the path) const char* levelPath = levelSystem->GetLevelInfo(i)->GetName(); - const int levelPathLength = strlen(levelPath); + const int levelPathLength = static_cast(strlen(levelPath)); const char* levelName = levelPath; for (int j = 0; j < levelPathLength; ++j) { diff --git a/Gems/GradientSignal/Code/Source/GradientImageConversion.cpp b/Gems/GradientSignal/Code/Source/GradientImageConversion.cpp index 4ed3ff1718..fdb3d77674 100644 --- a/Gems/GradientSignal/Code/Source/GradientImageConversion.cpp +++ b/Gems/GradientSignal/Code/Source/GradientImageConversion.cpp @@ -259,7 +259,7 @@ namespace for (AZStd::size_t i = 0; i < channels; ++i) { min = AZStd::min(min, Lerp(min, - arr[i], IsActive(i, mask))); + arr[i], IsActive(static_cast(i), mask))); } return min; @@ -273,7 +273,7 @@ namespace for (AZStd::size_t i = 0; i < channels; ++i) { max = AZStd::max(max, Lerp(max, - arr[i], IsActive(i, mask))); + arr[i], IsActive(static_cast(i), mask))); } return max; @@ -287,7 +287,7 @@ namespace for (AZStd::size_t i = 0; i < channels; ++i) { - AZ::u8 result = IsActive(i, mask); + AZ::u8 result = IsActive(static_cast(i), mask); total += result * arr[i]; active += result; } @@ -493,7 +493,7 @@ namespace GradientSignal newAsset->m_imageFormat = OperationHelper(settings.m_rgbTransform, newAsset->m_imageFormat, mask, settings.m_alphaTransform, newAsset->m_imageData); newAsset->m_imageFormat = ConvertBufferType(newAsset->m_imageData, newAsset->m_imageFormat, ExportFormatToPixelFormat(settings.m_format), settings.m_autoScale, AZStd::make_pair(settings.m_scaleRangeMin, settings.m_scaleRangeMax)); - newAsset->m_bytesPerPixel = newAsset->m_imageData.size() / aznumeric_cast(newAsset->m_imageWidth * newAsset->m_imageHeight); + newAsset->m_bytesPerPixel = static_cast(newAsset->m_imageData.size() / aznumeric_cast(newAsset->m_imageWidth * newAsset->m_imageHeight)); return newAsset; } diff --git a/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp b/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp index 54ca51f579..c5b003bf3c 100644 --- a/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp +++ b/Gems/GradientSignal/Code/Tests/ImageAssetTests.cpp @@ -40,7 +40,7 @@ namespace asset.m_imageWidth = dimensions; asset.m_imageHeight = dimensions; - asset.m_bytesPerPixel = bytesPerPixel; + asset.m_bytesPerPixel = static_cast(bytesPerPixel); asset.m_imageFormat = format; asset.m_imageData.resize(asset.m_bytesPerPixel * asset.m_imageWidth * asset.m_imageHeight); diff --git a/Gems/ImGui/Code/Include/LYImGuiUtils/HistogramContainer.h b/Gems/ImGui/Code/Include/LYImGuiUtils/HistogramContainer.h index 630825035e..101b123bb5 100644 --- a/Gems/ImGui/Code/Include/LYImGuiUtils/HistogramContainer.h +++ b/Gems/ImGui/Code/Include/LYImGuiUtils/HistogramContainer.h @@ -45,7 +45,7 @@ namespace ImGui , bool autoExpandScale, bool startCollapsed = false, bool drawMostRecentValue = true); // How many values are in the container currently - int GetSize() { return m_values.size(); } + int GetSize() { return static_cast(m_values.size()); } // What is the max size of the container int GetMaxSize() { return m_maxSize; } @@ -57,7 +57,7 @@ namespace ImGui void PushValue(float val); // Get the last value pushed - float GetLastValue() { return GetValue(m_values.size() - 1); } + float GetLastValue() { return GetValue(static_cast(m_values.size() - 1)); } // Get a Values at a particular index float GetValue(int index) { return index < m_values.size() ? m_values.at(index) : 0.0f; } diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp index 39778d241b..8e0e23652c 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYEntityOutliner.cpp @@ -940,7 +940,7 @@ namespace ImGui rootSliceComponent->GetEntityIds(entityIds); // Save off our count for use later. - m_totalEntitiesFound = entityIds.size(); + m_totalEntitiesFound = static_cast(entityIds.size()); // Clear the entityId to InfoNodePtr Map. m_entityIdToInfoNodePtrMap.clear(); diff --git a/Gems/InAppPurchases/Code/Source/InAppPurchasesSystemComponent.cpp b/Gems/InAppPurchases/Code/Source/InAppPurchasesSystemComponent.cpp index fd1f4146dc..824208e918 100644 --- a/Gems/InAppPurchases/Code/Source/InAppPurchasesSystemComponent.cpp +++ b/Gems/InAppPurchases/Code/Source/InAppPurchasesSystemComponent.cpp @@ -329,7 +329,7 @@ namespace InAppPurchases { if (m_productInfoIndex < 0) { - m_productInfoIndex = productDetails->size() - 1; + m_productInfoIndex = static_cast(productDetails->size() - 1); } if (productDetails->size() > 0) @@ -375,7 +375,7 @@ namespace InAppPurchases { if (m_purchasedProductInfoIndex < 0) { - m_purchasedProductInfoIndex = purchasedProductDetails->size() - 1; + m_purchasedProductInfoIndex = static_cast(purchasedProductDetails->size() - 1); } if (purchasedProductDetails->size() > 0) diff --git a/Gems/LmbrCentral/Code/Source/Shape/TubeShape.cpp b/Gems/LmbrCentral/Code/Source/Shape/TubeShape.cpp index 2c6ce3dc72..68198c491a 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/TubeShape.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/TubeShape.cpp @@ -355,7 +355,7 @@ namespace LmbrCentral return; } - const AZ::u32 segments = segmentCount * spline->GetSegmentGranularity() + segmentCount - 1; + const AZ::u32 segments = static_cast(segmentCount * spline->GetSegmentGranularity() + segmentCount - 1); const AZ::u32 totalSegments = segments + capSegments * 2; const AZ::u32 capSegmentTipVerts = capSegments > 0 ? 2 : 0; const size_t numVerts = sides * (totalSegments + 1) + capSegmentTipVerts; @@ -401,7 +401,7 @@ namespace LmbrCentral // 2 verts for each segment // loops == sides // 2 loops per segment - const AZ::u32 segments = segmentCount * spline->GetSegmentGranularity(); + const AZ::u32 segments = static_cast(segmentCount * spline->GetSegmentGranularity()); const AZ::u32 totalEndSegments = capSegments * 2 * 2 * 2 * 2; const AZ::u32 totalSegments = segments * 2 * 2 * 2; const AZ::u32 totalLoops = 2 * sides * segments * 2; @@ -594,7 +594,7 @@ namespace LmbrCentral // to ensure the total radius stays positive if (GetTotalRadius(AZ::SplineAddress(vertIndex)) < 0.0f) { - SetVariableRadius(vertIndex, -GetRadius()); + SetVariableRadius(static_cast(vertIndex), -GetRadius()); } } diff --git a/Gems/LmbrCentral/Code/Tests/TubeShapeTest.cpp b/Gems/LmbrCentral/Code/Tests/TubeShapeTest.cpp index 3deb12fad0..86c7ce23e5 100644 --- a/Gems/LmbrCentral/Code/Tests/TubeShapeTest.cpp +++ b/Gems/LmbrCentral/Code/Tests/TubeShapeTest.cpp @@ -406,7 +406,7 @@ namespace UnitTest float variableRadius = 0.0f; LmbrCentral::TubeShapeComponentRequestsBus::EventResult( variableRadius, entity.GetId(), &LmbrCentral::TubeShapeComponentRequestsBus::Events::GetVariableRadius, - vertIndex); + static_cast(vertIndex)); EXPECT_THAT(totalRadius, FloatEq(radiis.first)); EXPECT_THAT(variableRadius, FloatEq(radiis.second)); diff --git a/Gems/LyShine/Assets/Passes/LyShineParent.pass b/Gems/LyShine/Assets/Passes/LyShineParent.pass new file mode 100644 index 0000000000..7bbd4748a7 --- /dev/null +++ b/Gems/LyShine/Assets/Passes/LyShineParent.pass @@ -0,0 +1,22 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "PassAsset", + "ClassData": { + "PassTemplate": { + "Name": "LyShineParentTemplate", + "PassClass": "LyShinePass", + "Slots": [ + { + "Name": "ColorInputOutput", + "SlotType": "InputOutput" + }, + { + "Name": "DepthInputOutput", + "SlotType": "InputOutput", + "ScopeAttachmentUsage": "DepthStencil" + } + ] + } + } +} diff --git a/Gems/LyShine/Assets/Passes/LyShinePassTemplates.azasset b/Gems/LyShine/Assets/Passes/LyShinePassTemplates.azasset new file mode 100644 index 0000000000..c9ee5186e0 --- /dev/null +++ b/Gems/LyShine/Assets/Passes/LyShinePassTemplates.azasset @@ -0,0 +1,13 @@ +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "AssetAliasesSourceData", + "ClassData": { + "AssetPaths": [ + { + "Name": "LyShineParentTemplate", + "Path": "Passes/LyShineParent.pass" + } + ] + } +} diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index 171927c4a3..93bf84c66e 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -193,6 +193,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) FILES_CMAKE lyshine_common_module_files.cmake lyshine_tests_files.cmake + COMPILE_DEFINITIONS + PRIVATE + LYSHINE_TESTS INCLUDE_DIRECTORIES PRIVATE Tests diff --git a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp index 746ea04559..cf5c1b2d8f 100644 --- a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp +++ b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.cpp @@ -1402,7 +1402,7 @@ void SplineWidget::mouseMoveEvent(QMouseEvent* event) QString tipText; bool boFoundTheSelectedKey(false); - for (int splineIndex = 0, endSpline = m_splines.size(); splineIndex < endSpline; ++splineIndex) + for (int splineIndex = 0, endSpline = static_cast(m_splines.size()); splineIndex < endSpline; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; for (int i = 0; i < pSpline->GetKeyCount(); i++) @@ -1619,7 +1619,7 @@ bool AbstractSplineWidget::IsKeySelected(ISplineInterpolator* pSpline, int nKey, int AbstractSplineWidget::GetNumSelected() { int nSelected = 0; - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { if (ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline) { @@ -1726,7 +1726,7 @@ AbstractSplineWidget::EHitCode AbstractSplineWidget::HitTest(const QPoint& point } // For each Spline... - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; ISplineInterpolator* pDetailSpline = m_splines[splineIndex].pDetailSpline; @@ -1867,7 +1867,7 @@ void AbstractSplineWidget::ScaleAmplitudeKeys(float time, float startValue, floa m_nHitKeyIndex = -1; m_nHitDimension = -1; - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -1971,7 +1971,7 @@ void AbstractSplineWidget::TimeScaleKeys(float time, float startTime, float endT float affectedRangeMin = FLT_MAX; float affectedRangeMax = -FLT_MAX; - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -2078,7 +2078,7 @@ void AbstractSplineWidget::ValueScaleKeys(float startValue, float endValue) m_nHitKeyIndex = -1; m_nHitDimension = -1; - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -2119,7 +2119,7 @@ void AbstractSplineWidget::MoveSelectedKeys(Vec2 offset, bool copyKeys) float affectedRangeMin = FLT_MAX; float affectedRangeMax = -FLT_MAX; // For each spline... - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -2241,7 +2241,7 @@ void AbstractSplineWidget::RemoveSelectedKeys() m_pHitDetailSpline = 0; m_nHitKeyIndex = -1; - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -2281,7 +2281,7 @@ void AbstractSplineWidget::RemoveSelectedKeyTimesImpl() StoreUndo(); SendNotifyEvent(SPLN_BEFORE_CHANGE); - for (int splineIndex = 0, end = m_splines.size(); splineIndex < end; ++splineIndex) + for (int splineIndex = 0, end = static_cast(m_splines.size()); splineIndex < end; ++splineIndex) { std::vector::iterator itTime = m_keyTimes.begin(), endTime = m_keyTimes.end(); for (int keyIndex = 0, endIndex = m_splines[splineIndex].pSpline->GetKeyCount(); keyIndex < endIndex; ) @@ -2319,7 +2319,7 @@ void AbstractSplineWidget::RedrawWindowAroundMarker() { UpdateKeyTimes(); std::vector::iterator itKeyTime = std::lower_bound(m_keyTimes.begin(), m_keyTimes.end(), KeyTime(m_fTimeMarker, 0)); - int keyTimeIndex = (itKeyTime != m_keyTimes.end() ? itKeyTime - m_keyTimes.begin() : m_keyTimes.size()); + int keyTimeIndex = static_cast(itKeyTime != m_keyTimes.end() ? itKeyTime - m_keyTimes.begin() : m_keyTimes.size()); int redrawRangeStart = (keyTimeIndex >= 2 ? aznumeric_cast(TimeToXOfs(m_keyTimes[keyTimeIndex - 2].time)) : m_rcSpline.left()); int redrawRangeEnd = (keyTimeIndex < int(m_keyTimes.size()) - 2 ? aznumeric_cast(TimeToXOfs(m_keyTimes[keyTimeIndex + 2].time)) : m_rcSpline.right()); @@ -2421,7 +2421,7 @@ void AbstractSplineWidget::ClearSelection() { ConditionalStoreUndo(); - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -2465,7 +2465,7 @@ void AbstractSplineWidget::StoreUndo() if (UiAnimUndo::IsRecording() && !m_pCurrentUndo) { std::vector splines(m_splines.size()); - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { splines[splineIndex] = m_splines[splineIndex].pSpline; } @@ -2508,7 +2508,7 @@ void AbstractSplineWidget::DuplicateSelectedKeys() typedef std::vector KeysToAddContainer; KeysToAddContainer keysToInsert; - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -2608,7 +2608,7 @@ void AbstractSplineWidget::KeyAll() ////////////////////////////////////////////////////////////////////////// void AbstractSplineWidget::SelectAll() { - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -2756,7 +2756,7 @@ void AbstractSplineWidget::SelectRectangle(const QRect& rc, bool bSelect) { std::swap(t0, t1); } - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; ISplineInterpolator* pDetailSpline = m_splines[splineIndex].pDetailSpline; @@ -2972,7 +2972,7 @@ void AbstractSplineWidget::ModifySelectedKeysFlags(int nRemoveFlags, int nAddFla SendNotifyEvent(SPLN_BEFORE_CHANGE); - for (int splineIndex = 0, splineCount = m_splines.size(); splineIndex < splineCount; ++splineIndex) + for (int splineIndex = 0, splineCount = static_cast(m_splines.size()); splineIndex < splineCount; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -3138,7 +3138,7 @@ void AbstractSplineWidget::GotoNextKey(bool previousKey) { bool boFoundTheSelectedKey(false); - for (int splineIndex = 0, endSpline = m_splines.size(); splineIndex < endSpline; ++splineIndex) + for (int splineIndex = 0, endSpline = static_cast(m_splines.size()); splineIndex < endSpline; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; for (int i = 0; i < pSpline->GetKeyCount(); i++) @@ -3180,7 +3180,7 @@ void AbstractSplineWidget::GotoNextKey(bool previousKey) } else { - for (int splineIndex = 0, endSpline = m_splines.size(); splineIndex < endSpline; ++splineIndex) + for (int splineIndex = 0, endSpline = static_cast(m_splines.size()); splineIndex < endSpline; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; @@ -3231,7 +3231,7 @@ void AbstractSplineWidget::RemoveAllKeysButThis() { std::vector keys; - for (int splineIndex = 0, endSpline = m_splines.size(); splineIndex < endSpline; ++splineIndex) + for (int splineIndex = 0, endSpline = static_cast(m_splines.size()); splineIndex < endSpline; ++splineIndex) { ISplineInterpolator* pSpline = m_splines[splineIndex].pSpline; diff --git a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h index 2a7b0c3d1f..1bbcf8eea7 100644 --- a/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h +++ b/Gems/LyShine/Code/Editor/Animation/Controls/UiSplineCtrlEx.h @@ -90,7 +90,7 @@ public: void AddSpline(ISplineInterpolator * pSpline, ISplineInterpolator * pDetailSpline, COLORREF anColorArray[4]); void RemoveSpline(ISplineInterpolator* pSpline); void RemoveAllSplines(); - int GetSplineCount() const { return m_splines.size(); } + int GetSplineCount() const { return static_cast(m_splines.size()); } ISplineInterpolator* GetSpline(int nIndex) const { return m_splines[nIndex].pSpline; } void SetTimeMarker(float fTime); diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.h b/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.h index 40d9013392..72dc7344ec 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.h +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.h @@ -27,7 +27,7 @@ namespace AZ class CUiAnimViewAnimNodeBundle { public: - unsigned int GetCount() const { return m_animNodes.size(); } + unsigned int GetCount() const { return static_cast(m_animNodes.size()); } CUiAnimViewAnimNode* GetNode(const unsigned int index) { return m_animNodes[index]; } const CUiAnimViewAnimNode* GetNode(const unsigned int index) const { return m_animNodes[index]; } diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewNode.h b/Gems/LyShine/Code/Editor/Animation/UiAnimViewNode.h index 61833adcd6..5a82d1be7f 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewNode.h +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewNode.h @@ -121,7 +121,7 @@ public: virtual bool AreAllKeysOfSameType() const override { return m_bAllOfSameType; } - virtual unsigned int GetKeyCount() const override { return m_keys.size(); } + virtual unsigned int GetKeyCount() const override { return static_cast(m_keys.size()); } virtual CUiAnimViewKeyHandle GetKey(unsigned int index) override { return m_keys[index]; } virtual void SelectKeys(const bool bSelected) override; @@ -173,7 +173,7 @@ public: CUiAnimViewNode* GetParentNode() const { return m_pParentNode; } // Children - unsigned int GetChildCount() const { return m_childNodes.size(); } + unsigned int GetChildCount() const { return static_cast(m_childNodes.size()); } CUiAnimViewNode* GetChild(unsigned int index) const { return m_childNodes[index].get(); } // Snap time value to prev/next key in sequence diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp index cdafd8a4ce..bac7779ef1 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequence.cpp @@ -1320,7 +1320,7 @@ void CUiAnimViewSequence::CloneSelectedKeys() std::vector selectedKeyTimes; for (size_t k = 0; k < selectedKeys.GetKeyCount(); ++k) { - CUiAnimViewKeyHandle skey = selectedKeys.GetKey(k); + CUiAnimViewKeyHandle skey = selectedKeys.GetKey(static_cast(k)); if (pTrack != skey.GetTrack()) { pTrack = skey.GetTrack(); @@ -1332,7 +1332,7 @@ void CUiAnimViewSequence::CloneSelectedKeys() // Now, do the actual cloning. for (size_t k = 0; k < selectedKeyTimes.size(); ++k) { - CUiAnimViewKeyHandle skey = selectedKeys.GetKey(k); + CUiAnimViewKeyHandle skey = selectedKeys.GetKey(static_cast(k)); skey = skey.GetTrack()->GetKeyByTime(selectedKeyTimes[k]); assert(skey.IsValid()); diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.h b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.h index 61aecc9cd5..e26a1ceec3 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.h +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.h @@ -36,7 +36,7 @@ public: virtual void OnEditorNotifyEvent(EEditorNotifyEvent event); - unsigned int GetCount() const { return m_sequences.size(); } + unsigned int GetCount() const { return static_cast(m_sequences.size()); } void CreateSequence(QString name); void DeleteSequence(CUiAnimViewSequence* pSequence); diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewTrack.h b/Gems/LyShine/Code/Editor/Animation/UiAnimViewTrack.h index 6d11f55247..a2e38edc51 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewTrack.h +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewTrack.h @@ -23,7 +23,7 @@ public: : m_bAllOfSameType(true) , m_bHasRotationTrack(false) {} - unsigned int GetCount() const { return m_tracks.size(); } + unsigned int GetCount() const { return static_cast(m_tracks.size()); } CUiAnimViewTrack* GetTrack(const unsigned int index) { return m_tracks[index]; } const CUiAnimViewTrack* GetTrack(const unsigned int index) const { return m_tracks[index]; } diff --git a/Gems/LyShine/Code/Editor/CanvasSizeToolbarSection.cpp b/Gems/LyShine/Code/Editor/CanvasSizeToolbarSection.cpp index 39fe3e9719..de9e5e63bc 100644 --- a/Gems/LyShine/Code/Editor/CanvasSizeToolbarSection.cpp +++ b/Gems/LyShine/Code/Editor/CanvasSizeToolbarSection.cpp @@ -493,7 +493,7 @@ void CanvasSizeToolbarSection::HandleIndexChanged() int CanvasSizeToolbarSection::GetCustomSizeIndex() { - return m_canvasSizePresets.size() - 1; + return static_cast(m_canvasSizePresets.size() - 1); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Editor/EditorWindow.cpp b/Gems/LyShine/Code/Editor/EditorWindow.cpp index 81360ed793..8d7e20492d 100644 --- a/Gems/LyShine/Code/Editor/EditorWindow.cpp +++ b/Gems/LyShine/Code/Editor/EditorWindow.cpp @@ -1547,6 +1547,20 @@ AssetTreeEntry* EditorWindow::GetSliceLibraryTree() return m_sliceLibraryTree; } +AZ::EntityId EditorWindow::GetCanvasForCurrentEditorMode() +{ + AZ::EntityId canvasEntityId; + if (GetEditorMode() == UiEditorMode::Edit) + { + canvasEntityId = GetCanvas(); + } + else + { + canvasEntityId = GetPreviewModeCanvas(); + } + return canvasEntityId; +} + void EditorWindow::ToggleEditorMode() { m_editorMode = (m_editorMode == UiEditorMode::Edit) ? UiEditorMode::Preview : UiEditorMode::Edit; diff --git a/Gems/LyShine/Code/Editor/EditorWindow.h b/Gems/LyShine/Code/Editor/EditorWindow.h index c2fa6808f1..d9b3e60c32 100644 --- a/Gems/LyShine/Code/Editor/EditorWindow.h +++ b/Gems/LyShine/Code/Editor/EditorWindow.h @@ -143,6 +143,9 @@ public: // member functions //! Returns the current mode of the editor (Edit or Preview) UiEditorMode GetEditorMode() { return m_editorMode; } + //! Returns the UI canvas for the current mode (Edit or Preview) + AZ::EntityId GetCanvasForCurrentEditorMode(); + //! Toggle the editor mode between Edit and Preview void ToggleEditorMode(); diff --git a/Gems/LyShine/Code/Editor/HierarchyClipboard.cpp b/Gems/LyShine/Code/Editor/HierarchyClipboard.cpp index df65c677ef..41a29988e7 100644 --- a/Gems/LyShine/Code/Editor/HierarchyClipboard.cpp +++ b/Gems/LyShine/Code/Editor/HierarchyClipboard.cpp @@ -156,7 +156,7 @@ void HierarchyClipboard::CopySelectedItemsToClipboard(HierarchyWidget* widget, QMimeData* mimeData = pEditor->CreateQMimeData(); { // Concatenate all the data we need into a single QByteArray. - QByteArray data(xml.c_str(), xml.size()); + QByteArray data(xml.c_str(), static_cast(xml.size())); mimeData->setData(UICANVASEDITOR_MIMETYPE, data); } diff --git a/Gems/LyShine/Code/Editor/HierarchyMenu.cpp b/Gems/LyShine/Code/Editor/HierarchyMenu.cpp index f4e1776440..ab0c250434 100644 --- a/Gems/LyShine/Code/Editor/HierarchyMenu.cpp +++ b/Gems/LyShine/Code/Editor/HierarchyMenu.cpp @@ -34,7 +34,7 @@ HierarchyMenu::HierarchyMenu(HierarchyWidget* hierarchy, New_EmptyElement(hierarchy, selectedItems, menu, (showMask & Show::kNew_EmptyElementAtRoot), optionalPos); } - if (showMask & Show::kNew_InstantiateSlice | Show::kNew_InstantiateSliceAtRoot) + if (showMask & (Show::kNew_InstantiateSlice | Show::kNew_InstantiateSliceAtRoot)) { New_ElementFromSlice(hierarchy, selectedItems, menu, (showMask & Show::kNew_InstantiateSliceAtRoot), optionalPos); } diff --git a/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp b/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp index d833c93af8..c82a6e2681 100644 --- a/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp +++ b/Gems/LyShine/Code/Editor/SpriteBorderEditor.cpp @@ -286,8 +286,8 @@ void SpriteBorderEditor::AddConfigureSection(QGridLayout* gridLayout, int& rowNu // Count the number of unique entries along each axis to determine number // of rows/cols contained within the spritesheet. - m_numRows = vSet.size() > 1 ? vSet.size() - 1 : 1; - m_numCols = uSet.size() > 1 ? uSet.size() - 1 : 1; + m_numRows = static_cast(vSet.size() > 1 ? vSet.size() - 1 : 1); + m_numCols = static_cast(uSet.size() > 1 ? uSet.size() - 1 : 1); // Text input fields displaying row/col information for auto-extracting // spritesheet cells diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.cpp b/Gems/LyShine/Code/Editor/ViewportWidget.cpp index 46f4f4f8fa..1ce8f5b64d 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.cpp +++ b/Gems/LyShine/Code/Editor/ViewportWidget.cpp @@ -7,6 +7,8 @@ */ #include "EditorCommon.h" +#include "UiCanvasComponent.h" + #include "EditorDefs.h" #include "Settings.h" #include @@ -245,6 +247,7 @@ ViewportWidget::ViewportWidget(EditorWindow* parent) FontNotificationBus::Handler::BusConnect(); AZ::TickBus::Handler::BusConnect(); + AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect(GetCurrentContextName()); } ViewportWidget::~ViewportWidget() @@ -252,6 +255,8 @@ ViewportWidget::~ViewportWidget() AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect(); FontNotificationBus::Handler::BusDisconnect(); AZ::TickBus::Handler::BusDisconnect(); + LyShinePassDataRequestBus::Handler::BusDisconnect(); + AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect(); m_uiRenderer.reset(); @@ -272,6 +277,8 @@ void ViewportWidget::InitUiRenderer() lyShine->SetUiRendererForEditor(m_uiRenderer); m_draw2d = AZStd::make_shared(GetViewportContext()); + + LyShinePassDataRequestBus::Handler::BusConnect(GetViewportContext()->GetRenderScene()->GetId()); } ViewportInteraction* ViewportWidget::GetViewportInteraction() @@ -487,30 +494,44 @@ void ViewportWidget::EnableCanvasRender() } void ViewportWidget::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) +{ + // Update + UiEditorMode editorMode = m_editorWindow->GetEditorMode(); + if (editorMode == UiEditorMode::Edit) + { + UpdateEditMode(deltaTime); + } + else // if (editorMode == UiEditorMode::Preview) + { + UpdatePreviewMode(deltaTime); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +int ViewportWidget::GetTickOrder() +{ + return AZ::TICK_PRE_RENDER; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void ViewportWidget::OnRenderTick() { if (!m_uiRenderer->IsReady() || !m_canvasRenderIsEnabled) { return; } -#ifdef LYSHINE_ATOM_TODO - gEnv->pRenderer->SetSrgbWrite(true); -#endif - const float dpiScale = QtHelpers::GetHighDpiScaleFactor(*this); ViewportIcon::SetDpiScaleFactor(dpiScale); - // Set up to render a frame to this viewport's window - GetViewportContext()->RenderTick(); - UiEditorMode editorMode = m_editorWindow->GetEditorMode(); if (editorMode == UiEditorMode::Edit) { - RenderEditMode(deltaTime); + RenderEditMode(); } else // if (editorMode == UiEditorMode::Preview) { - RenderPreviewMode(deltaTime); + RenderPreviewMode(); } } @@ -884,17 +905,37 @@ void ViewportWidget::OnFontTextureUpdated([[maybe_unused]] IFFont* font) m_fontTextureHasChanged = true; } +LyShine::AttachmentImagesAndDependencies ViewportWidget::GetRenderTargets() +{ + LyShine::AttachmentImagesAndDependencies canvasTargets; + + AZ::EntityId canvasEntityId = m_editorWindow->GetCanvasForCurrentEditorMode(); + if (canvasEntityId.IsValid()) + { + AZ::Entity* canvasEntity = nullptr; + EBUS_EVENT_RESULT(canvasEntity, AZ::ComponentApplicationBus, FindEntity, canvasEntityId); + AZ_Assert(canvasEntity, "Canvas entity not found by ID"); + if (canvasEntity) + { + UiCanvasComponent* canvasComponent = canvasEntity->FindComponent(); + AZ_Assert(canvasComponent, "Canvas entity has no canvas component"); + if (canvasComponent) + { + canvasComponent->GetRenderTargets(canvasTargets); + } + } + } + + return canvasTargets; +} + QPointF ViewportWidget::WidgetToViewport(const QPointF & point) const { return point * WidgetToViewportFactor(); } -void ViewportWidget::RenderEditMode(float deltaTime) +void ViewportWidget::UpdateEditMode(float deltaTime) { - // sort keys for different layers - static const int64_t backgroundKey = -0x1000; - static const int64_t topLayerKey = 0x1000000; - if (m_fontTextureHasChanged) { // A font texture has changed since we last rendered. Force a render graph update for each loaded canvas @@ -908,6 +949,28 @@ void ViewportWidget::RenderEditMode(float deltaTime) return; // this can happen if a render happens during a restart } + AZ::Vector2 canvasSize; + EBUS_EVENT_ID_RESULT(canvasSize, canvasEntityId, UiCanvasBus, GetCanvasSize); + + // Set the target size of the canvas + EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetTargetCanvasSize, false, canvasSize); + + // Update this canvas (must be done after SetTargetCanvasSize) + EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, deltaTime, false); +} + +void ViewportWidget::RenderEditMode() +{ + // sort keys for different layers + static const int64_t backgroundKey = -0x1000; + static const int64_t topLayerKey = 0x1000000; + + AZ::EntityId canvasEntityId = m_editorWindow->GetCanvas(); + if (!canvasEntityId.IsValid()) + { + return; // this can happen if a render happens during a restart + } + Draw2dHelper draw2d(m_draw2d.get()); // sets and resets 2D draw mode in constructor/destructor QTreeWidgetItemRawPtrQList selection = m_editorWindow->GetHierarchy()->selectedItems(); @@ -936,9 +999,6 @@ void ViewportWidget::RenderEditMode(float deltaTime) // Set the target size of the canvas EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetTargetCanvasSize, false, canvasSize); - // Update this canvas (must be done after SetTargetCanvasSize) - EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, deltaTime, false); - // Render this canvas QSize scaledViewportSize = QtHelpers::GetDpiScaledViewportSize(*this); AZ::Vector2 viewportSize(scaledViewportSize.width(), scaledViewportSize.height()); @@ -1037,11 +1097,8 @@ void ViewportWidget::RenderEditMode(float deltaTime) } } -void ViewportWidget::RenderPreviewMode(float deltaTime) +void ViewportWidget::UpdatePreviewMode(float deltaTime) { - // sort keys for different layers - static const int64_t backgroundKey = -0x1000; - AZ::EntityId canvasEntityId = m_editorWindow->GetPreviewModeCanvas(); if (m_fontTextureHasChanged) @@ -1051,6 +1108,37 @@ void ViewportWidget::RenderPreviewMode(float deltaTime) m_fontTextureHasChanged = false; } + if (canvasEntityId.IsValid()) + { + QSize scaledViewportSize = QtHelpers::GetDpiScaledViewportSize(*this); + AZ::Vector2 viewportSize(scaledViewportSize.width(), scaledViewportSize.height()); + + // Get the canvas size + AZ::Vector2 canvasSize = m_editorWindow->GetPreviewCanvasSize(); + if (canvasSize.GetX() == 0.0f && canvasSize.GetY() == 0.0f) + { + // special value of (0,0) means use the viewport size + canvasSize = viewportSize; + } + + // Set the target size of the canvas + EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetTargetCanvasSize, true, canvasSize); + + // Update this canvas (must be done after SetTargetCanvasSize) + EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, deltaTime, true); + + // Execute events that have been queued during the canvas update + gEnv->pLyShine->ExecuteQueuedEvents(); + } +} + +void ViewportWidget::RenderPreviewMode() +{ + // sort keys for different layers + static const int64_t backgroundKey = -0x1000; + + AZ::EntityId canvasEntityId = m_editorWindow->GetPreviewModeCanvas(); + // Rather than scaling to exactly fit we try to draw at one of these preset scale factors // to make it it bit more obvious that the canvas size is changing float zoomScales[] = { @@ -1096,15 +1184,6 @@ void ViewportWidget::RenderPreviewMode(float deltaTime) } } - // Set the target size of the canvas - EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetTargetCanvasSize, true, canvasSize); - - // Update this canvas (must be done after SetTargetCanvasSize) - EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, UpdateCanvasInEditorViewport, deltaTime, true); - - // Execute events that have been queued during the canvas update - gEnv->pLyShine->ExecuteQueuedEvents(); - // match scale to one of the predefined scales. If the scale is so small // that it is less than the smallest scale then leave it as it is for (int i = 0; i < AZ_ARRAY_SIZE(zoomScales); ++i) @@ -1131,14 +1210,6 @@ void ViewportWidget::RenderPreviewMode(float deltaTime) canvasToViewportMatrix.SetTranslation(translation); EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetCanvasToViewportMatrix, canvasToViewportMatrix); -#ifdef LYSHINE_ATOM_TODO // mask support with Atom - // clear the stencil buffer before rendering each canvas - required for masking - // NOTE: the FRT_CLEAR_IMMEDIATE is required since we will not be setting the render target - // We also clear the color to a mid grey so that we can see the bounds of the canvas - ColorF viewportBackgroundColor(0.5f, 0.5f, 0.5f, 0); // if clearing color we want to set alpha to zero also - gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR, viewportBackgroundColor); -#endif - m_draw2d->SetSortKey(backgroundKey); RenderViewportBackground(); diff --git a/Gems/LyShine/Code/Editor/ViewportWidget.h b/Gems/LyShine/Code/Editor/ViewportWidget.h index 0473b219dc..620cb8fb35 100644 --- a/Gems/LyShine/Code/Editor/ViewportWidget.h +++ b/Gems/LyShine/Code/Editor/ViewportWidget.h @@ -9,9 +9,11 @@ #if !defined(Q_MOC_RUN) #include "EditorCommon.h" +#include "LyShinePassDataBus.h" #include #include +#include #include @@ -27,6 +29,8 @@ class ViewportWidget : public AtomToolsFramework::RenderViewportWidget , private AzToolsFramework::EditorPickModeNotificationBus::Handler , private FontNotificationBus::Handler + , private LyShinePassDataRequestBus::Handler + , public AZ::RPI::ViewportContextNotificationBus::Handler { Q_OBJECT @@ -138,15 +142,29 @@ private: // member functions void OnFontTextureUpdated(IFFont* font) override; // ~FontNotifications + // LyShinePassDataRequestBus + LyShine::AttachmentImagesAndDependencies GetRenderTargets() override; + // ~LyShinePassDataRequestBus + // AZ::TickBus::Handler void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; + int GetTickOrder() override; // ~AZ::TickBus::Handler + // AZ::RPI::ViewportContextNotificationBus::Handler overrides... + void OnRenderTick() override; + + //! Update UI canvases when in edit mode + void UpdateEditMode(float deltaTime); + //! Render the viewport when in edit mode - void RenderEditMode(float deltaTime); + void RenderEditMode(); + + //! Update UI canvases when in preview mode + void UpdatePreviewMode(float deltaTime); //! Render the viewport when in preview mode - void RenderPreviewMode(float deltaTime); + void RenderPreviewMode(); //! Fill the entire viewport area with a background color void RenderViewportBackground(); diff --git a/Gems/LyShine/Code/Source/Animation/AnimNode.cpp b/Gems/LyShine/Code/Source/Animation/AnimNode.cpp index f7a6015a56..a87dae6fbd 100644 --- a/Gems/LyShine/Code/Source/Animation/AnimNode.cpp +++ b/Gems/LyShine/Code/Source/Animation/AnimNode.cpp @@ -62,7 +62,7 @@ void CUiAnimNode::Activate([[maybe_unused]] bool bActivate) ////////////////////////////////////////////////////////////////////////// int CUiAnimNode::GetTrackCount() const { - return m_tracks.size(); + return static_cast(m_tracks.size()); } const char* CUiAnimNode::GetParamName(const CUiAnimParamType& paramType) const diff --git a/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp b/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp index 0b19c4a06a..9b841bfd45 100644 --- a/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp +++ b/Gems/LyShine/Code/Source/Animation/AnimSequence.cpp @@ -48,7 +48,7 @@ CUiAnimSequence::CUiAnimSequence(IUiAnimationSystem* pUiAnimationSystem, uint32 CUiAnimSequence::~CUiAnimSequence() { // clear reference to me from all my nodes - for (int i = m_nodes.size(); --i >= 0;) + for (int i = static_cast(m_nodes.size()); --i >= 0;) { if (m_nodes[i]) { @@ -144,7 +144,7 @@ const IUiAnimSequence* CUiAnimSequence::GetParentSequence() const ////////////////////////////////////////////////////////////////////////// int CUiAnimSequence::GetNodeCount() const { - return m_nodes.size(); + return static_cast(m_nodes.size()); } ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Source/Animation/AnimTrack.h b/Gems/LyShine/Code/Source/Animation/AnimTrack.h index e2d6fd1069..f73cd7ede7 100644 --- a/Gems/LyShine/Code/Source/Animation/AnimTrack.h +++ b/Gems/LyShine/Code/Source/Animation/AnimTrack.h @@ -71,7 +71,7 @@ public: } //! Return number of keys in track. - virtual int GetNumKeys() const { return m_keys.size(); }; + virtual int GetNumKeys() const { return static_cast(m_keys.size()); }; //! Return true if keys exists in this track virtual bool HasKeys() const { return !m_keys.empty(); } @@ -517,7 +517,7 @@ inline int TUiAnimTrack::GetActiveKey(float time, KeyType* key) return -1; } - int nkeys = m_keys.size(); + int nkeys = static_cast(m_keys.size()); if (nkeys == 0) { m_lastTime = time; diff --git a/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp b/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp index 32dfb97a58..a98b651ea0 100644 --- a/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp +++ b/Gems/LyShine/Code/Source/Animation/AzEntityNode.cpp @@ -163,7 +163,7 @@ CUiAnimAzEntityNode::~CUiAnimAzEntityNode() ////////////////////////////////////////////////////////////////////////// unsigned int CUiAnimAzEntityNode::GetParamCount() const { - return CUiAnimAzEntityNode::GetParamCountStatic() + m_entityScriptPropertiesParamInfos.size(); + return static_cast(CUiAnimAzEntityNode::GetParamCountStatic() + m_entityScriptPropertiesParamInfos.size()); } ////////////////////////////////////////////////////////////////////////// @@ -190,7 +190,7 @@ CUiAnimParamType CUiAnimAzEntityNode::GetParamType(unsigned int nIndex) const ////////////////////////////////////////////////////////////////////////// int CUiAnimAzEntityNode::GetParamCountStatic() { - return s_nodeParams.size(); + return static_cast(s_nodeParams.size()); } ////////////////////////////////////////////////////////////////////////// @@ -680,7 +680,7 @@ IUiAnimTrack* CUiAnimAzEntityNode::CreateTrackForAzField(const UiAnimParamData& // this is a compound type, create a compound track // We only support compound tracks with 2, 3 or 4 subtracks - int numElements = classData->m_elements.size(); + int numElements = static_cast(classData->m_elements.size()); if (numElements < 2 || numElements > 4) { return nullptr; diff --git a/Gems/LyShine/Code/Source/Animation/BoolTrack.cpp b/Gems/LyShine/Code/Source/Animation/BoolTrack.cpp index 911c3a29ce..4582cd7be1 100644 --- a/Gems/LyShine/Code/Source/Animation/BoolTrack.cpp +++ b/Gems/LyShine/Code/Source/Animation/BoolTrack.cpp @@ -31,7 +31,7 @@ void UiBoolTrack::GetValue(float time, bool& value) CheckValid(); - int nkeys = m_keys.size(); + int nkeys = static_cast(m_keys.size()); if (nkeys < 1) { return; diff --git a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp index 1ea35006e2..324f32b414 100644 --- a/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp +++ b/Gems/LyShine/Code/Source/Animation/UiAnimationSystem.cpp @@ -296,7 +296,7 @@ IUiAnimSequence* UiAnimationSystem::GetSequence(int i) const ////////////////////////////////////////////////////////////////////////// int UiAnimationSystem::GetNumSequences() const { - return m_sequences.size(); + return static_cast(m_sequences.size()); } ////////////////////////////////////////////////////////////////////////// @@ -315,7 +315,7 @@ IUiAnimSequence* UiAnimationSystem::GetPlayingSequence(int i) const ////////////////////////////////////////////////////////////////////////// int UiAnimationSystem::GetNumPlayingSequences() const { - return m_playingSequences.size(); + return static_cast(m_playingSequences.size()); } ////////////////////////////////////////////////////////////////////////// @@ -327,7 +327,7 @@ void UiAnimationSystem::AddSequence(IUiAnimSequence* pSequence) ////////////////////////////////////////////////////////////////////////// bool UiAnimationSystem::IsCutScenePlaying() const { - const uint numPlayingSequences = m_playingSequences.size(); + const uint numPlayingSequences = static_cast(m_playingSequences.size()); for (uint i = 0; i < numPlayingSequences; ++i) { const IUiAnimSequence* pAnimSequence = m_playingSequences[i].sequence.get(); diff --git a/Gems/LyShine/Code/Source/Draw2d.cpp b/Gems/LyShine/Code/Source/Draw2d.cpp index 34ffb38fa3..2d3612fc07 100644 --- a/Gems/LyShine/Code/Source/Draw2d.cpp +++ b/Gems/LyShine/Code/Source/Draw2d.cpp @@ -9,6 +9,7 @@ #include // for SVF_P3F_C4B_T2F which will be removed in a coming PR #include +#include "LyShinePassDataBus.h" #include #include @@ -95,6 +96,12 @@ void CDraw2d::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapSc AZ_Assert(scene != nullptr, "Attempting to create a DynamicDrawContext for a viewport context that has not been associated with a scene yet."); // Create and initialize a DynamicDrawContext for 2d drawing + + // Get the pass for the dynamic draw context to render to + AZ::RPI::RasterPass* uiCanvasPass = nullptr; + AZ::RPI::SceneId sceneId = scene->GetId(); + LyShinePassRequestBus::EventResult(uiCanvasPass, sceneId, &LyShinePassRequestBus::Events::GetUiCanvasPass); + m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(); AZ::RPI::ShaderOptionList shaderOptions; shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true"))); @@ -106,7 +113,15 @@ void CDraw2d::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapSc {"TEXCOORD0", AZ::RHI::Format::R32G32_FLOAT} }); m_dynamicDraw->AddDrawStateOptions(AZ::RPI::DynamicDrawContext::DrawStateOptions::PrimitiveType | AZ::RPI::DynamicDrawContext::DrawStateOptions::BlendMode); - m_dynamicDraw->SetOutputScope(scene.get()); + if (uiCanvasPass) + { + m_dynamicDraw->SetOutputScope(uiCanvasPass); + } + else + { + // Render target support is disabled + m_dynamicDraw->SetOutputScope(scene.get()); + } m_dynamicDraw->EndInit(); AZ::RHI::TargetBlendState targetBlendState; @@ -491,6 +506,7 @@ bool CDraw2d::GetDeferPrimitives() return m_deferCalls; } +//////////////////////////////////////////////////////////////////////////////////////////////////// void CDraw2d::SetSortKey(int64_t key) { m_dynamicDraw->SetSortKey(key); diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index 4e265bd973..694a9665a8 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -163,6 +163,8 @@ CLyShine::CLyShine(ISystem* system) AzFramework::InputTextEventListener::Connect(); UiCursorBus::Handler::BusConnect(); AZ::TickBus::Handler::BusConnect(); + AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect( + AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContextName()); AZ::Render::Bootstrap::NotificationBus::Handler::BusConnect(); // These are internal Amazon components, so register them so that we can send back their names to our metrics collection @@ -240,9 +242,11 @@ CLyShine::~CLyShine() { UiCursorBus::Handler::BusDisconnect(); AZ::TickBus::Handler::BusDisconnect(); + AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect(); AzFramework::InputTextEventListener::Disconnect(); AzFramework::InputChannelEventListener::Disconnect(); AZ::Render::Bootstrap::NotificationBus::Handler::BusDisconnect(); + LyShinePassDataRequestBus::Handler::BusDisconnect(); UiCanvasComponent::Shutdown(); @@ -642,15 +646,19 @@ void CLyShine::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time { // Update the loaded UI canvases Update(deltaTime); - - // Recreate dirty render graphs and send primitive data to the dynamic draw context - Render(); } //////////////////////////////////////////////////////////////////////////////////////////////////// int CLyShine::GetTickOrder() { - return AZ::TICK_UI; + return AZ::TICK_PRE_RENDER; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CLyShine::OnRenderTick() +{ + // Recreate dirty render graphs and send primitive data to the dynamic draw context + Render(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -658,6 +666,16 @@ void CLyShine::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapS { // Load cursor if its path was set before RPI was initialized LoadUiCursor(); + + LyShinePassDataRequestBus::Handler::BusConnect(AZ::RPI::RPISystemInterface::Get()->GetDefaultScene()->GetId()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +LyShine::AttachmentImagesAndDependencies CLyShine::GetRenderTargets() +{ + LyShine::AttachmentImagesAndDependencies attachmentImagesAndDependencies; + m_uiCanvasManager->GetRenderTargets(attachmentImagesAndDependencies); + return attachmentImagesAndDependencies; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Source/LyShine.h b/Gems/LyShine/Code/Source/LyShine.h index cb5b77a861..19a4e664e5 100644 --- a/Gems/LyShine/Code/Source/LyShine.h +++ b/Gems/LyShine/Code/Source/LyShine.h @@ -16,8 +16,11 @@ #include #include +#include #include +#include "LyShinePassDataBus.h" + #if !defined(_RELEASE) #define LYSHINE_INTERNAL_UNIT_TEST #endif @@ -40,7 +43,9 @@ class CLyShine , public AzFramework::InputChannelEventListener , public AzFramework::InputTextEventListener , public AZ::TickBus::Handler + , public AZ::RPI::ViewportContextNotificationBus::Handler , protected AZ::Render::Bootstrap::NotificationBus::Handler + , protected LyShinePassDataRequestBus::Handler { public: @@ -111,10 +116,17 @@ public: int GetTickOrder() override; // ~TickEvents + // AZ::RPI::ViewportContextNotificationBus::Handler overrides... + void OnRenderTick() override; + // AZ::Render::Bootstrap::NotificationBus void OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) override; // ~AZ::Render::Bootstrap::NotificationBus + // LyShinePassDataRequestBus + LyShine::AttachmentImagesAndDependencies GetRenderTargets() override; + // ~LyShinePassDataRequestBus + // Get the UIRenderer for the game (which is owned by CLyShine). This is not exposed outside the gem. UiRenderer* GetUiRenderer(); diff --git a/Gems/LyShine/Code/Source/LyShineDebug.h b/Gems/LyShine/Code/Source/LyShineDebug.h index 11f48a1e32..84b4d1b4a5 100644 --- a/Gems/LyShine/Code/Source/LyShineDebug.h +++ b/Gems/LyShine/Code/Source/LyShineDebug.h @@ -12,9 +12,9 @@ #include #include +#endif #include -#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //! Class for drawing test displays for testing the LyShine functionality diff --git a/Gems/LyShine/Code/Source/LyShinePass.cpp b/Gems/LyShine/Code/Source/LyShinePass.cpp new file mode 100644 index 0000000000..fbf7f34e14 --- /dev/null +++ b/Gems/LyShine/Code/Source/LyShinePass.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "LyShinePass.h" + +namespace LyShine +{ + AZ::RPI::Ptr LyShinePass::Create(const AZ::RPI::PassDescriptor& descriptor) + { + return aznew LyShinePass(descriptor); + } + + LyShinePass::LyShinePass(const AZ::RPI::PassDescriptor& descriptor) + : Base(descriptor) + { + } + + LyShinePass::~LyShinePass() + { + LyShinePassRequestBus::Handler::BusDisconnect(); + } + + void LyShinePass::ResetInternal() + { + LyShinePassRequestBus::Handler::BusDisconnect(); + + Base::ResetInternal(); + } + + void LyShinePass::BuildInternal() + { + AZ::RPI::Scene* scene = GetScene(); + if (scene) + { + // Listen for rebuild requests + LyShinePassRequestBus::Handler::BusConnect(scene->GetId()); + + RemoveChildren(); + + // Get the current list of render targets being used across all loaded UI Canvases + LyShine::AttachmentImagesAndDependencies attachmentImagesAndDependencies; + LyShinePassDataRequestBus::EventResult( + attachmentImagesAndDependencies, + scene->GetId(), + &LyShinePassDataRequestBus::Events::GetRenderTargets + ); + + AddRttChildPasses(attachmentImagesAndDependencies); + AddUiCanvasChildPass(attachmentImagesAndDependencies); + } + + Base::BuildInternal(); + } + + void LyShinePass::RebuildRttChildren() + { + QueueForBuildAndInitialization(); + } + + AZ::RPI::RasterPass* LyShinePass::GetRttPass(const AZStd::string& name) + { + for (auto child:m_children) + { + if (child->GetName() == AZ::Name(name)) + { + return azrtti_cast(child.get()); + } + } + return nullptr; + } + + AZ::RPI::RasterPass* LyShinePass::GetUiCanvasPass() + { + return m_uiCanvasChildPass.get(); + } + + void LyShinePass::AddRttChildPasses(LyShine::AttachmentImagesAndDependencies attachmentImagesAndDependencies) + { + for (const auto& attachmentImageAndDependencies : attachmentImagesAndDependencies) + { + AddRttChildPass(attachmentImageAndDependencies.first, attachmentImageAndDependencies.second); + } + } + + void LyShinePass::AddRttChildPass(AZ::Data::Instance attachmentImage, AttachmentImages attachmentImageDependencies) + { + // Add a pass that renders to the specified texture + + // Create a pass template + auto passTemplate = AZStd::make_shared(); + passTemplate->m_name = "RttChildPass"; + passTemplate->m_passClass = AZ::Name("RttChildPass"); + + // Slots + passTemplate->m_slots.resize(2); + + AZ::RPI::PassSlot& depthInOutSlot = passTemplate->m_slots[0]; + depthInOutSlot.m_name = "DepthInputOutput"; + depthInOutSlot.m_slotType = AZ::RPI::PassSlotType::InputOutput; + depthInOutSlot.m_scopeAttachmentUsage = AZ::RHI::ScopeAttachmentUsage::DepthStencil; + depthInOutSlot.m_loadStoreAction.m_clearValue = AZ::RHI::ClearValue::CreateDepthStencil(0.0f, 0); + depthInOutSlot.m_loadStoreAction.m_loadActionStencil = AZ::RHI::AttachmentLoadAction::Clear; + + AZ::RPI::PassSlot& outSlot = passTemplate->m_slots[1]; + outSlot.m_name = AZ::Name("RenderTargetOutput"); + outSlot.m_slotType = AZ::RPI::PassSlotType::Output; + outSlot.m_scopeAttachmentUsage = AZ::RHI::ScopeAttachmentUsage::RenderTarget; + outSlot.m_loadStoreAction.m_clearValue = AZ::RHI::ClearValue::CreateVector4Float(0.0f, 0.0f, 0.0f, 0.0f); + outSlot.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Clear; + + // Connections + passTemplate->m_connections.resize(1); + + AZ::RPI::PassConnection& depthInOutConnection = passTemplate->m_connections[0]; + depthInOutConnection.m_localSlot = "DepthInputOutput"; + depthInOutConnection.m_attachmentRef.m_pass = "Parent"; + depthInOutConnection.m_attachmentRef.m_attachment = "DepthInputOutput"; + + // Pass data + AZStd::shared_ptr passData = AZStd::make_shared(); + passData->m_drawListTag = AZ::Name("uicanvas"); + passData->m_pipelineViewTag = AZ::Name("MainCamera"); + auto size = attachmentImage->GetRHIImage()->GetDescriptor().m_size; + passData->m_overrideScissor = AZ::RHI::Scissor(0, 0, size.m_width, size.m_height); + passData->m_overrideViewport = AZ::RHI::Viewport(0, size.m_width, 0, size.m_height); + passTemplate->m_passData = AZStd::move(passData); + // Create a pass descriptor for the new child pass + AZ::RPI::PassDescriptor childDesc; + childDesc.m_passTemplate = passTemplate; + childDesc.m_passName = attachmentImage->GetAttachmentId(); + + AZ::RPI::PassSystemInterface* passSystem = AZ::RPI::PassSystemInterface::Get(); + AZ::RPI::Ptr rttChildPass = passSystem->CreatePass(childDesc); + AZ_Assert(rttChildPass, "[LyShinePass] Unable to create %s.", passTemplate->m_name.GetCStr()); + + // Store the info needed to attach to slots and set up frame graph dependencies + rttChildPass->m_attachmentImage = attachmentImage; + rttChildPass->m_attachmentImageDependencies = attachmentImageDependencies; + + AddChild(rttChildPass); + } + + void LyShinePass::AddUiCanvasChildPass(LyShine::AttachmentImagesAndDependencies AttachmentImagesAndDependencies) + { + if (!m_uiCanvasChildPass) + { + // Create a pass template + auto passTemplate = AZStd::make_shared(); + passTemplate->m_name = AZ::Name("LyShineChildPass"); + passTemplate->m_passClass = AZ::Name("LyShineChildPass"); + + // Slots + passTemplate->m_slots.resize(2); + + AZ::RPI::PassSlot& depthInOutSlot = passTemplate->m_slots[0]; + depthInOutSlot.m_name = "DepthInputOutput"; + depthInOutSlot.m_slotType = AZ::RPI::PassSlotType::InputOutput; + depthInOutSlot.m_scopeAttachmentUsage = AZ::RHI::ScopeAttachmentUsage::DepthStencil; + depthInOutSlot.m_loadStoreAction.m_clearValue = AZ::RHI::ClearValue::CreateDepthStencil(0.0f, 0); + depthInOutSlot.m_loadStoreAction.m_loadActionStencil = AZ::RHI::AttachmentLoadAction::Clear; + + AZ::RPI::PassSlot& inOutSlot = passTemplate->m_slots[1]; + inOutSlot.m_name = "ColorInputOutput"; + inOutSlot.m_slotType = AZ::RPI::PassSlotType::InputOutput; + inOutSlot.m_scopeAttachmentUsage = AZ::RHI::ScopeAttachmentUsage::RenderTarget; + + // Connections + passTemplate->m_connections.resize(2); + + AZ::RPI::PassConnection& depthInOutConnection = passTemplate->m_connections[0]; + depthInOutConnection.m_localSlot = "DepthInputOutput"; + depthInOutConnection.m_attachmentRef.m_pass = "Parent"; + depthInOutConnection.m_attachmentRef.m_attachment = "DepthInputOutput"; + + AZ::RPI::PassConnection& inOutConnection = passTemplate->m_connections[1]; + inOutConnection.m_localSlot = "ColorInputOutput"; + inOutConnection.m_attachmentRef.m_pass = "Parent"; + inOutConnection.m_attachmentRef.m_attachment = "ColorInputOutput"; + + // Pass data + AZStd::shared_ptr passData = AZStd::make_shared(); + passData->m_drawListTag = AZ::Name("uicanvas"); + passData->m_pipelineViewTag = AZ::Name("MainCamera"); + passTemplate->m_passData = AZStd::move(passData); + + // Create a pass descriptor for the new child pass + AZ::RPI::PassDescriptor childDesc; + childDesc.m_passTemplate = passTemplate; + childDesc.m_passName = AZ::Name("LyShineChildPass"); + + AZ::RPI::PassSystemInterface* passSystem = AZ::RPI::PassSystemInterface::Get(); + m_uiCanvasChildPass = passSystem->CreatePass(childDesc); + AZ_Assert(m_uiCanvasChildPass, "[LyShinePass] Unable to create %s.", passTemplate->m_name.GetCStr()); + } + + // Store the info needed to set up frame graph dependencies + m_uiCanvasChildPass->m_attachmentImageDependencies.clear(); + for (const auto& attachmentImageAndDescendents : AttachmentImagesAndDependencies) + { + m_uiCanvasChildPass->m_attachmentImageDependencies.emplace_back(attachmentImageAndDescendents.first); + } + + AddChild(m_uiCanvasChildPass); + } + + AZ::RPI::Ptr LyShineChildPass::Create(const AZ::RPI::PassDescriptor& descriptor) + { + return aznew LyShineChildPass(descriptor); + } + + LyShineChildPass::LyShineChildPass(const AZ::RPI::PassDescriptor& descriptor) + : RasterPass(descriptor) + { + } + + LyShineChildPass::~LyShineChildPass() + { + } + + void LyShineChildPass::SetupFrameGraphDependencies(AZ::RHI::FrameGraphInterface frameGraph) + { + AZ::RPI::RasterPass::SetupFrameGraphDependencies(frameGraph); + + for (auto attachmentImage : m_attachmentImageDependencies) + { + // Ensure that the image is imported into the attachment database. + // The image may not be imported if the owning pass has been disabled. + auto attachmentImageId = attachmentImage->GetAttachmentId(); + if (!frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentImageId)) + { + frameGraph.GetAttachmentDatabase().ImportImage(attachmentImageId, attachmentImage->GetRHIImage()); + } + + AZ::RHI::ImageScopeAttachmentDescriptor desc; + desc.m_attachmentId = attachmentImageId; + desc.m_imageViewDescriptor = attachmentImage->GetImageView()->GetDescriptor(); + desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load; + + frameGraph.UseShaderAttachment(desc, AZ::RHI::ScopeAttachmentAccess::Read); + } + } + + AZ::RPI::Ptr RttChildPass::Create(const AZ::RPI::PassDescriptor& descriptor) + { + return aznew RttChildPass(descriptor); + } + + RttChildPass::RttChildPass(const AZ::RPI::PassDescriptor& descriptor) + : LyShineChildPass(descriptor) + { + } + + RttChildPass::~RttChildPass() + { + } + + void RttChildPass::BuildInternal() + { + AttachImageToSlot(AZ::Name("RenderTargetOutput"), m_attachmentImage); + } +} // namespace LyShine diff --git a/Gems/LyShine/Code/Source/LyShinePass.h b/Gems/LyShine/Code/Source/LyShinePass.h new file mode 100644 index 0000000000..6275353641 --- /dev/null +++ b/Gems/LyShine/Code/Source/LyShinePass.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include +#include +#include +#include +#include +#include "LyShinePassDataBus.h" + +namespace LyShine +{ + class LyShineChildPass; + + //! Manages child passes at runtime that render to render targets + class LyShinePass final + : public AZ::RPI::ParentPass + , protected LyShinePassRequestBus::Handler + { + AZ_RPI_PASS(LyShinePass); + using Base = AZ::RPI::ParentPass; + + public: + AZ_CLASS_ALLOCATOR(LyShinePass, AZ::SystemAllocator, 0); + AZ_RTTI(LyShinePass, "C3B812ED-3771-42F4-A96F-EBD94B4D54CA", Base); + + virtual ~LyShinePass(); + static AZ::RPI::Ptr Create(const AZ::RPI::PassDescriptor& descriptor); + + protected: + // Pass behavior overrides + void ResetInternal() override; + void BuildInternal() override; + + // LyShinePassRequestBus overrides + void RebuildRttChildren() override; + AZ::RPI::RasterPass* GetRttPass(const AZStd::string& name) override; + AZ::RPI::RasterPass* GetUiCanvasPass() override; + + private: + LyShinePass() = delete; + explicit LyShinePass(const AZ::RPI::PassDescriptor& descriptor); + + // Build the render to texture child passes + void AddRttChildPasses(LyShine::AttachmentImagesAndDependencies AttachmentImagesAndDependencies); + + // Add a render to texture child pass + void AddRttChildPass(AZ::Data::Instance attachmentImage, AttachmentImages dependentAttachmentImages); + + // Append the final pass to render UI Canvas elements to the screen + void AddUiCanvasChildPass(LyShine::AttachmentImagesAndDependencies AttachmentImagesAndDependencies); + + // Pass that renders the UI Canvas elements to the screen + AZ::RPI::Ptr m_uiCanvasChildPass; + }; + + // Child pass with potential attachment dependencies + class LyShineChildPass + : public AZ::RPI::RasterPass + { + AZ_RPI_PASS(LyShineChildPass); + + friend class LyShinePass; + public: + AZ_RTTI(LyShineChildPass, "{41D525F9-09EB-4004-97DC-082078FF8DD2}", RasterPass); + AZ_CLASS_ALLOCATOR(LyShineChildPass, AZ::SystemAllocator, 0); + virtual ~LyShineChildPass(); + + //! Creates a LyShineChildPass + static AZ::RPI::Ptr Create(const AZ::RPI::PassDescriptor& descriptor); + + protected: + LyShineChildPass(const AZ::RPI::PassDescriptor& descriptor); + + // Scope producer Overrides... + void SetupFrameGraphDependencies(AZ::RHI::FrameGraphInterface frameGraph) override; + + AttachmentImages m_attachmentImageDependencies; + }; + + // Child pass that renders UI elements to a render target + class RttChildPass + : public LyShineChildPass + { + AZ_RPI_PASS(RttChildPass); + + friend class LyShinePass; + + public: + AZ_RTTI(RttChildPass, "{54B0574D-2EB3-4054-9E1D-0E0D9C8CB09A}", LyShineChildPass); + AZ_CLASS_ALLOCATOR(RttChildPass, AZ::SystemAllocator, 0); + virtual ~RttChildPass(); + + //! Creates a RttChildPass + static AZ::RPI::Ptr Create(const AZ::RPI::PassDescriptor& descriptor); + + protected: + RttChildPass(const AZ::RPI::PassDescriptor& descriptor); + + // Pass behavior overrides + void BuildInternal() override; + + AZ::Data::Instance m_attachmentImage; + }; +} // namespace LyShine diff --git a/Gems/LyShine/Code/Source/LyShinePassDataBus.h b/Gems/LyShine/Code/Source/LyShinePassDataBus.h new file mode 100644 index 0000000000..a07e43bc44 --- /dev/null +++ b/Gems/LyShine/Code/Source/LyShinePassDataBus.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include +#include +#include +#include + +namespace AZ +{ + namespace RPI + { + class AttachmentImage; + class RasterPass; + } +} + +namespace LyShine +{ + using AttachmentImages = AZStd::vector>; + using AttachmentImageAndDependentsPair = AZStd::pair, AttachmentImages>; + using AttachmentImagesAndDependencies = AZStd::vector; +} + +class LyShinePassRequests + : public AZ::EBusTraits +{ +public: + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; + using BusIdType = AZ::RPI::SceneId; + + //! Called when the number of render targets has changed and the LyShine pass needs to rebuild + virtual void RebuildRttChildren() = 0; + + //! Returns a render to texture pass based on render target name + virtual AZ::RPI::RasterPass* GetRttPass(const AZStd::string& name) = 0; + + //! Returns the final pass that renders the UI canvas contents + virtual AZ::RPI::RasterPass* GetUiCanvasPass() = 0; +}; +using LyShinePassRequestBus = AZ::EBus; + +class LyShinePassDataRequests + : public AZ::EBusTraits +{ +public: + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; + using BusIdType = AZ::RPI::SceneId; + + //! Get a list of render targets that require a render to texture pass, and any + //! other render targets that are drawn on them + virtual LyShine::AttachmentImagesAndDependencies GetRenderTargets() = 0; +}; +using LyShinePassDataRequestBus = AZ::EBus; diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp index 337fe27bc5..f05cbc04d4 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp @@ -49,6 +49,7 @@ #include "UiDynamicLayoutComponent.h" #include "UiDynamicScrollBoxComponent.h" #include "UiNavigationSettings.h" +#include "LyShinePass.h" namespace LyShine { @@ -113,9 +114,11 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void LyShineSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + void LyShineSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) { - (void)required; +#if !defined(LYSHINE_BUILDER) && !defined(LYSHINE_TESTS) + required.push_back(AZ_CRC("RPISystem", 0xf2add773)); +#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -186,6 +189,17 @@ namespace LyShine RegisterComponentTypeForMenuOrdering(UiDynamicScrollBoxComponent::RTTI_Type()); RegisterComponentTypeForMenuOrdering(UiParticleEmitterComponent::RTTI_Type()); RegisterComponentTypeForMenuOrdering(UiFlipbookAnimationComponent::RTTI_Type()); + +#if !defined(LYSHINE_BUILDER) && !defined(LYSHINE_TESTS) + // Add LyShine pass + auto* passSystem = AZ::RPI::PassSystemInterface::Get(); + AZ_Assert(passSystem, "Cannot get the pass system."); + passSystem->AddPassCreator(AZ::Name("LyShinePass"), &LyShine::LyShinePass::Create); + + // Setup handler for load pass template mappings + m_loadTemplatesHandler = AZ::RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler([this]() { this->LoadPassTemplateMappings(); }); + AZ::RPI::PassSystemInterface::Get()->ConnectEvent(m_loadTemplatesHandler); +#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -386,4 +400,13 @@ namespace LyShine { UiCursorBus::Broadcast(&UiCursorInterface::SetUiCursor, m_cursorImagePathname.GetAssetPath().c_str()); } + +#if !defined(LYSHINE_BUILDER) && !defined(LYSHINE_TESTS) + //////////////////////////////////////////////////////////////////////////////////////////////////// + void LyShineSystemComponent::LoadPassTemplateMappings() + { + const char* passTemplatesFile = "Passes/LyShinePassTemplates.azasset"; + AZ::RPI::PassSystemInterface::Get()->LoadPassTemplateMappings(passTemplatesFile); + } +#endif } diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.h b/Gems/LyShine/Code/Source/LyShineSystemComponent.h index f922c59afe..3d5e81f7c5 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.h +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.h @@ -20,6 +20,10 @@ #include #include "LyShine.h" +#if !defined(LYSHINE_BUILDER) && !defined(LYSHINE_TESTS) +#include +#endif + namespace LyShine { // LyShine depends on the LegacyAllocator. This will be managed @@ -90,6 +94,11 @@ namespace LyShine void BroadcastCursorImagePathname(); +#if !defined(LYSHINE_BUILDER) && !defined(LYSHINE_TESTS) + // Load pass template mappings for this gem + void LoadPassTemplateMappings(); +#endif + protected: // data CLyShine* m_pLyShine = nullptr; @@ -102,5 +111,9 @@ namespace LyShine // We only store this in order to generate metrics on LyShine specific components static const AZStd::list* m_componentDescriptors; + +#if !defined(LYSHINE_BUILDER) && !defined(LYSHINE_TESTS) + AZ::RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler m_loadTemplatesHandler; +#endif }; } diff --git a/Gems/LyShine/Code/Source/RenderGraph.cpp b/Gems/LyShine/Code/Source/RenderGraph.cpp index 9ee26cdf8e..b07aab78c7 100644 --- a/Gems/LyShine/Code/Source/RenderGraph.cpp +++ b/Gems/LyShine/Code/Source/RenderGraph.cpp @@ -10,6 +10,9 @@ #include "UiRenderer.h" #include +#include + +#include #ifndef _RELEASE #include @@ -78,57 +81,28 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void PrimitiveListRenderNode::Render(UiRenderer* uiRenderer) + void PrimitiveListRenderNode::Render(UiRenderer* uiRenderer + , const AZ::Matrix4x4& modelViewProjMat + , AZ::RHI::Ptr dynamicDraw) { -#ifdef LYSHINE_ATOM_TODO // keeping this code for reference for future phase (masks/render targets) - for (int i = 0; i < m_numTextures; ++i) - { - uiRenderer->SetTexture(m_textures[i].m_texture, i, m_textures[i].m_isClampTextureMode); - } - - int blendModeState = m_blendModeState; - - IRenderer* renderer = gEnv->pRenderer; - renderer->SetState(blendModeState | uiRenderer->GetBaseState()); - - if (m_isTextureSRGB) - { - renderer->SetSrgbWrite(false); - } - - // We are using SetColorOp as a way to set flags for the ui.cfx shader by reusing flags - // that the FixedPipelineEmu.cfx shader uses. So the names colorOp and alphaOp are used - // just because this are the inputs to SetColorOp. - uint8 colorOp = m_preMultiplyAlpha ? ColorOp_PreMultiplyAlpha : ColorOp_Normal; - uint8 alphaOp = AlphaOp_Normal; - switch (m_alphaMaskType) - { - case AlphaMaskType::None: - alphaOp = AlphaOp_Normal; - break; - case AlphaMaskType::ModulateAlpha: - alphaOp = AlphaOp_ModulateAlpha; - break; - case AlphaMaskType::ModulateAlphaAndColor: - alphaOp = AlphaOp_ModulateAlphaAndColor; - break; - } - - renderer->SetColorOp(colorOp, alphaOp, DEF_TEXARG0, DEF_TEXARG0); - - renderer->DrawDynUiPrimitiveList(m_primitives, m_totalNumVertices, m_totalNumIndices); - - if (m_isTextureSRGB) - { - renderer->SetSrgbWrite(true); - } -#endif if (!uiRenderer->IsReady()) { return; } - AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); + UiRenderer::BaseState curBaseState = uiRenderer->GetBaseState(); + UiRenderer::BaseState prevBaseState = curBaseState; + if (m_isTextureSRGB) + { + curBaseState.m_srgbWrite = false; + } + + if (m_alphaMaskType == AlphaMaskType::ModulateAlpha) + { + curBaseState.m_modulateAlpha = true; + } + uiRenderer->SetBaseState(curBaseState); + const UiRenderer::UiShaderData& uiShaderData = uiRenderer->GetUiShaderData(); // Set render state @@ -167,7 +141,7 @@ namespace LyShine drawSrg->SetConstant(uiShaderData.m_isClampInputIndex, isClampTextureMode); // Set projection matrix - drawSrg->SetConstant(uiShaderData.m_viewProjInputIndex, uiRenderer->GetModelViewProjectionMatrix()); + drawSrg->SetConstant(uiShaderData.m_viewProjInputIndex, modelViewProjMat); drawSrg->Compile(); @@ -180,6 +154,8 @@ namespace LyShine { dynamicDraw->DrawIndexed(primitive.m_vertices, primitive.m_numVertices, primitive.m_indices, primitive.m_numIndices, AZ::RHI::IndexFormat::Uint16, drawSrg); } + + uiRenderer->SetBaseState(prevBaseState); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -303,33 +279,35 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void MaskRenderNode::Render(UiRenderer* uiRenderer) + void MaskRenderNode::Render(UiRenderer* uiRenderer + , const AZ::Matrix4x4& modelViewProjMat + , AZ::RHI::Ptr dynamicDraw) { UiRenderer::BaseState priorBaseState = uiRenderer->GetBaseState(); if (m_isMaskingEnabled || m_drawBehind) { - SetupBeforeRenderingMask(uiRenderer, true, priorBaseState); + SetupBeforeRenderingMask(uiRenderer, dynamicDraw, true, priorBaseState); for (RenderNode* renderNode : m_maskRenderNodes) { - renderNode->Render(uiRenderer); + renderNode->Render(uiRenderer, modelViewProjMat, dynamicDraw); } - SetupAfterRenderingMask(uiRenderer, true, priorBaseState); + SetupAfterRenderingMask(uiRenderer, dynamicDraw, true, priorBaseState); } for (RenderNode* renderNode : m_contentRenderNodes) { - renderNode->Render(uiRenderer); + renderNode->Render(uiRenderer, modelViewProjMat, dynamicDraw); } if (m_isMaskingEnabled || m_drawInFront) { - SetupBeforeRenderingMask(uiRenderer, false, priorBaseState); + SetupBeforeRenderingMask(uiRenderer, dynamicDraw, false, priorBaseState); for (RenderNode* renderNode : m_maskRenderNodes) { - renderNode->Render(uiRenderer); + renderNode->Render(uiRenderer, modelViewProjMat, dynamicDraw); } - SetupAfterRenderingMask(uiRenderer, false, priorBaseState); + SetupAfterRenderingMask(uiRenderer, dynamicDraw, false, priorBaseState); } } @@ -367,7 +345,9 @@ namespace LyShine #endif //////////////////////////////////////////////////////////////////////////////////////////////////// - void MaskRenderNode::SetupBeforeRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState) + void MaskRenderNode::SetupBeforeRenderingMask(UiRenderer* uiRenderer, + AZ::RHI::Ptr dynamicDraw, + bool firstPass, UiRenderer::BaseState priorBaseState) { UiRenderer::BaseState curBaseState = priorBaseState; @@ -406,7 +386,6 @@ namespace LyShine curBaseState.m_stencilState.m_backFace = stencilOpState; // set up for stencil write - AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); dynamicDraw->SetStencilReference(uiRenderer->GetStencilRef()); curBaseState.m_stencilState.m_enable = true; curBaseState.m_stencilState.m_writeMask = 0xFF; @@ -421,7 +400,9 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void MaskRenderNode::SetupAfterRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState) + void MaskRenderNode::SetupAfterRenderingMask(UiRenderer* uiRenderer, + AZ::RHI::Ptr dynamicDraw, + bool firstPass, UiRenderer::BaseState priorBaseState) { if (m_isMaskingEnabled) { @@ -439,7 +420,6 @@ namespace LyShine uiRenderer->DecrementStencilRef(); } - AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); dynamicDraw->SetStencilReference(uiRenderer->GetStencilRef()); if (firstPass) @@ -474,16 +454,14 @@ namespace LyShine //////////////////////////////////////////////////////////////////////////////////////////////////// RenderTargetRenderNode::RenderTargetRenderNode( RenderTargetRenderNode* parentRenderTarget, - int renderTargetHandle, - SDepthTexture* renderTargetDepthSurface, + AZ::Data::Instance attachmentImage, const AZ::Vector2& viewportTopLeft, const AZ::Vector2& viewportSize, const AZ::Color& clearColor, int nestLevel) : RenderNode(RenderNodeType::RenderTarget) , m_parentRenderTarget(parentRenderTarget) - , m_renderTargetHandle(renderTargetHandle) - , m_renderTargetDepthSurface(renderTargetDepthSurface) + , m_attachmentImage(attachmentImage) , m_viewportX(viewportTopLeft.GetX()) , m_viewportY(viewportTopLeft.GetY()) , m_viewportWidth(viewportSize.GetX()) @@ -491,6 +469,13 @@ namespace LyShine , m_clearColor(clearColor) , m_nestLevel(nestLevel) { + AZ::MakeOrthographicMatrixRH(m_modelViewProjMat, + m_viewportX, + m_viewportX + m_viewportWidth, + m_viewportY + m_viewportHeight, + m_viewportY, + 0.0f, + 1.0f); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -505,9 +490,11 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void RenderTargetRenderNode::Render(UiRenderer* uiRenderer) + void RenderTargetRenderNode::Render(UiRenderer* uiRenderer + , [[maybe_unused]] const AZ::Matrix4x4& modelViewProjMat + , [[maybe_unused]] AZ::RHI::Ptr dynamicDraw) { - if (m_renderTargetHandle <= 0) + if (!m_attachmentImage) { return; } @@ -515,39 +502,52 @@ namespace LyShine ISystem* system = gEnv->pSystem; if (system && !gEnv->IsDedicated()) { - TransformationMatrices backupMatrices; - gEnv->pRenderer->Set2DModeNonZeroTopLeft(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight, backupMatrices); - - // this will change the viewport - gEnv->pRenderer->SetRenderTarget(m_renderTargetHandle, m_renderTargetDepthSurface); - - // clear the render target before rendering to it - // NOTE: the FRT_CLEAR_IMMEDIATE is required since we will have already set the render target - // In theory we could call this before setting the render target without the immediate flag - // but that doesn't work. Perhaps because FX_Commit is not called. - ColorF viewportBackgroundColor(m_clearColor.GetR(), m_clearColor.GetG(), m_clearColor.GetB(), m_clearColor.GetA()); - gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR, viewportBackgroundColor); - - // we could use SetSrgbWrite to write to a linear texture here. But that gets complicated with - // having to affect all decsendant element renders. So we just let it write srgb to the render target and - // allow for that when we render using the render target as a source texture. - - for (RenderNode* renderNode : m_childRenderNodes) + // Use a dedicated dynamic draw context for rendering to the texture since it can only have one draw list tag + if (!m_dynamicDraw) { - renderNode->Render(uiRenderer); + m_dynamicDraw = uiRenderer->CreateDynamicDrawContextForRTT(GetRenderTargetName()); } - gEnv->pRenderer->SetRenderTarget(0); // restore render target + if (m_dynamicDraw) + { + UiRenderer::BaseState priorBaseState = uiRenderer->GetBaseState(); - gEnv->pRenderer->Unset2DMode(backupMatrices); + UiRenderer::BaseState curBaseState = priorBaseState; + curBaseState.m_blendState.m_blendAlphaSource = AZ::RHI::BlendFactor::One; + curBaseState.m_blendState.m_blendAlphaDest = AZ::RHI::BlendFactor::AlphaSource1Inverse; + uiRenderer->SetBaseState(curBaseState); + + for (RenderNode* renderNode : m_childRenderNodes) + { + renderNode->Render(uiRenderer, m_modelViewProjMat, m_dynamicDraw); + } + + uiRenderer->SetBaseState(priorBaseState); + } + else + { + AZ_WarningOnce("UI", false, "Failed to create a Dynamic Draw Context for UI Element's render target. "\ + "Please ensure that the custom LyShinePass has been added to the project's main render pipeline."); + } } } //////////////////////////////////////////////////////////////////////////////////////////////////// const char* RenderTargetRenderNode::GetRenderTargetName() const { - ITexture* texture = gEnv->pRenderer->EF_GetTextureByID(m_renderTargetHandle); - return texture->GetName(); + return m_attachmentImage->GetRHIImage()->GetName().GetCStr(); + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + int RenderTargetRenderNode::GetNestLevel() const + { + return m_nestLevel; + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + const AZ::Data::Instance RenderTargetRenderNode::GetRenderTarget() const + { + return m_attachmentImage; } #ifndef _RELEASE @@ -671,31 +671,29 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void RenderGraph::BeginRenderToTexture(int renderTargetHandle, SDepthTexture* renderTargetDepthSurface, + void RenderGraph::BeginRenderToTexture([[maybe_unused]] int renderTargetHandle, [[maybe_unused]] SDepthTexture* renderTargetDepthSurface, + [[maybe_unused]] const AZ::Vector2& viewportTopLeft, [[maybe_unused]] const AZ::Vector2& viewportSize, [[maybe_unused]] const AZ::Color& clearColor) + { + // LYSHINE_ATOM_TODO - this function will be removed when all IRenderer references are gone from UI components + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + void RenderGraph::BeginRenderToTexture(AZ::Data::Instance attachmentImage, const AZ::Vector2& viewportTopLeft, const AZ::Vector2& viewportSize, const AZ::Color& clearColor) { -#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (masks and render targets) // this uses pool allocator RenderTargetRenderNode* renderTargetRenderNode = new RenderTargetRenderNode( - m_currentRenderTarget, renderTargetHandle, renderTargetDepthSurface, + m_currentRenderTarget, attachmentImage, viewportTopLeft, viewportSize, clearColor, m_renderTargetNestLevel); m_currentRenderTarget = renderTargetRenderNode; m_renderNodeListStack.push(&m_currentRenderTarget->GetChildRenderNodeList()); m_renderTargetNestLevel++; -#else - AZ_UNUSED(clearColor); - AZ_UNUSED(viewportSize); - AZ_UNUSED(viewportTopLeft); - AZ_UNUSED(renderTargetDepthSurface); - AZ_UNUSED(renderTargetHandle); -#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// void RenderGraph::EndRenderToTexture() { -#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (masks and render targets) AZ_Assert(m_currentRenderTarget, "Calling EndRenderToTexture while not defining a render target node"); if (m_currentRenderTarget) { @@ -709,7 +707,6 @@ namespace LyShine m_renderNodeListStack.pop(); m_renderTargetNestLevel--; } -#endif } void RenderGraph::AddPrimitive( @@ -803,11 +800,22 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void RenderGraph::AddAlphaMaskPrimitive(IRenderer::DynUiPrimitive* primitive, - ITexture* texture, ITexture* maskTexture, - bool isClampTextureMode, bool isTextureSRGB, bool isTexturePremultipliedAlpha, BlendMode blendMode) + void RenderGraph::AddAlphaMaskPrimitive([[maybe_unused]] IRenderer::DynUiPrimitive* primitive, + [[maybe_unused]] ITexture* texture, [[maybe_unused]] ITexture* maskTexture, + [[maybe_unused]] bool isClampTextureMode, [[maybe_unused]] bool isTextureSRGB, [[maybe_unused]] bool isTexturePremultipliedAlpha, [[maybe_unused]] BlendMode blendMode) + { + // LYSHINE_ATOM_TODO - this function will be removed when all IRenderer references are gone from UI components + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + void RenderGraph::AddAlphaMaskPrimitiveAtom(IRenderer::DynUiPrimitive* primitive, + AZ::Data::Instance contentAttachmentImage, + AZ::Data::Instance maskAttachmentImage, + bool isClampTextureMode, + bool isTextureSRGB, + bool isTexturePremultipliedAlpha, + BlendMode blendMode) { -#ifdef LYSHINE_ATOM_TODO // keeping this code for future phase (masks and render targets) AZStd::vector* renderNodeList = m_renderNodeListStack.top(); int texUnit0 = -1; @@ -842,8 +850,8 @@ namespace LyShine { // render state is the same - we can add the primitive to this list if the texture is in // the list or there is space for another texture - texUnit0 = primListRenderNode->GetOrAddTexture(texture, true); - texUnit1 = primListRenderNode->GetOrAddTexture(maskTexture, true); + texUnit0 = primListRenderNode->GetOrAddTexture(contentAttachmentImage, true); + texUnit1 = primListRenderNode->GetOrAddTexture(maskAttachmentImage, true); if (texUnit0 != -1 && texUnit1 != -1) { @@ -857,7 +865,7 @@ namespace LyShine { // We can't add this primitive to the existing render node, we need to create a new render node // this uses a pool allocator for fast allocation - renderNodeToAddTo = new PrimitiveListRenderNode(texture, maskTexture, + renderNodeToAddTo = new PrimitiveListRenderNode(contentAttachmentImage, maskAttachmentImage, isClampTextureMode, isTextureSRGB, isPreMultiplyAlpha, alphaMaskType, blendModeState); renderNodeList->push_back(renderNodeToAddTo); @@ -881,15 +889,6 @@ namespace LyShine // add this primitive to the render node renderNodeToAddTo->AddPrimitive(primitive); } -#else - AZ_UNUSED(primitive); - AZ_UNUSED(texture); - AZ_UNUSED(maskTexture); - AZ_UNUSED(isClampTextureMode); - AZ_UNUSED(isTextureSRGB); - AZ_UNUSED(isTexturePremultipliedAlpha); - AZ_UNUSED(blendMode); -#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -972,11 +971,8 @@ namespace LyShine } //////////////////////////////////////////////////////////////////////////////////////////////////// - void RenderGraph::Render(UiRenderer* uiRenderer, const AZ::Vector2& viewportSize) + void RenderGraph::Render(UiRenderer* uiRenderer, [[maybe_unused]] const AZ::Vector2& viewportSize) { - // LYSHINE_ATOM_TODO - will probably need to support this when converting UI Editor to use Atom - AZ_UNUSED(viewportSize); - AZ::RHI::Ptr dynamicDraw = uiRenderer->GetDynamicDrawContext(); // Disable stencil and enable blend/color write @@ -984,57 +980,35 @@ namespace LyShine dynamicDraw->SetTarget0BlendState(uiRenderer->GetBaseState().m_blendState); // First render the render targets, they are sorted so that more deeply nested ones are rendered first. - -#ifdef LYSHINE_ATOM_TODO // keeping this code for reference for future phase (render targets) // They only need to be rendered the first time that a render graph is rendered after it has been built. - // Though there is a special case, if this is the first time a shader variant has been used it can miss - // the first render. So to be safe we only stop rendering to render targets after we have rendered to - // them twice with no shader compiles initiated. - if (m_renderToRenderTargetCount < 2) + if (m_renderToRenderTargetCount == 0) + { + // Enable the Rtt passes to draw onto the render targets + SetRttPassesEnabled(uiRenderer, true); + } + + // LYSHINE_ATOM_TODO - It is currently necessary to render to the targets twice. Needs investigation + constexpr int timesToRenderToRenderTargets = 2; + if (m_renderToRenderTargetCount < timesToRenderToRenderTargets) { for (RenderNode* renderNode : m_renderTargetRenderNodes) { - renderNode->Render(uiRenderer); - } - - // if the render targets render OK we don't need to render them every frame. But if a new shader - // variant needed to be compiled then they will not have rendered OK. So we check is there are - // any shaders still in the process of compiling. Because they are compiled on the render - // thread, we may not know until the next frame that a shader needed to be compiled. So we need - // the counter. - SShaderCacheStatistics stats; - gEnv->pRenderer->EF_Query(EFQ_GetShaderCacheInfo, stats); - bool waitingOnShadersToCompile = stats.m_nNumShaderAsyncCompiles > 0 ? true : false; - if (!waitingOnShadersToCompile) - { - m_renderToRenderTargetCount++; - } - else - { - m_renderToRenderTargetCount = 0; + renderNode->Render(uiRenderer, uiRenderer->GetModelViewProjectionMatrix(), dynamicDraw); } + m_renderToRenderTargetCount++; } -#else - for (RenderNode* renderNode : m_renderTargetRenderNodes) + else if (m_renderToRenderTargetCount < timesToRenderToRenderTargets + 1) { - renderNode->Render(uiRenderer); + // Disable the rtt render passes since they don't need to be rendered to until the graph becomes invalidated again. + // This is also necessary to prevent the render targets' contents getting cleared on load by the pass. + SetRttPassesEnabled(uiRenderer, false); + m_renderToRenderTargetCount++; } -#endif -#ifdef LYSHINE_ATOM_TODO // keeping this code for reference for future phase (UI Editor) - // Set2DMode defines the viewport so we set it to canvas viewport here (the render target render nodes - // above will have set the viewport as they needed). - TransformationMatrices backupMatrices; - gEnv->pRenderer->Set2DMode(static_cast(viewportSize.GetX()), static_cast(viewportSize.GetY()), backupMatrices); -#endif for (RenderNode* renderNode : m_renderNodes) { - renderNode->Render(uiRenderer); + renderNode->Render(uiRenderer, uiRenderer->GetModelViewProjectionMatrix(), dynamicDraw); } -#ifdef LYSHINE_ATOM_TODO // keeping this code for reference for future phase (UI Editor) - // end the 2D mode - gEnv->pRenderer->Unset2DMode(backupMatrices); -#endif } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1072,6 +1046,31 @@ namespace LyShine return m_renderNodes.empty(); } + //////////////////////////////////////////////////////////////////////////////////////////////////// + void RenderGraph::GetRenderTargetsAndDependencies(LyShine::AttachmentImagesAndDependencies& attachmentImagesAndDependencies) + { + for (RenderNode* renderNode : m_renderTargetRenderNodes) + { + const RenderTargetRenderNode* renderTargetRenderNode = static_cast(renderNode); + + if (renderTargetRenderNode->GetNestLevel() == 0) + { + LyShine::AttachmentImages attachmentImages; + const AZStd::vector& childNodeList = renderTargetRenderNode->GetChildRenderNodeList(); + for (auto& childNode : childNodeList) + { + if (childNode->GetType() == RenderNodeType::RenderTarget) + { + const RenderTargetRenderNode* childRenderTargetRenderNode = static_cast(childNode); + attachmentImages.emplace_back(childRenderTargetRenderNode->GetRenderTarget()); + } + } + + attachmentImagesAndDependencies.emplace_back(AttachmentImageAndDependentsPair(renderTargetRenderNode->GetRenderTarget(), attachmentImages)); + } + } + } + #ifndef _RELEASE //////////////////////////////////////////////////////////////////////////////////////////////////// void RenderGraph::ValidateGraph() @@ -1128,7 +1127,7 @@ namespace LyShine // walk the graph recursively to add up all of the data GetDebugInfoRenderNodeList(m_renderNodes, info, uniqueTextures); - info.m_numUniqueTextures = uniqueTextures.size(); + info.m_numUniqueTextures = static_cast(uniqueTextures.size()); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1183,7 +1182,7 @@ namespace LyShine const PrimitiveListRenderNode* primListRenderNode = static_cast(renderNode); IRenderer::DynUiPrimitiveList& primitives = primListRenderNode->GetPrimitives(); - info.m_numPrimitives += primitives.size(); + info.m_numPrimitives += static_cast(primitives.size()); { for (const IRenderer::DynUiPrimitive& primitive : primitives) { @@ -1367,7 +1366,7 @@ namespace LyShine } IRenderer::DynUiPrimitiveList& primitives = primListRenderNode->GetPrimitives(); - int numPrimitives = primitives.size(); + int numPrimitives = static_cast(primitives.size()); int numTriangles = 0; for (const IRenderer::DynUiPrimitive& primitive : primitives) { @@ -1540,4 +1539,19 @@ namespace LyShine return flags; } + void RenderGraph::SetRttPassesEnabled(UiRenderer* uiRenderer, bool enabled) + { + // Enable or disable the rtt render passes + AZ::RPI::SceneId sceneId = uiRenderer->GetViewportContext()->GetRenderScene()->GetId(); + for (RenderTargetRenderNode* renderTargetRenderNode : m_renderTargetRenderNodes) + { + // Find the rtt pass to disable + AZ::RPI::RasterPass* rttPass = nullptr; + LyShinePassRequestBus::EventResult(rttPass, sceneId, &LyShinePassRequestBus::Events::GetRttPass, renderTargetRenderNode->GetRenderTargetName()); + if (rttPass) + { + rttPass->SetEnabled(enabled); + } + } + } } diff --git a/Gems/LyShine/Code/Source/RenderGraph.h b/Gems/LyShine/Code/Source/RenderGraph.h index 2529c0f47e..bc5bd094c8 100644 --- a/Gems/LyShine/Code/Source/RenderGraph.h +++ b/Gems/LyShine/Code/Source/RenderGraph.h @@ -15,10 +15,13 @@ #include #include +#include #include +#include #include #include "UiRenderer.h" +#include "LyShinePass.h" #ifndef _RELEASE #include "LyShineDebug.h" #endif @@ -46,7 +49,9 @@ namespace LyShine RenderNode(RenderNodeType type) : m_type(type) {} virtual ~RenderNode() {}; - virtual void Render(UiRenderer* uiRenderer) = 0; + virtual void Render(UiRenderer* uiRenderer + , const AZ::Matrix4x4& modelViewProjMat + , AZ::RHI::Ptr dynamicDraw) = 0; RenderNodeType GetType() const { return m_type; } @@ -70,7 +75,9 @@ namespace LyShine PrimitiveListRenderNode(const AZ::Data::Instance& texture, const AZ::Data::Instance& maskTexture, bool isClampTextureMode, bool isTextureSRGB, bool preMultiplyAlpha, AlphaMaskType alphaMaskType, int blendModeState); ~PrimitiveListRenderNode() override; - void Render(UiRenderer* uiRenderer) override; + void Render(UiRenderer* uiRenderer + , const AZ::Matrix4x4& modelViewProjMat + , AZ::RHI::Ptr dynamicDraw) override; void AddPrimitive(IRenderer::DynUiPrimitive* primitive); IRenderer::DynUiPrimitiveList& GetPrimitives() const; @@ -128,7 +135,9 @@ namespace LyShine MaskRenderNode(MaskRenderNode* parentMask, bool isMaskingEnabled, bool useAlphaTest, bool drawBehind, bool drawInFront); ~MaskRenderNode() override; - void Render(UiRenderer* uiRenderer) override; + void Render(UiRenderer* uiRenderer + , const AZ::Matrix4x4& modelViewProjMat + , AZ::RHI::Ptr dynamicDraw) override; AZStd::vector& GetMaskRenderNodeList() { return m_maskRenderNodes; } const AZStd::vector& GetMaskRenderNodeList() const { return m_maskRenderNodes; } @@ -152,8 +161,12 @@ namespace LyShine #endif private: // functions - void SetupBeforeRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState); - void SetupAfterRenderingMask(UiRenderer* uiRenderer, bool firstPass, UiRenderer::BaseState priorBaseState); + void SetupBeforeRenderingMask(UiRenderer* uiRenderer, + AZ::RHI::Ptr dynamicDraw, + bool firstPass, UiRenderer::BaseState priorBaseState); + void SetupAfterRenderingMask(UiRenderer* uiRenderer, + AZ::RHI::Ptr dynamicDraw, + bool firstPass, UiRenderer::BaseState priorBaseState); private: // data AZStd::vector m_maskRenderNodes; //!< The render nodes used to render the mask shape @@ -175,15 +188,17 @@ namespace LyShine // We use a pool allocator to keep these allocations fast. AZ_CLASS_ALLOCATOR(RenderTargetRenderNode, AZ::PoolAllocator, 0); - RenderTargetRenderNode(RenderTargetRenderNode* parentRenderTarget, int renderTargetHandle, - SDepthTexture* renderTargetDepthSurface, + RenderTargetRenderNode(RenderTargetRenderNode* parentRenderTarget, + AZ::Data::Instance attachmentImage, const AZ::Vector2& viewportTopLeft, const AZ::Vector2& viewportSize, const AZ::Color& clearColor, int nestLevel); ~RenderTargetRenderNode() override; - void Render(UiRenderer* uiRenderer) override; + void Render(UiRenderer* uiRenderer + , const AZ::Matrix4x4& modelViewProjMat + , AZ::RHI::Ptr dynamicDraw) override; AZStd::vector& GetChildRenderNodeList() { return m_childRenderNodes; } const AZStd::vector& GetChildRenderNodeList() const { return m_childRenderNodes; } @@ -197,6 +212,9 @@ namespace LyShine AZ::Color GetClearColor() const { return m_clearColor; } const char* GetRenderTargetName() const; + int GetNestLevel() const; + + const AZ::Data::Instance GetRenderTarget() const; #ifndef _RELEASE // A debug-only function useful for debugging @@ -213,13 +231,16 @@ namespace LyShine RenderTargetRenderNode* m_parentRenderTarget = nullptr; //! Used while building the render graph. - int m_renderTargetHandle = -1; - SDepthTexture* m_renderTargetDepthSurface = nullptr; + AZ::Data::Instance m_attachmentImage; + + // Each render target requires a unique dynamic draw context to draw to the raster pass associated with the target + AZ::RHI::Ptr m_dynamicDraw; float m_viewportX = 0; float m_viewportY = 0; float m_viewportWidth = 0; float m_viewportHeight = 0; + AZ::Matrix4x4 m_modelViewProjMat; AZ::Color m_clearColor; int m_nestLevel = 0; }; @@ -241,9 +262,10 @@ namespace LyShine void StartChildrenForMask() override; void EndMask() override; + //! Begin rendering to a texture void BeginRenderToTexture(int renderTargetHandle, SDepthTexture* renderTargetDepthSurface, - const AZ::Vector2& viewportTopLeft, const AZ::Vector2& viewportSize, - const AZ::Color& clearColor) override; + const AZ::Vector2& viewportTopLeft, const AZ::Vector2& viewportSize, const AZ::Color& clearColor) override; + void EndRenderToTexture() override; void AddPrimitive(IRenderer::DynUiPrimitive* primitive, ITexture* texture, @@ -268,6 +290,20 @@ namespace LyShine void AddPrimitiveAtom(IRenderer::DynUiPrimitive* primitive, const AZ::Data::Instance& texture, bool isClampTextureMode, bool isTextureSRGB, bool isTexturePremultipliedAlpha, BlendMode blendMode); + //! Add an indexed triangle list primitive to the render graph which will use maskTexture as an alpha (gradient) mask + void AddAlphaMaskPrimitiveAtom(IRenderer::DynUiPrimitive* primitive, + AZ::Data::Instance contentAttachmentImage, + AZ::Data::Instance maskAttachmentImage, + bool isClampTextureMode, + bool isTextureSRGB, + bool isTexturePremultipliedAlpha, + BlendMode blendMode); + + void BeginRenderToTexture(AZ::Data::Instance attachmentImage, + const AZ::Vector2& viewportTopLeft, + const AZ::Vector2& viewportSize, + const AZ::Color& clearColor); + //! Render the display graph void Render(UiRenderer* uiRenderer, const AZ::Vector2& viewportSize); @@ -283,6 +319,8 @@ namespace LyShine //! Test whether the render graph contains any render nodes bool IsEmpty(); + void GetRenderTargetsAndDependencies(LyShine::AttachmentImagesAndDependencies& attachmentImagesAndDependencies); + #ifndef _RELEASE // A debug-only function useful for debugging, not called but calls can be added during debugging void ValidateGraph(); @@ -311,6 +349,8 @@ namespace LyShine //! Given a blend mode and whether the shader will be outputing premultiplied alpha, return state flags int GetBlendModeState(LyShine::BlendMode blendMode, bool isShaderOutputPremultAlpha) const; + void SetRttPassesEnabled(UiRenderer* uiRenderer, bool enabled); + protected: // data AZStd::vector m_renderNodes; diff --git a/Gems/LyShine/Code/Source/RenderToTextureBus.h b/Gems/LyShine/Code/Source/RenderToTextureBus.h new file mode 100644 index 0000000000..310f1f93cf --- /dev/null +++ b/Gems/LyShine/Code/Source/RenderToTextureBus.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +namespace LyShine +{ + //! Ebus to handle render target requests + class RenderToTextureRequests + : public AZ::ComponentBus + { + public: + virtual AZ::RHI::AttachmentId UseRenderTarget(const AZ::Name& renderTargetName, AZ::RHI::Size size) = 0; + virtual void ReleaseRenderTarget(const AZ::RHI::AttachmentId& attachmentId) = 0; + virtual AZ::Data::Instance GetRenderTarget(const AZ::RHI::AttachmentId& attachmentId) = 0; + }; + + using RenderToTextureRequestBus = AZ::EBus; +} diff --git a/Gems/LyShine/Code/Source/Sprite.cpp b/Gems/LyShine/Code/Source/Sprite.cpp index 0e0edb8e34..a097e23dfe 100644 --- a/Gems/LyShine/Code/Source/Sprite.cpp +++ b/Gems/LyShine/Code/Source/Sprite.cpp @@ -273,7 +273,7 @@ void CSprite::Serialize(TSerialize ser) if (hasSpriteSheetCells && ser.BeginOptionalGroup("SpriteSheet", true)) { - const int numSpriteSheetCells = ser.IsReading() ? m_numSpriteSheetCellTags : GetSpriteSheetCells().size(); + const int numSpriteSheetCells = static_cast(ser.IsReading() ? m_numSpriteSheetCellTags : GetSpriteSheetCells().size()); for (int i = 0; i < numSpriteSheetCells; ++i) { ser.BeginOptionalGroup("Cell", true); diff --git a/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp b/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp index 8cf2cd2edb..05e670fdd5 100644 --- a/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp +++ b/Gems/LyShine/Code/Source/Tests/internal/test_UiTextComponent.cpp @@ -2716,7 +2716,7 @@ namespace float newWidth; EBUS_EVENT_ID_RESULT(newWidth, testElemId, UiLayoutCellDefaultBus, GetTargetWidth, LyShine::UiLayoutCellUnspecifiedSize); - const int testStringLength = testString.length(); + const int testStringLength = static_cast(testString.length()); const int numGapsBetweenCharacters = testStringLength >= 1 ? testStringLength - 1 : 0; const float ems = characterSpacing * 0.001f; float expectedWidth = baseWidth + numGapsBetweenCharacters * ems * fontSize; diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp index b665f039b0..9d17f90f0b 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp @@ -49,6 +49,8 @@ #include #include +#include +#include #include "Animation/UiAnimationSystem.h" @@ -64,6 +66,8 @@ #include #endif +#include "LyShinePassDataBus.h" + //////////////////////////////////////////////////////////////////////////////////////////////////// //! UiCanvasNotificationBus Behavior context handler class class UiCanvasNotificationBusBehaviorHandler @@ -251,14 +255,22 @@ namespace UiRenderer* GetUiRendererForGame() { - CLyShine* lyShine = static_cast(gEnv->pLyShine); - return lyShine ? lyShine->GetUiRenderer() : nullptr; + if (gEnv && gEnv->pLyShine) + { + CLyShine* lyShine = static_cast(gEnv->pLyShine); + return lyShine->GetUiRenderer(); + } + return nullptr; } UiRenderer* GetUiRendererForEditor() { - CLyShine* lyShine = static_cast(gEnv->pLyShine); - return lyShine ? lyShine->GetUiRendererForEditor() : nullptr; + if (gEnv && gEnv->pLyShine) + { + CLyShine* lyShine = static_cast(gEnv->pLyShine); + return lyShine->GetUiRendererForEditor(); + } + return nullptr; } bool IsValidInteractable(const AZ::EntityId& entityId) @@ -705,7 +717,7 @@ AZStd::string UiCanvasComponent::GetUniqueChildName(AZ::EntityId parentEntityId, // Count trailing digits in base name int i; - for (i = baseName.length() - 1; i >= 0; i--) + for (i = static_cast(baseName.length() - 1); i >= 0; i--) { if (!isdigit(baseName[i])) { @@ -713,7 +725,7 @@ AZStd::string UiCanvasComponent::GetUniqueChildName(AZ::EntityId parentEntityId, } } int startDigitIndex = i + 1; - int numDigits = baseName.length() - startDigitIndex; + int numDigits = static_cast(baseName.length() - startDigitIndex); int suffix = 1; if (numDigits > 0) @@ -737,7 +749,7 @@ AZStd::string UiCanvasComponent::GetUniqueChildName(AZ::EntityId parentEntityId, AZStd::string suffixString = AZStd::string::format("%d", suffix); // Append leading zeros - int numLeadingZeros = (suffixString.length() < numDigits) ? numDigits - suffixString.length() : 0; + int numLeadingZeros = static_cast((suffixString.length() < numDigits) ? numDigits - suffixString.length() : 0); for (int zeroes = 0; zeroes < numLeadingZeros; zeroes++) { proposedChildName.push_back('0'); @@ -1829,6 +1841,46 @@ void UiCanvasComponent::MarkRenderGraphDirty() } } +//////////////////////////////////////////////////////////////////////////////////////////////////// +AZ::RHI::AttachmentId UiCanvasComponent::UseRenderTarget(const AZ::Name& renderTargetName, AZ::RHI::Size size) +{ + // Create a render target that UI elements will render to + AZ::RHI::ImageDescriptor imageDesc; + imageDesc.m_bindFlags = AZ::RHI::ImageBindFlags::Color | AZ::RHI::ImageBindFlags::ShaderReadWrite; + imageDesc.m_size = size; + imageDesc.m_format = AZ::RHI::Format::R8G8B8A8_UNORM; + + AZ::Data::Instance pool = AZ::RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool(); + auto attachmentImage = AZ::RPI::AttachmentImage::Create(*pool.get(), imageDesc, renderTargetName); + if (!attachmentImage) + { + AZ_Warning("UI", false, "Failed to create render target"); + return AZ::RHI::AttachmentId(); + } + + m_attachmentImageMap[attachmentImage->GetAttachmentId()] = attachmentImage; + + // Notify LyShine render pass that it needs to rebuild + QueueRttPassRebuild(); + + return attachmentImage->GetAttachmentId(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void UiCanvasComponent::ReleaseRenderTarget(const AZ::RHI::AttachmentId& attachmentId) +{ + m_attachmentImageMap.erase(attachmentId); + + // Notify LyShine render pass that it needs to rebuild + QueueRttPassRebuild(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +AZ::Data::Instance UiCanvasComponent::GetRenderTarget(const AZ::RHI::AttachmentId& attachmentId) +{ + return m_attachmentImageMap[attachmentId]; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void UiCanvasComponent::UpdateCanvas(float deltaTime, bool isInGame) { @@ -1864,6 +1916,8 @@ void UiCanvasComponent::RenderCanvas(bool isInGame, AZ::Vector2 viewportSize, Ui return; } + m_renderInEditor = uiRenderer ? true : false; + if (!uiRenderer) { uiRenderer = GetUiRendererForGame(); @@ -1948,6 +2002,12 @@ void UiCanvasComponent::ScheduleElementDestroy(AZ::EntityId entityId) m_elementsScheduledForDestroy.push_back(entityId); } +//////////////////////////////////////////////////////////////////////////////////////////////////// +void UiCanvasComponent::GetRenderTargets(LyShine::AttachmentImagesAndDependencies& attachmentImagesAndDependencies) +{ + m_renderGraph.GetRenderTargetsAndDependencies(attachmentImagesAndDependencies); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void UiCanvasComponent::DestroyScheduledElements() { @@ -1959,6 +2019,17 @@ void UiCanvasComponent::DestroyScheduledElements() m_elementsScheduledForDestroy.clear(); } +//////////////////////////////////////////////////////////////////////////////////////////////////// +void UiCanvasComponent::QueueRttPassRebuild() +{ + UiRenderer* uiRenderer = m_renderInEditor ? GetUiRendererForEditor() : GetUiRendererForGame(); + if (uiRenderer && uiRenderer->GetViewportContext()) // can be null in automated testing + { + AZ::RPI::SceneId sceneId = uiRenderer->GetViewportContext()->GetRenderScene()->GetId(); + EBUS_EVENT_ID(sceneId, LyShinePassRequestBus, RebuildRttChildren); + } +} + //////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _RELEASE void UiCanvasComponent::GetDebugInfoInteractables(AZ::EntityId& activeInteractable, AZ::EntityId& hoverInteractable) const @@ -1978,7 +2049,7 @@ void UiCanvasComponent::GetDebugInfoNumElements(DebugInfoNumElements& info) cons info.m_numMaskElements = 0; info.m_numFaderElements = 0; info.m_numInteractableElements = 0; - info.m_numUpdateElements = UiCanvasUpdateNotificationBus::GetNumOfEventHandlers(GetEntityId()); + info.m_numUpdateElements = static_cast(UiCanvasUpdateNotificationBus::GetNumOfEventHandlers(GetEntityId())); DebugInfoCountChildren(m_rootElement, true, info); } @@ -2350,6 +2421,7 @@ void UiCanvasComponent::Activate() UiCanvasComponentImplementationBus::Handler::BusConnect(m_entity->GetId()); UiEditorCanvasBus::Handler::BusConnect(m_entity->GetId()); UiAnimationBus::Handler::BusConnect(m_entity->GetId()); + LyShine::RenderToTextureRequestBus::Handler::BusConnect(m_entity->GetId()); // Reconnect to buses that we connect to intermittently // This will only happen if we have been deactivated and reactivated at runtime @@ -2382,6 +2454,7 @@ void UiCanvasComponent::Deactivate() UiCanvasComponentImplementationBus::Handler::BusDisconnect(); UiEditorCanvasBus::Handler::BusDisconnect(); UiAnimationBus::Handler::BusDisconnect(); + LyShine::RenderToTextureRequestBus::Handler::BusDisconnect(); // disconnect from any other buses we could be connected to if (m_hoverInteractable.IsValid() && AZ::EntityBus::Handler::BusIsConnectedId(m_hoverInteractable)) @@ -2400,6 +2473,12 @@ void UiCanvasComponent::Deactivate() DestroyRenderTarget(); } + // Destroy owned render targets + m_attachmentImageMap.clear(); + + //! Notify LyShine pass that it needs to rebuild + QueueRttPassRebuild(); + delete m_layoutManager; m_layoutManager = nullptr; diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.h b/Gems/LyShine/Code/Source/UiCanvasComponent.h index 097f23cbda..79cb044af0 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.h +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.h @@ -32,6 +32,8 @@ #include "TextureAtlas/TextureAtlasBus.h" #include "TextureAtlas/TextureAtlasNotificationBus.h" +#include "RenderToTextureBus.h" + namespace AZ { class SerializeContext; @@ -51,6 +53,7 @@ class UiCanvasComponent , public IUiAnimationListener , public UiEditorCanvasBus::Handler , public UiCanvasComponentImplementationBus::Handler + , public LyShine::RenderToTextureRequestBus::Handler { public: // constants static const AZ::Vector2 s_defaultCanvasSize; @@ -232,6 +235,12 @@ public: // member functions void MarkRenderGraphDirty() override; // ~UiCanvasComponentImplementationInterface + // RenderToTextureRequests + AZ::RHI::AttachmentId UseRenderTarget(const AZ::Name& renderTargetName, AZ::RHI::Size size) override; + void ReleaseRenderTarget(const AZ::RHI::AttachmentId& attachmentId) override; + AZ::Data::Instance GetRenderTarget(const AZ::RHI::AttachmentId& attachmentId) override; + // ~RenderToTextureRequests + void UpdateCanvas(float deltaTime, bool isInGame); void RenderCanvas(bool isInGame, AZ::Vector2 viewportSize, UiRenderer* uiRenderer = nullptr); @@ -257,6 +266,10 @@ public: // member functions //! Queue an element to be destroyed at end of frame void ScheduleElementDestroy(AZ::EntityId entityId); + bool IsRenderGraphDirty() { return m_renderGraph.GetDirtyFlag(); } + + void GetRenderTargets(LyShine::AttachmentImagesAndDependencies& attachmentImagesAndDependencies); + #ifndef _RELEASE struct DebugInfoNumElements { @@ -427,6 +440,9 @@ private: // member functions void DestroyScheduledElements(); + //! Notify LyShine pass that it needs to rebuild its Rtt child passes + void QueueRttPassRebuild(); + private: // static member functions static AZ::u64 CreateUniqueId(); @@ -597,4 +613,8 @@ private: // static data LyShine::RenderGraph m_renderGraph; //!< the render graph for rendering the canvas, can be cached between frames bool m_isRendering = false; + bool m_renderInEditor = false; //!< indicates whether this canvas will render in the Editor viewport or the Game viewport + + //! Map of attachments used by this canvas's elements + AZStd::unordered_map> m_attachmentImageMap; }; diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.cpp b/Gems/LyShine/Code/Source/UiCanvasManager.cpp index bed3bcf433..5f2adcd20c 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasManager.cpp @@ -301,6 +301,17 @@ void UiCanvasManager::OnFontTextureUpdated([[maybe_unused]] IFFont* font) m_fontTextureHasChanged = true; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +void UiCanvasManager::GetRenderTargets(LyShine::AttachmentImagesAndDependencies& attachmentImagesAndDependencies) +{ + for (auto canvas : m_loadedCanvases) + { + LyShine::AttachmentImagesAndDependencies canvasTargets; + canvas->GetRenderTargets(canvasTargets); + attachmentImagesAndDependencies.insert(attachmentImagesAndDependencies.end(), canvasTargets.begin(), canvasTargets.end()); + } +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void UiCanvasManager::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) { @@ -606,13 +617,6 @@ void UiCanvasManager::RenderLoadedCanvases() m_fontTextureHasChanged = false; } -#ifdef LYSHINE_ATOM_TODO // render target conversion to Atom - // clear the stencil buffer before rendering the loaded canvases - required for masking - // NOTE: We want to use ClearTargetsImmediately instead of ClearTargetsLater since we will not be setting the render target - ColorF viewportBackgroundColor(0, 0, 0, 0); // if clearing color we want to set alpha to zero also - gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR_STENCIL, viewportBackgroundColor); -#endif - for (auto canvas : m_loadedCanvases) { if (!canvas->GetIsRenderToTexture()) diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.h b/Gems/LyShine/Code/Source/UiCanvasManager.h index ebcee200e4..1d8a77a673 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.h +++ b/Gems/LyShine/Code/Source/UiCanvasManager.h @@ -11,6 +11,7 @@ #include #include #include +#include "LyShinePassDataBus.h" #include class UiCanvasComponent; @@ -92,6 +93,9 @@ public: // member functions bool HandleInputEventForLoadedCanvases(const AzFramework::InputChannel& inputChannel); bool HandleTextEventForLoadedCanvases(const AZStd::string& textUTF8); + // Get the render targets used by all currently loaded UI Canvases + void GetRenderTargets(LyShine::AttachmentImagesAndDependencies& attachmentImagesAndDependencies); + #ifndef _RELEASE void DebugDisplayCanvasData(int setting) const; void DebugDisplayDrawCallData() const; diff --git a/Gems/LyShine/Code/Source/UiDynamicScrollBoxComponent.cpp b/Gems/LyShine/Code/Source/UiDynamicScrollBoxComponent.cpp index 30df88da2b..83c4a2d02a 100644 --- a/Gems/LyShine/Code/Source/UiDynamicScrollBoxComponent.cpp +++ b/Gems/LyShine/Code/Source/UiDynamicScrollBoxComponent.cpp @@ -1179,7 +1179,7 @@ void UiDynamicScrollBoxComponent::ResizeContentToFitElements() } else { - int numHeaders = m_sections.size(); + int numHeaders = static_cast(m_sections.size()); int numItems = m_numElements - numHeaders; newSize = numHeaders * m_prototypeElementSize[ElementType::SectionHeader] + numItems * m_prototypeElementSize[ElementType::Item]; } @@ -1201,7 +1201,7 @@ void UiDynamicScrollBoxComponent::ResizeContentToFitElements() } else { - int numHeaders = m_sections.size(); + int numHeaders = static_cast(m_sections.size()); int numItems = m_numElements - numHeaders; newSize = numHeaders * m_estimatedElementSize[ElementType::SectionHeader] + numItems * m_estimatedElementSize[ElementType::Item]; } @@ -1555,7 +1555,7 @@ float UiDynamicScrollBoxComponent::GetFixedSizeElementOffset(int index) const int numHeaders = 0; int numItems = 0; - int numSections = m_sections.size(); + int numSections = static_cast(m_sections.size()); if (numSections > 0) { if (index > m_sections[numSections - 1].m_headerElementIndex) diff --git a/Gems/LyShine/Code/Source/UiElementComponent.cpp b/Gems/LyShine/Code/Source/UiElementComponent.cpp index 388b280e9f..d06b87cf6a 100644 --- a/Gems/LyShine/Code/Source/UiElementComponent.cpp +++ b/Gems/LyShine/Code/Source/UiElementComponent.cpp @@ -142,7 +142,7 @@ void UiElementComponent::RenderElement(LyShine::IRenderGraph* renderGraph, bool if (m_renderControlInterface) { // give control of rendering this element and its children to the render control component on this element - m_renderControlInterface->Render(renderGraph, this, m_renderInterface, m_childElementComponents.size(), isInGame); + m_renderControlInterface->Render(renderGraph, this, m_renderInterface, static_cast(m_childElementComponents.size()), isInGame); } else { @@ -153,7 +153,7 @@ void UiElementComponent::RenderElement(LyShine::IRenderGraph* renderGraph, bool } // now render child elements - int numChildren = m_childElementComponents.size(); + int numChildren = static_cast(m_childElementComponents.size()); for (int i = 0; i < numChildren; ++i) { GetChildElementComponent(i)->RenderElement(renderGraph, isInGame); @@ -194,7 +194,7 @@ AZ::EntityId UiElementComponent::GetParentEntityId() //////////////////////////////////////////////////////////////////////////////////////////////////// int UiElementComponent::GetNumChildElements() { - return m_childEntityIdOrder.size(); + return static_cast(m_childEntityIdOrder.size()); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -236,7 +236,7 @@ UiElementInterface* UiElementComponent::GetChildElementInterface(int index) int UiElementComponent::GetIndexOfChild(const AZ::Entity* child) { AZ::EntityId childEntityId = child->GetId(); - int numChildren = m_childEntityIdOrder.size(); + int numChildren = static_cast(m_childEntityIdOrder.size()); for (int i = 0; i < numChildren; ++i) { if (m_childEntityIdOrder[i].m_entityId == childEntityId) @@ -251,7 +251,7 @@ int UiElementComponent::GetIndexOfChild(const AZ::Entity* child) //////////////////////////////////////////////////////////////////////////////////////////////////// int UiElementComponent::GetIndexOfChildByEntityId(AZ::EntityId childId) { - int numChildren = m_childEntityIdOrder.size(); + int numChildren = static_cast(m_childEntityIdOrder.size()); for (int i = 0; i < numChildren; ++i) { if (m_childEntityIdOrder[i].m_entityId == childId) @@ -266,7 +266,7 @@ int UiElementComponent::GetIndexOfChildByEntityId(AZ::EntityId childId) //////////////////////////////////////////////////////////////////////////////////////////////////// LyShine::EntityArray UiElementComponent::GetChildElements() { - int numChildren = m_childEntityIdOrder.size(); + int numChildren = static_cast(m_childEntityIdOrder.size()); LyShine::EntityArray children; children.reserve(numChildren); @@ -477,7 +477,7 @@ AZ::Entity* UiElementComponent::FindFrontmostChildContainingPoint(AZ::Vector2 po // this traverses all of the elements in reverse hierarchy order and returns the first one that // is containing the point. // If necessary, this could be optimized using a spatial partitioning data structure. - for (int i = m_childEntityIdOrder.size() - 1; !matchElem && i >= 0; i--) + for (int i = static_cast(m_childEntityIdOrder.size() - 1); !matchElem && i >= 0; i--) { AZ::EntityId child = m_childEntityIdOrder[i].m_entityId; @@ -602,7 +602,7 @@ AZ::EntityId UiElementComponent::FindInteractableToHandleEvent(AZ::Vector2 point EBUS_EVENT_ID_RESULT(isMasked, GetEntityId(), UiInteractionMaskBus, IsPointMasked, point); if (!isMasked) { - for (int i = m_childEntityIdOrder.size() - 1; !result.IsValid() && i >= 0; i--) + for (int i = static_cast(m_childEntityIdOrder.size() - 1); !result.IsValid() && i >= 0; i--) { result = GetChildElementComponent(i)->FindInteractableToHandleEvent(point); } @@ -674,7 +674,7 @@ AZ::Entity* UiElementComponent::FindChildByName(const LyShine::NameType& name) if (AreChildPointersValid()) { - int numChildren = m_childElementComponents.size(); + int numChildren = static_cast(m_childElementComponents.size()); for (int i = 0; i < numChildren; ++i) { AZ::Entity* childEntity = GetChildElementComponent(i)->GetEntity(); @@ -709,7 +709,7 @@ AZ::Entity* UiElementComponent::FindDescendantByName(const LyShine::NameType& na if (AreChildPointersValid()) { - int numChildren = m_childElementComponents.size(); + int numChildren = static_cast(m_childElementComponents.size()); for (int i = 0; i < numChildren; ++i) { UiElementComponent* childElementComponent = GetChildElementComponent(i); @@ -771,7 +771,7 @@ AZ::Entity* UiElementComponent::FindChildByEntityId(AZ::EntityId id) { AZ::Entity* matchElem = nullptr; - int numChildren = m_childEntityIdOrder.size(); + int numChildren = static_cast(m_childEntityIdOrder.size()); for (int i = 0; i < numChildren; ++i) { if (id == m_childEntityIdOrder[i].m_entityId) @@ -803,7 +803,7 @@ AZ::Entity* UiElementComponent::FindDescendantById(LyShine::ElementId id) if (AreChildPointersValid()) { - int numChildren = m_childEntityIdOrder.size(); + int numChildren = static_cast(m_childEntityIdOrder.size()); for (int i = 0; !match && i < numChildren; ++i) { match = GetChildElementComponent(i)->FindDescendantById(id); @@ -825,7 +825,7 @@ void UiElementComponent::FindDescendantElements(AZStd::function(m_childElementComponents.size()); for (int i = 0; i < numChildren; ++i) { UiElementComponent* childElementComponent = GetChildElementComponent(i); @@ -860,7 +860,7 @@ void UiElementComponent::CallOnDescendantElements(AZStd::function(m_childEntityIdOrder.size()); for (int i = 0; i < numChildren; ++i) { callFunction(m_childEntityIdOrder[i].m_entityId); @@ -1068,7 +1068,7 @@ void UiElementComponent::AddChild(AZ::Entity* child, AZ::Entity* insertBefore) if (insertBefore) { - int numChildren = m_childEntityIdOrder.size(); + int numChildren = static_cast(m_childEntityIdOrder.size()); for (int i = 0; i < numChildren; ++i) { if (m_childEntityIdOrder[i].m_entityId == insertBefore->GetId()) @@ -1211,8 +1211,8 @@ bool UiElementComponent::FixupPostLoad(AZ::Entity* entity, UiCanvasComponent* ca #ifdef AZ_DEBUG_BUILD // check that the m_childEntityIdOrder is ordered such that the m_sortIndex fields are in order and contiguous { - int numChildren = m_childEntityIdOrder.size(); - for (AZ::u64 index = 0; index < numChildren; ++index) + size_t numChildren = m_childEntityIdOrder.size(); + for (size_t index = 0; index < numChildren; ++index) { if (m_childEntityIdOrder[index].m_sortIndex != index) { @@ -1696,7 +1696,7 @@ void UiElementComponent::OnPatchEnd(const AZ::DataPatchNodeInfo& patchInfo) // the lookupAddress is the same length as the "Children" address plus an index // check if the address is childrenAddress plus an extra element bool match = true; - for (int i = childrenAddress.size() - 1; i >= 0; --i) + for (int i = static_cast(childrenAddress.size() - 1); i >= 0; --i) { if (lookupAddress[i] != childrenAddress[i]) { @@ -1827,7 +1827,7 @@ void UiElementComponent::OnPatchEnd(const AZ::DataPatchNodeInfo& patchInfo) // This will sort all the entity order entries by sort index (primary) and entity id (secondary) which should never result in any collisions // This is used since slice data patching may create duplicate entries for the same sort index, missing indices and the like. // It should never result in multiple entity id entries since the serialization of this data uses a persistent id which is the entity id - int numChildren = m_childEntityIdOrder.size(); + int numChildren = static_cast(m_childEntityIdOrder.size()); if (numChildren > 0) { AZStd::sort(m_childEntityIdOrder.begin(), m_childEntityIdOrder.end()); diff --git a/Gems/LyShine/Code/Source/UiFaderComponent.cpp b/Gems/LyShine/Code/Source/UiFaderComponent.cpp index dbc3981056..f195689a43 100644 --- a/Gems/LyShine/Code/Source/UiFaderComponent.cpp +++ b/Gems/LyShine/Code/Source/UiFaderComponent.cpp @@ -6,6 +6,7 @@ * */ #include "UiFaderComponent.h" +#include "RenderGraph.h" #include #include @@ -14,6 +15,9 @@ #include #include +#include +#include + #include #include #include @@ -22,6 +26,7 @@ #include #include "UiSerialize.h" +#include "RenderToTextureBus.h" // BehaviorContext UiFaderNotificationBus forwarder class BehaviorUiFaderNotificationBusHandler @@ -120,7 +125,7 @@ void UiFaderComponent::Render(LyShine::IRenderGraph* renderGraph, UiElementInter AZ::Vector2 renderTargetSize = pixelAlignedBottomRight - pixelAlignedTopLeft; bool needsResize = static_cast(renderTargetSize.GetX()) != m_renderTargetWidth || static_cast(renderTargetSize.GetY()) != m_renderTargetHeight; - if (m_renderTargetHandle == -1 || needsResize) + if (m_attachmentImageId.IsEmpty() || needsResize) { // We delay first creation of the render target until render time since size is not known in Activate // We also call this if the size has changed @@ -128,7 +133,7 @@ void UiFaderComponent::Render(LyShine::IRenderGraph* renderGraph, UiElementInter } // if the render target failed to be created (zero size for example) we don't render the element at all - if (m_renderTargetHandle == -1) + if (m_attachmentImageId.IsEmpty()) { return; } @@ -139,7 +144,7 @@ void UiFaderComponent::Render(LyShine::IRenderGraph* renderGraph, UiElementInter else { // destroy previous render target, if exists - if (m_renderTargetHandle != -1) + if (!m_attachmentImageId.IsEmpty()) { DestroyRenderTarget(); } @@ -452,54 +457,22 @@ void UiFaderComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligne m_viewportTopLeft = pixelAlignedTopLeft; m_viewportSize = renderTargetSize; -#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom - // Check if the render target already exists - if (m_renderTargetHandle != -1) - { - // Render target exists, resize it to the given size - if (!gEnv->pRenderer->ResizeRenderTarget(m_renderTargetHandle, static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY()))) - { - AZ_Warning("UI", false, "Failed to resize render target for UiFaderComponent"); - DestroyRenderTarget(); - } - } - else - { - // Create a render target that this element and its children will be rendered to. - m_renderTargetHandle = gEnv->pRenderer->CreateRenderTarget(m_renderTargetName.c_str(), - static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY()), Clr_Transparent, eTF_R8G8B8A8); + // LYSHINE_ATOM_TODO: optimize by reusing/resizing targets + DestroyRenderTarget(); - if (m_renderTargetHandle == -1) - { - AZ_Warning("UI", false, "Failed to create render target for UiFaderComponent"); - } - } - - // if depth surface already exists then destroy it - if (m_renderTargetDepthSurface) + // Create a render target that this element and its children will be rendered to + AZ::EntityId canvasEntityId; + EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId); + AZ::RHI::Size imageSize(renderTargetSize.GetX(), renderTargetSize.GetY(), 1); + EBUS_EVENT_ID_RESULT(m_attachmentImageId, canvasEntityId, LyShine::RenderToTextureRequestBus, UseRenderTarget, AZ::Name(m_renderTargetName.c_str()), imageSize); + if (m_attachmentImageId.IsEmpty()) { - gEnv->pRenderer->DestroyDepthSurface(m_renderTargetDepthSurface); - m_renderTargetDepthSurface = nullptr; + AZ_Warning("UI", false, "Failed to create render target for UiFaderComponent"); } - if (m_renderTargetHandle != -1) - { - // Also create a depth surface to render the canvas to, we need depth for masking - // since that uses the stencil buffer. We support any combination of nesting faders and masks - m_renderTargetDepthSurface = gEnv->pRenderer->CreateDepthSurface( - static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY())); - - if (!m_renderTargetDepthSurface) - { - AZ_Warning("UI", false, "Failed to create depth surface for UiFaderComponent"); - DestroyRenderTarget(); - } - } -#endif - // at this point either all render targets and depth surfaces are created or none are. // If all succeeded then update the render target size - if (m_renderTargetHandle != -1) + if (!m_attachmentImageId.IsEmpty()) { m_renderTargetWidth = static_cast(renderTargetSize.GetX()); m_renderTargetHeight = static_cast(renderTargetSize.GetY()); @@ -511,16 +484,12 @@ void UiFaderComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligne //////////////////////////////////////////////////////////////////////////////////////////////////// void UiFaderComponent::DestroyRenderTarget() { - if (m_renderTargetHandle != -1) + if (!m_attachmentImageId.IsEmpty()) { - gEnv->pRenderer->DestroyRenderTarget(m_renderTargetHandle); - m_renderTargetHandle = -1; - } - - if (m_renderTargetDepthSurface) - { - gEnv->pRenderer->DestroyDepthSurface(m_renderTargetDepthSurface); - m_renderTargetDepthSurface = nullptr; + AZ::EntityId canvasEntityId; + EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId); + EBUS_EVENT_ID(canvasEntityId, LyShine::RenderToTextureRequestBus, ReleaseRenderTarget, m_attachmentImageId); + m_attachmentImageId = AZ::RHI::AttachmentId{}; } } @@ -594,14 +563,20 @@ void UiFaderComponent::RenderStandardFader(LyShine::IRenderGraph* renderGraph, U void UiFaderComponent::RenderRttFader(LyShine::IRenderGraph* renderGraph, UiElementInterface* elementInterface, UiRenderInterface* renderInterface, int numChildren, bool isInGame) { + // Get the render target + AZ::Data::Instance attachmentImage; + AZ::EntityId canvasEntityId; + EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId); + EBUS_EVENT_ID_RESULT(attachmentImage, canvasEntityId, LyShine::RenderToTextureRequestBus, GetRenderTarget, m_attachmentImageId); + // Render the element and its children to a render target { // we always clear to transparent black - the accumulation of alpha in the render target requires it AZ::Color clearColor(0.0f, 0.0f, 0.0f, 0.0f); // Start building the render to texture node in the render graph - renderGraph->BeginRenderToTexture(m_renderTargetHandle, m_renderTargetDepthSurface, - m_viewportTopLeft, m_viewportSize, clearColor); + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); + lyRenderGraph->BeginRenderToTexture(attachmentImage, m_viewportTopLeft, m_viewportSize, clearColor); // We don't want this fader or parent faders to affect what is rendered to the render target since we will // apply those fades when we render from the render target. @@ -624,14 +599,13 @@ void UiFaderComponent::RenderRttFader(LyShine::IRenderGraph* renderGraph, UiElem float desiredAlpha = renderGraph->GetAlphaFade() * m_fade; uint8 desiredPackedAlpha = static_cast(desiredAlpha * 255.0f); - UCol desiredPackedColor; - // This is a special case. We have an input texture that already has premultiplied alpha. - // So we tell the shader not to premultiply the output colors and we premultiply the alpha - // into the vertex colors so that they are premultiplied too. - desiredPackedColor.r = desiredPackedColor.g = desiredPackedColor.b = desiredPackedColor.a = desiredPackedAlpha; - if (m_cachedPrimitive.m_vertices[0].color.dcolor != desiredPackedColor.dcolor) + // If the fade value has changed we need to update the alpha values in the vertex colors but we do + // not want to touch or recompute the RGB values + if (m_cachedPrimitive.m_vertices[0].color.a != desiredPackedAlpha) { - // go through the cached vertices and update the color values + // go through all the cached vertices and update the alpha values + UCol desiredPackedColor = m_cachedPrimitive.m_vertices[0].color; + desiredPackedColor.a = desiredPackedAlpha; for (int i = 0; i < m_cachedPrimitive.m_numVertices; ++i) { m_cachedPrimitive.m_vertices[i].color = desiredPackedColor; @@ -639,21 +613,20 @@ void UiFaderComponent::RenderRttFader(LyShine::IRenderGraph* renderGraph, UiElem } } -#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom // Add a primitive to render a quad using the render target we have created { - // Set the texture and other render state required - ITexture* texture = gEnv->pRenderer->EF_GetTextureByID(m_renderTargetHandle); - bool isClampTextureMode = true; - bool isTextureSRGB = true; - bool isTexturePremultipliedAlpha = true; - LyShine::BlendMode blendMode = LyShine::BlendMode::Normal; - - // add a render node to render from the render target texture to the current target - renderGraph->AddPrimitive(&m_cachedPrimitive, texture, - isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode); + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); + if (lyRenderGraph) + { + // Set the texture and other render state required + AZ::Data::Instance image = attachmentImage; + bool isClampTextureMode = true; + bool isTextureSRGB = true; + bool isTexturePremultipliedAlpha = true; + LyShine::BlendMode blendMode = LyShine::BlendMode::Normal; + lyRenderGraph->AddPrimitiveAtom(&m_cachedPrimitive, image, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode); + } } -#endif } } diff --git a/Gems/LyShine/Code/Source/UiFaderComponent.h b/Gems/LyShine/Code/Source/UiFaderComponent.h index a6960a5e36..560c1beaaa 100644 --- a/Gems/LyShine/Code/Source/UiFaderComponent.h +++ b/Gems/LyShine/Code/Source/UiFaderComponent.h @@ -18,6 +18,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// class UiFaderComponent @@ -156,11 +157,8 @@ private: // data //! This is generated from the entity ID and cached AZStd::string m_renderTargetName; - //! When rendering to a texture this is the texture ID of the render target - int m_renderTargetHandle = -1; - - //! When rendering to a texture this is our depth surface - SDepthTexture* m_renderTargetDepthSurface = nullptr; + //! When rendering to a texture this is the attachment image for the render target + AZ::RHI::AttachmentId m_attachmentImageId; //! The positions used for the render to texture viewport and to render the render target to the screen AZ::Vector2 m_viewportTopLeft; diff --git a/Gems/LyShine/Code/Source/UiImageComponent.cpp b/Gems/LyShine/Code/Source/UiImageComponent.cpp index 06996fbb48..1ca5e93b0d 100644 --- a/Gems/LyShine/Code/Source/UiImageComponent.cpp +++ b/Gems/LyShine/Code/Source/UiImageComponent.cpp @@ -699,7 +699,7 @@ const AZ::u32 UiImageComponent::GetImageIndexCount() { if (m_sprite) { - return m_sprite->GetSpriteSheetCells().size(); + return static_cast(m_sprite->GetSpriteSheetCells().size()); } return 0; @@ -2635,7 +2635,7 @@ LyShine::AZu32ComboBoxVec UiImageComponent::PopulateIndexStringList() const // There may not be a sprite loaded for this component if (m_sprite) { - const AZ::u32 numCells = m_sprite->GetSpriteSheetCells().size(); + const AZ::u32 numCells = static_cast(m_sprite->GetSpriteSheetCells().size()); if (numCells != 0) { diff --git a/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp b/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp index 33b73dfa63..086aed9f58 100644 --- a/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp +++ b/Gems/LyShine/Code/Source/UiImageSequenceComponent.cpp @@ -268,7 +268,7 @@ const AZ::u32 UiImageSequenceComponent::GetImageIndex() //////////////////////////////////////////////////////////////////////////////////////////////////// const AZ::u32 UiImageSequenceComponent::GetImageIndexCount() { - return m_spriteList.size(); + return static_cast(m_spriteList.size()); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/LyShine/Code/Source/UiLayoutColumnComponent.cpp b/Gems/LyShine/Code/Source/UiLayoutColumnComponent.cpp index f385a2eead..bd557ad64e 100644 --- a/Gems/LyShine/Code/Source/UiLayoutColumnComponent.cpp +++ b/Gems/LyShine/Code/Source/UiLayoutColumnComponent.cpp @@ -452,7 +452,7 @@ void UiLayoutColumnComponent::ApplyLayoutWidth(float availableWidth) // Get the child element cell widths UiLayoutHelpers::LayoutCellSizes layoutCells; UiLayoutHelpers::GetLayoutCellWidths(GetEntityId(), m_ignoreDefaultLayoutCells, layoutCells); - int numChildren = layoutCells.size(); + int numChildren = static_cast(layoutCells.size()); if (numChildren > 0) { // Set the child elements' transform properties based on the calculated child widths @@ -492,7 +492,7 @@ void UiLayoutColumnComponent::ApplyLayoutHeight(float availableHeight) // Get the child element cell heights UiLayoutHelpers::LayoutCellSizes layoutCells; UiLayoutHelpers::GetLayoutCellHeights(GetEntityId(), m_ignoreDefaultLayoutCells, layoutCells); - int numChildren = layoutCells.size(); + int numChildren = static_cast(layoutCells.size()); if (numChildren > 0) { // Calculate child heights diff --git a/Gems/LyShine/Code/Source/UiLayoutHelpers.cpp b/Gems/LyShine/Code/Source/UiLayoutHelpers.cpp index 5f53635ae8..49b1f59f97 100644 --- a/Gems/LyShine/Code/Source/UiLayoutHelpers.cpp +++ b/Gems/LyShine/Code/Source/UiLayoutHelpers.cpp @@ -434,7 +434,7 @@ namespace UiLayoutHelpers //////////////////////////////////////////////////////////////////////////////////////////////////// void CalculateElementSizes(const LayoutCellSizes& layoutCells, float availableSize, float spacing, AZStd::vector& sizesOut) { - int numElements = layoutCells.size(); + int numElements = static_cast(layoutCells.size()); availableSize -= (numElements - 1) * spacing; diff --git a/Gems/LyShine/Code/Source/UiLayoutRowComponent.cpp b/Gems/LyShine/Code/Source/UiLayoutRowComponent.cpp index 08770ebe83..3dcc8afdef 100644 --- a/Gems/LyShine/Code/Source/UiLayoutRowComponent.cpp +++ b/Gems/LyShine/Code/Source/UiLayoutRowComponent.cpp @@ -452,7 +452,7 @@ void UiLayoutRowComponent::ApplyLayoutWidth(float availableWidth) // Get the child element cell widths UiLayoutHelpers::LayoutCellSizes layoutCells; UiLayoutHelpers::GetLayoutCellWidths(GetEntityId(), m_ignoreDefaultLayoutCells, layoutCells); - int numChildren = layoutCells.size(); + int numChildren = static_cast(layoutCells.size()); if (numChildren > 0) { // Calculate child widths @@ -529,7 +529,7 @@ void UiLayoutRowComponent::ApplyLayoutHeight(float availableHeight) // Get the child element cell heights UiLayoutHelpers::LayoutCellSizes layoutCells; UiLayoutHelpers::GetLayoutCellHeights(GetEntityId(), m_ignoreDefaultLayoutCells, layoutCells); - int numChildren = layoutCells.size(); + int numChildren = static_cast(layoutCells.size()); if (numChildren > 0) { // Set the child elements' transform properties based on the calculated child heights diff --git a/Gems/LyShine/Code/Source/UiMarkupButtonComponent.cpp b/Gems/LyShine/Code/Source/UiMarkupButtonComponent.cpp index 8373ebf0d3..5df648cf5e 100644 --- a/Gems/LyShine/Code/Source/UiMarkupButtonComponent.cpp +++ b/Gems/LyShine/Code/Source/UiMarkupButtonComponent.cpp @@ -32,7 +32,7 @@ namespace { // Iterate through the clickable rects to find one that contains the point int clickableRectIndex = -1; - const int numClickableRects = clickableTextRects.size(); + const int numClickableRects = static_cast(clickableTextRects.size()); for (int i = 0; i < numClickableRects; ++i) { const auto& clickableRect = clickableTextRects[i]; diff --git a/Gems/LyShine/Code/Source/UiMaskComponent.cpp b/Gems/LyShine/Code/Source/UiMaskComponent.cpp index 4ecb558b2b..2c1763e4ec 100644 --- a/Gems/LyShine/Code/Source/UiMaskComponent.cpp +++ b/Gems/LyShine/Code/Source/UiMaskComponent.cpp @@ -14,12 +14,17 @@ #include #include "IRenderer.h" +#include "RenderToTextureBus.h" +#include "RenderGraph.h" #include #include #include #include #include +#include +#include + //////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC MEMBER FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -79,7 +84,7 @@ void UiMaskComponent::Render(LyShine::IRenderGraph* renderGraph, UiElementInterf AZ::Vector2 renderTargetSize = pixelAlignedBottomRight - pixelAlignedTopLeft; bool needsResize = static_cast(renderTargetSize.GetX()) != m_renderTargetWidth || static_cast(renderTargetSize.GetY()) != m_renderTargetHeight; - if (m_contentRenderTargetHandle == -1 || needsResize) + if (m_contentAttachmentImageId.IsEmpty() || needsResize) { // Need to create or resize the render target CreateOrResizeRenderTarget(pixelAlignedTopLeft, pixelAlignedBottomRight); @@ -89,7 +94,7 @@ void UiMaskComponent::Render(LyShine::IRenderGraph* renderGraph, UiElementInterf // in theory the child mask element could still be non-zero size and could reveal things. But the way gradient masks // currently work is that the size of the render target is defined by the size of this element, therefore nothing would // be revealed by the mask if it is zero sized. - if (m_contentRenderTargetHandle == -1) + if (m_contentAttachmentImageId.IsEmpty()) { return; } @@ -101,7 +106,7 @@ void UiMaskComponent::Render(LyShine::IRenderGraph* renderGraph, UiElementInterf else { // using stencil mask, not going to use render targets, destroy previous render target, if exists - if (m_contentRenderTargetHandle != -1) + if (!m_contentAttachmentImageId.IsEmpty()) { DestroyRenderTarget(); } @@ -113,7 +118,7 @@ void UiMaskComponent::Render(LyShine::IRenderGraph* renderGraph, UiElementInterf else { // masking disabled, not going to use render targets, destroy previous render target, if exists - if (m_contentRenderTargetHandle != -1) + if (!m_contentAttachmentImageId.IsEmpty()) { DestroyRenderTarget(); } @@ -553,77 +558,30 @@ void UiMaskComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligned m_viewportTopLeft = pixelAlignedTopLeft; m_viewportSize = renderTargetSize; -#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom - // Check if the render target already exists - if (m_contentRenderTargetHandle != -1) - { - // Render target exists, resize it to the given size - if (!gEnv->pRenderer->ResizeRenderTarget(m_contentRenderTargetHandle, static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY()))) - { - AZ_Warning("UI", false, "Failed to resize content render target for UiMaskComponent"); - DestroyRenderTarget(); - } - } - else - { - // Create a render target that this element and its children will be rendered to. - m_contentRenderTargetHandle = gEnv->pRenderer->CreateRenderTarget(m_renderTargetName.c_str(), - static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY()), Clr_Transparent, eTF_R8G8B8A8); + // LYSHINE_ATOM_TODO: optimize by reusing/resizing targets + DestroyRenderTarget(); - if (m_contentRenderTargetHandle == -1) - { - AZ_Warning("UI", false, "Failed to create content render target for UiMaskComponent"); - } + // Create a render target that this element and its children will be rendered to + AZ::EntityId canvasEntityId; + EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId); + AZ::RHI::Size imageSize(renderTargetSize.GetX(), renderTargetSize.GetY(), 1); + EBUS_EVENT_ID_RESULT(m_contentAttachmentImageId, canvasEntityId, LyShine::RenderToTextureRequestBus, UseRenderTarget, AZ::Name(m_renderTargetName.c_str()), imageSize); + if (m_contentAttachmentImageId.IsEmpty()) + { + AZ_Warning("UI", false, "Failed to create content render target for UiMaskComponent"); } - // if depth surface already exists then destroy it - if (m_renderTargetDepthSurface) + // Create separate render target for the mask texture + EBUS_EVENT_ID_RESULT(m_maskAttachmentImageId, canvasEntityId, LyShine::RenderToTextureRequestBus, UseRenderTarget, AZ::Name(m_maskRenderTargetName.c_str()), imageSize); + if (m_maskAttachmentImageId.IsEmpty()) { - gEnv->pRenderer->DestroyDepthSurface(m_renderTargetDepthSurface); - m_renderTargetDepthSurface = nullptr; + AZ_Warning("UI", false, "Failed to create mask render target for UiMaskComponent"); + DestroyRenderTarget(); } - if (m_contentRenderTargetHandle != -1) - { - // Also create a depth surface to render the canvas to, we need depth for masking - // since that uses the stencil buffer. We support any combination of nesting faders and masks - m_renderTargetDepthSurface = gEnv->pRenderer->CreateDepthSurface( - static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY())); - - if (!m_renderTargetDepthSurface) - { - AZ_Warning("UI", false, "Failed to create depth surface for UiMaskComponent"); - DestroyRenderTarget(); - } - } - - // Check if the mask render target already exists - if (m_maskRenderTargetHandle != -1) - { - // Render target exists, resize it to the given size - if (!gEnv->pRenderer->ResizeRenderTarget(m_maskRenderTargetHandle, static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY()))) - { - AZ_Warning("UI", false, "Failed to resize mask render target for UiMaskComponent"); - DestroyRenderTarget(); - } - } - else - { - // create separate render target for the mask texture - m_maskRenderTargetHandle = gEnv->pRenderer->CreateRenderTarget(m_maskRenderTargetName.c_str(), - static_cast(renderTargetSize.GetX()), static_cast(renderTargetSize.GetY()), Clr_Transparent, eTF_R8G8B8A8); - - if (m_maskRenderTargetHandle == -1) - { - AZ_Warning("UI", false, "Failed to create mask render target for UiMaskComponent"); - DestroyRenderTarget(); - } - } -#endif - // at this point either all render targets and depth surfaces are created or none are. // If all succeeded then update the render target size - if (m_contentRenderTargetHandle != -1) + if (!m_contentAttachmentImageId.IsEmpty()) { m_renderTargetWidth = static_cast(renderTargetSize.GetX()); m_renderTargetHeight = static_cast(renderTargetSize.GetY()); @@ -635,22 +593,22 @@ void UiMaskComponent::CreateOrResizeRenderTarget(const AZ::Vector2& pixelAligned //////////////////////////////////////////////////////////////////////////////////////////////////// void UiMaskComponent::DestroyRenderTarget() { - if (m_contentRenderTargetHandle != -1) + if (!m_contentAttachmentImageId.IsEmpty()) { - gEnv->pRenderer->DestroyRenderTarget(m_contentRenderTargetHandle); - m_contentRenderTargetHandle = -1; + AZ::EntityId canvasEntityId; + EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId); + EBUS_EVENT_ID(canvasEntityId, LyShine::RenderToTextureRequestBus, ReleaseRenderTarget, m_contentAttachmentImageId); + + m_contentAttachmentImageId = AZ::RHI::AttachmentId{}; } - if (m_renderTargetDepthSurface) + if (!m_maskAttachmentImageId.IsEmpty()) { - gEnv->pRenderer->DestroyDepthSurface(m_renderTargetDepthSurface); - m_renderTargetDepthSurface = nullptr; - } + AZ::EntityId canvasEntityId; + EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId); + EBUS_EVENT_ID(canvasEntityId, LyShine::RenderToTextureRequestBus, ReleaseRenderTarget, m_maskAttachmentImageId); - if (m_maskRenderTargetHandle != -1) - { - gEnv->pRenderer->DestroyRenderTarget(m_maskRenderTargetHandle); - m_maskRenderTargetHandle = -1; + m_maskAttachmentImageId = AZ::RHI::AttachmentId{}; } } @@ -747,6 +705,14 @@ void UiMaskComponent::RenderUsingGradientMask(LyShine::IRenderGraph* renderGraph // we always clear to transparent black - the accumulation of alpha in the render target requires it AZ::Color clearColor(0.0f, 0.0f, 0.0f, 0.0f); + // Get the render targets + AZ::Data::Instance contentAttachmentImage; + AZ::Data::Instance maskAttachmentImage; + AZ::EntityId canvasEntityId; + EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId); + EBUS_EVENT_ID_RESULT(contentAttachmentImage, canvasEntityId, LyShine::RenderToTextureRequestBus, GetRenderTarget, m_contentAttachmentImageId); + EBUS_EVENT_ID_RESULT(maskAttachmentImage, canvasEntityId, LyShine::RenderToTextureRequestBus, GetRenderTarget, m_maskAttachmentImageId); + // We don't want parent faders to affect what is rendered to the render target since we will // apply those fades when we render from the render target. // Note that this means that, if there are parent (no render to texture) faders, we get a "free" @@ -756,8 +722,8 @@ void UiMaskComponent::RenderUsingGradientMask(LyShine::IRenderGraph* renderGraph // mask render target { // Start building the render to texture node in the render graph - renderGraph->BeginRenderToTexture(m_maskRenderTargetHandle, m_renderTargetDepthSurface, - m_viewportTopLeft, m_viewportSize, clearColor); + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); + lyRenderGraph->BeginRenderToTexture(maskAttachmentImage, m_viewportTopLeft, m_viewportSize, clearColor); // Render the visual component for this element (if there is one) plus the child mask element (if there is one) RenderMaskPrimitives(renderGraph, renderInterface, childMaskElementInterface, isInGame); @@ -769,8 +735,8 @@ void UiMaskComponent::RenderUsingGradientMask(LyShine::IRenderGraph* renderGraph // content render target { // Start building the render to texture node for the content render target in the render graph - renderGraph->BeginRenderToTexture(m_contentRenderTargetHandle, m_renderTargetDepthSurface, - m_viewportTopLeft, m_viewportSize, clearColor); + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); + lyRenderGraph->BeginRenderToTexture(contentAttachmentImage, m_viewportTopLeft, m_viewportSize, clearColor); // Render the "content" - the child elements excluding the child mask element (if any) RenderContentPrimitives(renderGraph, elementInterface, childMaskElementInterface, numChildren, isInGame); @@ -790,14 +756,13 @@ void UiMaskComponent::RenderUsingGradientMask(LyShine::IRenderGraph* renderGraph float desiredAlpha = renderGraph->GetAlphaFade(); uint32 desiredPackedAlpha = static_cast(desiredAlpha * 255.0f); - UCol desiredPackedColor; - // This is a special case. We have an input texture that already has premultiplied alpha. - // So we tell the shader not to premultiply the output colors and we premultiply the alpha - // into the vertex colors so that they are premultiplied too. - desiredPackedColor.r = desiredPackedColor.g = desiredPackedColor.b = desiredPackedColor.a = desiredPackedAlpha; - if (m_cachedPrimitive.m_vertices[0].color.dcolor != desiredPackedColor.dcolor) + // If the fade value has changed we need to update the alpha values in the vertex colors but we do + // not want to touch or recompute the RGB values + if (m_cachedPrimitive.m_vertices[0].color.a != desiredPackedAlpha) { - // go through the cached vertices and update the color values + // go through all the cached vertices and update the alpha values + UCol desiredPackedColor = m_cachedPrimitive.m_vertices[0].color; + desiredPackedColor.a = desiredPackedAlpha; for (int i = 0; i < m_cachedPrimitive.m_numVertices; ++i) { m_cachedPrimitive.m_vertices[i].color = desiredPackedColor; @@ -805,22 +770,29 @@ void UiMaskComponent::RenderUsingGradientMask(LyShine::IRenderGraph* renderGraph } } -#ifdef LYSHINE_ATOM_TODO // [LYN-3359] Support RTT using Atom // Add a primitive to do the alpha mask { - // Set the texture and other render state required - ITexture* texture = gEnv->pRenderer->EF_GetTextureByID(m_contentRenderTargetHandle); - ITexture* maskTexture = gEnv->pRenderer->EF_GetTextureByID(m_maskRenderTargetHandle); - bool isClampTextureMode = true; - bool isTextureSRGB = true; - bool isTexturePremultipliedAlpha = true; - LyShine::BlendMode blendMode = LyShine::BlendMode::Normal; + LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph); + if (lyRenderGraph) + { + // Set the texture and other render state required + AZ::Data::Instance contentImage = contentAttachmentImage; + AZ::Data::Instance maskImage = maskAttachmentImage; + bool isClampTextureMode = true; + bool isTextureSRGB = true; + bool isTexturePremultipliedAlpha = false; + LyShine::BlendMode blendMode = LyShine::BlendMode::Normal; - // add a render node to render using the two render targets, one as an alpha mask of the other - renderGraph->AddAlphaMaskPrimitive(&m_cachedPrimitive, texture, maskTexture, - isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode); + // add a render node to render using the two render targets, one as an alpha mask of the other + lyRenderGraph->AddAlphaMaskPrimitiveAtom(&m_cachedPrimitive, + contentAttachmentImage, + maskAttachmentImage, + isClampTextureMode, + isTextureSRGB, + isTexturePremultipliedAlpha, + blendMode); + } } -#endif } } diff --git a/Gems/LyShine/Code/Source/UiMaskComponent.h b/Gems/LyShine/Code/Source/UiMaskComponent.h index ce0068ca97..8635f048f5 100644 --- a/Gems/LyShine/Code/Source/UiMaskComponent.h +++ b/Gems/LyShine/Code/Source/UiMaskComponent.h @@ -15,6 +15,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// class UiMaskComponent @@ -184,15 +185,16 @@ private: // data //! This is generated from the entity ID and cached AZStd::string m_maskRenderTargetName; - //! When rendering to a texture this is the texture ID of the render target - int m_contentRenderTargetHandle = -1; + //! When rendering to a texture this is the attachment image for the render target + AZ::RHI::AttachmentId m_contentAttachmentImageId; //! When rendering to a texture this is our depth surface, we use the same one for rendering the mask elements //! and the content elements - it is cleared in between. SDepthTexture* m_renderTargetDepthSurface = nullptr; //! When rendering to a texture this is the texture ID of the render target - int m_maskRenderTargetHandle = -1; + //! When rendering to a texture this is the attachment image for the render target + AZ::RHI::AttachmentId m_maskAttachmentImageId; //! The positions used for the render to texture viewport and to render the render target to the screen AZ::Vector2 m_viewportTopLeft = AZ::Vector2::CreateZero(); diff --git a/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp b/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp index 860eaf0d78..9668ebf463 100644 --- a/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp +++ b/Gems/LyShine/Code/Source/UiParticleEmitterComponent.cpp @@ -409,7 +409,7 @@ void UiParticleEmitterComponent::SetSpriteSheetCellIndex(int spriteSheetIndex) if (m_sprite) { - const AZ::u32 numCells = m_sprite->GetSpriteSheetCells().size(); + const AZ::u32 numCells = static_cast(m_sprite->GetSpriteSheetCells().size()); m_spriteSheetCellIndex = AZ::GetMin(numCells, m_spriteSheetCellIndex); m_spriteSheetCellEndIndex = AZ::GetMax(m_spriteSheetCellIndex, m_spriteSheetCellEndIndex); } @@ -428,7 +428,7 @@ void UiParticleEmitterComponent::SetSpriteSheetCellEndIndex(int spriteSheetEndIn if (m_sprite) { - const AZ::u32 numCells = m_sprite->GetSpriteSheetCells().size(); + const AZ::u32 numCells = static_cast(m_sprite->GetSpriteSheetCells().size()); m_spriteSheetCellEndIndex = AZ::GetMin(numCells, m_spriteSheetCellEndIndex); m_spriteSheetCellIndex = AZ::GetMin(m_spriteSheetCellIndex, m_spriteSheetCellEndIndex); } @@ -759,7 +759,7 @@ void UiParticleEmitterComponent::InGamePostActivate() //////////////////////////////////////////////////////////////////////////////////////////////////// void UiParticleEmitterComponent::Render(LyShine::IRenderGraph* renderGraph) { - AZ::u32 particlesToRender = AZ::GetMin(m_particleContainer.size(), m_particleBufferSize); + AZ::u32 particlesToRender = AZ::GetMin(static_cast(m_particleContainer.size()), m_particleBufferSize); if (particlesToRender == 0) { return; @@ -1943,7 +1943,7 @@ void UiParticleEmitterComponent::OnSpritePathnameChange() m_spriteSheetCellIndex = 0; if (IsSpriteTypeSpriteSheet()) { - m_spriteSheetCellEndIndex = m_sprite->GetSpriteSheetCells().size() - 1; + m_spriteSheetCellEndIndex = static_cast(m_sprite->GetSpriteSheetCells().size() - 1); } } @@ -2086,7 +2086,7 @@ UiParticleEmitterComponent::AZu32ComboBoxVec UiParticleEmitterComponent::Populat // There may not be a sprite loaded for this component if (m_sprite) { - const AZ::u32 numCells = m_sprite->GetSpriteSheetCells().size(); + const AZ::u32 numCells = static_cast(m_sprite->GetSpriteSheetCells().size()); if (numCells != 0) { diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp index 56374d1152..357431c80a 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.cpp +++ b/Gems/LyShine/Code/Source/UiRenderer.cpp @@ -6,6 +6,7 @@ * */ #include "UiRenderer.h" +#include "LyShinePassDataBus.h" #include #include @@ -60,25 +61,32 @@ void UiRenderer::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstra AZ::Data::Instance uiShader = AZ::RPI::LoadShader(uiShaderFilepath); // Create scene to be used by the dynamic draw context - AZ::RPI::ScenePtr scene; if (m_viewportContext) { // Create a new scene based on the user specified viewport context - scene = CreateScene(m_viewportContext); + m_scene = CreateScene(m_viewportContext); } else { // No viewport context specified, use default scene - scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene(); + m_scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene(); } // Create a dynamic draw context for UI Canvas drawing for the scene - CreateDynamicDrawContext(scene, uiShader); + m_dynamicDraw = CreateDynamicDrawContext(m_scene, uiShader); - // Cache shader data such as input indices for later use - CacheShaderData(m_dynamicDraw); + if (m_dynamicDraw) + { + // Cache shader data such as input indices for later use + CacheShaderData(m_dynamicDraw); - m_isRPIReady = true; + m_isRPIReady = true; + } + else + { + AZ_Error(LogName, false, "Failed to create a dynamic draw context for LyShine. \ + This can happen if the LyShine pass hasn't been added to the main render pipeline."); + } } AZ::RPI::ScenePtr UiRenderer::CreateScene(AZStd::shared_ptr viewportContext) @@ -107,22 +115,40 @@ AZ::RPI::ScenePtr UiRenderer::CreateScene(AZStd::shared_ptr uiShader) +AZ::RHI::Ptr UiRenderer::CreateDynamicDrawContext( + AZ::RPI::ScenePtr scene, + AZ::Data::Instance uiShader) { - m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(); + // Find the pass that renders the UI canvases after the rtt passes + AZ::RPI::RasterPass* uiCanvasPass = nullptr; + AZ::RPI::SceneId sceneId = m_scene->GetId(); + LyShinePassRequestBus::EventResult(uiCanvasPass, sceneId, &LyShinePassRequestBus::Events::GetUiCanvasPass); + + AZ::RHI::Ptr dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(); // Initialize the dynamic draw context - m_dynamicDraw->InitShader(uiShader); - m_dynamicDraw->InitVertexFormat( + dynamicDraw->InitShader(uiShader); + dynamicDraw->InitVertexFormat( { { "POSITION", AZ::RHI::Format::R32G32_FLOAT }, { "COLOR", AZ::RHI::Format::B8G8R8A8_UNORM }, { "TEXCOORD", AZ::RHI::Format::R32G32_FLOAT }, { "BLENDINDICES", AZ::RHI::Format::R16G16_UINT } } ); - m_dynamicDraw->AddDrawStateOptions(AZ::RPI::DynamicDrawContext::DrawStateOptions::StencilState + dynamicDraw->AddDrawStateOptions(AZ::RPI::DynamicDrawContext::DrawStateOptions::StencilState | AZ::RPI::DynamicDrawContext::DrawStateOptions::BlendMode); - m_dynamicDraw->SetOutputScope(scene.get()); - m_dynamicDraw->EndInit(); + + if (uiCanvasPass) + { + dynamicDraw->SetOutputScope(uiCanvasPass); + } + else + { + // Render target support is disabled + dynamicDraw->SetOutputScope(m_scene.get()); + } + dynamicDraw->EndInit(); + + return dynamicDraw; } AZStd::shared_ptr UiRenderer::GetViewportContext() @@ -158,19 +184,26 @@ void UiRenderer::CacheShaderData(const AZ::RHI::Ptr isClampIndexName); // Cache shader variants that will be used - // LYSHINE_ATOM_TODO - more variants will be used in future phase (masks/render target support) - AZ::RPI::ShaderOptionList shaderOptionsDefault; - shaderOptionsDefault.push_back(AZ::RPI::ShaderOption(AZ::Name("o_preMultiplyAlpha"), AZ::Name("false"))); - shaderOptionsDefault.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("false"))); - shaderOptionsDefault.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("true"))); - shaderOptionsDefault.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::None"))); - m_uiShaderData.m_shaderVariantDefault = dynamicDraw->UseShaderVariant(shaderOptionsDefault); - AZ::RPI::ShaderOptionList shaderOptionsAlphaTest; - shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_preMultiplyAlpha"), AZ::Name("false"))); - shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("true"))); - shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("true"))); - shaderOptionsAlphaTest.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::None"))); - m_uiShaderData.m_shaderVariantAlphaTest = dynamicDraw->UseShaderVariant(shaderOptionsAlphaTest); + AZ::RPI::ShaderOptionList shaderOptionsTextureLinear; + shaderOptionsTextureLinear.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("false"))); + shaderOptionsTextureLinear.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("true"))); + shaderOptionsTextureLinear.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::None"))); + m_uiShaderData.m_shaderVariantTextureLinear = dynamicDraw->UseShaderVariant(shaderOptionsTextureLinear); + AZ::RPI::ShaderOptionList shaderOptionsTextureSrgb; + shaderOptionsTextureSrgb.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("false"))); + shaderOptionsTextureSrgb.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("false"))); + shaderOptionsTextureSrgb.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::None"))); + m_uiShaderData.m_shaderVariantTextureSrgb = dynamicDraw->UseShaderVariant(shaderOptionsTextureSrgb); + AZ::RPI::ShaderOptionList shaderVariantAlphaTestMask; + shaderVariantAlphaTestMask.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("true"))); + shaderVariantAlphaTestMask.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("false"))); + shaderVariantAlphaTestMask.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::None"))); + m_uiShaderData.m_shaderVariantAlphaTestMask = dynamicDraw->UseShaderVariant(shaderVariantAlphaTestMask); + AZ::RPI::ShaderOptionList shaderVariantGradientMask; + shaderVariantGradientMask.push_back(AZ::RPI::ShaderOption(AZ::Name("o_alphaTest"), AZ::Name("false"))); + shaderVariantGradientMask.push_back(AZ::RPI::ShaderOption(AZ::Name("o_srgbWrite"), AZ::Name("false"))); + shaderVariantGradientMask.push_back(AZ::RPI::ShaderOption(AZ::Name("o_modulate"), AZ::Name("Modulate::Alpha"))); + m_uiShaderData.m_shaderVariantGradientMask = dynamicDraw->UseShaderVariant(shaderVariantGradientMask); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -215,6 +248,38 @@ AZ::RHI::Ptr UiRenderer::GetDynamicDrawContext() return m_dynamicDraw; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +AZ::RHI::Ptr UiRenderer::CreateDynamicDrawContextForRTT(const AZStd::string& rttName) +{ + // find the rtt pass with the specified name + AZ::RPI::RasterPass* rttPass = nullptr; + AZ::RPI::SceneId sceneId = m_scene->GetId(); + LyShinePassRequestBus::EventResult(rttPass, sceneId, &LyShinePassRequestBus::Events::GetRttPass, rttName); + if (!rttPass) + { + return nullptr; + } + + AZ::RHI::Ptr dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(); + + // Initialize the dynamic draw context + dynamicDraw->InitShader(m_dynamicDraw->GetShader()); + dynamicDraw->InitVertexFormat( + { { "POSITION", AZ::RHI::Format::R32G32_FLOAT }, + { "COLOR", AZ::RHI::Format::B8G8R8A8_UNORM }, + { "TEXCOORD", AZ::RHI::Format::R32G32_FLOAT }, + { "BLENDINDICES", AZ::RHI::Format::R16G16_UINT } } + ); + dynamicDraw->AddDrawStateOptions(AZ::RPI::DynamicDrawContext::DrawStateOptions::StencilState + | AZ::RPI::DynamicDrawContext::DrawStateOptions::BlendMode); + + dynamicDraw->SetOutputScope(rttPass); + + dynamicDraw->EndInit(); + + return dynamicDraw; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// const UiRenderer::UiShaderData& UiRenderer::GetUiShaderData() { @@ -270,11 +335,27 @@ void UiRenderer::SetBaseState(BaseState state) //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::RPI::ShaderVariantId UiRenderer::GetCurrentShaderVariant() { - AZ::RPI::ShaderVariantId variantId = m_uiShaderData.m_shaderVariantDefault; + AZ::RPI::ShaderVariantId variantId = m_uiShaderData.m_shaderVariantTextureLinear; if (m_baseState.m_useAlphaTest) { - variantId = m_uiShaderData.m_shaderVariantAlphaTest; + variantId = m_uiShaderData.m_shaderVariantAlphaTestMask; + } + else if (m_baseState.m_modulateAlpha) + { + variantId = m_uiShaderData.m_shaderVariantGradientMask; + } + else if (!m_baseState.m_useAlphaTest && m_baseState.m_srgbWrite) + { + variantId = m_uiShaderData.m_shaderVariantTextureLinear; + } + else if (!m_baseState.m_useAlphaTest && !m_baseState.m_srgbWrite) + { + variantId = m_uiShaderData.m_shaderVariantTextureSrgb; + } + else + { + AZ_Error(LogName, 0, "Unsupported shader variant."); } return variantId; diff --git a/Gems/LyShine/Code/Source/UiRenderer.h b/Gems/LyShine/Code/Source/UiRenderer.h index d05261c2d6..14fc67fc6b 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.h +++ b/Gems/LyShine/Code/Source/UiRenderer.h @@ -36,8 +36,10 @@ public: // types AZ::RHI::ShaderInputConstantIndex m_viewProjInputIndex; AZ::RHI::ShaderInputConstantIndex m_isClampInputIndex; - AZ::RPI::ShaderVariantId m_shaderVariantDefault; - AZ::RPI::ShaderVariantId m_shaderVariantAlphaTest; + AZ::RPI::ShaderVariantId m_shaderVariantTextureLinear; + AZ::RPI::ShaderVariantId m_shaderVariantTextureSrgb; + AZ::RPI::ShaderVariantId m_shaderVariantAlphaTestMask; + AZ::RPI::ShaderVariantId m_shaderVariantGradientMask; }; // Base state @@ -56,17 +58,23 @@ public: // types m_blendState.m_blendSource = AZ::RHI::BlendFactor::AlphaSource; m_blendState.m_blendDest = AZ::RHI::BlendFactor::AlphaSourceInverse; m_blendState.m_blendOp = AZ::RHI::BlendOp::Add; + m_blendState.m_blendAlphaSource = AZ::RHI::BlendFactor::One; + m_blendState.m_blendAlphaDest = AZ::RHI::BlendFactor::Zero; + m_blendState.m_blendAlphaOp = AZ::RHI::BlendOp::Add; // Disable stencil m_stencilState = AZ::RHI::StencilState(); m_stencilState.m_enable = 0; m_useAlphaTest = false; + m_modulateAlpha = false; } AZ::RHI::TargetBlendState m_blendState; AZ::RHI::StencilState m_stencilState; bool m_useAlphaTest = false; + bool m_modulateAlpha = false; + bool m_srgbWrite = true; }; public: // member functions @@ -93,6 +101,8 @@ public: // member functions //! Return the dynamic draw context associated with this UI renderer AZ::RHI::Ptr GetDynamicDrawContext(); + AZ::RHI::Ptr CreateDynamicDrawContextForRTT(const AZStd::string& rttName); + //! Return the shader data for the ui shader const UiShaderData& GetUiShaderData(); @@ -123,6 +133,9 @@ public: // member functions //! Decrement the current stencil reference value void DecrementStencilRef(); + //! Return the viewport context set by the user, or the default if not set + AZStd::shared_ptr GetViewportContext(); + #ifndef _RELEASE //! Setup to record debug texture data before rendering void DebugSetRecordingOptionForTextureData(int recordingOption); @@ -143,10 +156,9 @@ private: // member functions AZ::RPI::ScenePtr CreateScene(AZStd::shared_ptr viewportContext); //! Create a dynamic draw context for this renderer - void CreateDynamicDrawContext(AZ::RPI::ScenePtr scene, AZ::Data::Instance); - - //! Return the viewport context set by the user, or the default if not set - AZStd::shared_ptr GetViewportContext(); + AZ::RHI::Ptr CreateDynamicDrawContext( + AZ::RPI::ScenePtr scene, + AZ::Data::Instance uiShader); //! Bind the global white texture for all the texture units we use void BindNullTexture(); @@ -168,6 +180,8 @@ protected: // attributes // Set by user when viewport context is not the main/default viewport AZStd::shared_ptr m_viewportContext; + AZ::RPI::ScenePtr m_scene; + #ifndef _RELEASE int m_debugTextureDataRecordLevel = 0; AZStd::unordered_set m_texturesUsedInFrame; // LYSHINE_ATOM_TODO - convert to RPI::Image diff --git a/Gems/LyShine/Code/Source/UiTextComponent.cpp b/Gems/LyShine/Code/Source/UiTextComponent.cpp index be26a5a618..ea1be07074 100644 --- a/Gems/LyShine/Code/Source/UiTextComponent.cpp +++ b/Gems/LyShine/Code/Source/UiTextComponent.cpp @@ -4417,7 +4417,7 @@ void UiTextComponent::HandleWidthOnlyShrinkToFitWithWrapping( { // Consider the sizes of all overflowing lines when calculating the // scale to reduce the number of times we need to iterate. - int numOverflowingLines = drawBatchLinesOut.batchLines.size() - maxLinesElementCanHold; + int numOverflowingLines = static_cast(drawBatchLinesOut.batchLines.size() - maxLinesElementCanHold); DrawBatchLineContainer::reverse_iterator riter; int overflowLineCount = 0; float overflowingLineSize = 0.0f; diff --git a/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp b/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp index b472f79bd6..8803a1881c 100644 --- a/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp +++ b/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.cpp @@ -92,7 +92,7 @@ void UiTextComponentOffsetsSelector::ParseBatchLine(const UiTextComponent::DrawB // on the same line or not. else if (!lastIndexFound) { - int substrLength = drawBatch.text.length() - firstIndexLineIndex; + int substrLength = static_cast(drawBatch.text.length() - firstIndexLineIndex); AZStd::string curSubstring(drawBatch.text.substr(firstIndexLineIndex, substrLength)); curLineWidth += drawBatch.font->GetTextSize(curSubstring.c_str(), false, m_fontContext).x; lineOffsetsStack.top()->right.SetX(AZStd::GetMax(lineOffsetsStack.top()->right.GetX(), curLineWidth)); diff --git a/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.h b/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.h index 1c98e53970..896e93a3be 100644 --- a/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.h +++ b/Gems/LyShine/Code/Source/UiTextComponentOffsetsSelector.h @@ -29,7 +29,7 @@ struct UiTextComponentOffsetsSelector , m_firstIndex(firstIndex) , m_lastIndex(lastIndex) , m_lastIndexLineNumber(lastIndexLineNumber) - , m_numLines(m_drawBatchLines.batchLines.size()) + , m_numLines(static_cast(m_drawBatchLines.batchLines.size())) , m_indexIter(0) , m_numCharsSelected(0) , m_lineCounter(0) diff --git a/Gems/LyShine/Code/Source/UiTextInputComponent.cpp b/Gems/LyShine/Code/Source/UiTextInputComponent.cpp index 8cc0efcaaf..0c61116945 100644 --- a/Gems/LyShine/Code/Source/UiTextInputComponent.cpp +++ b/Gems/LyShine/Code/Source/UiTextInputComponent.cpp @@ -647,7 +647,7 @@ bool UiTextInputComponent::HandleKeyInputBegan(const AzFramework::InputChannel:: // Append text from clipboard textString.insert(m_textCursorPos, clipboardText); - m_textCursorPos += clipboardText.length(); + m_textCursorPos += static_cast(clipboardText.length()); m_textSelectionStartPos = m_textCursorPos; // If max length is set, remove extra characters diff --git a/Gems/LyShine/Code/Tests/UiTooltipComponentTest.cpp b/Gems/LyShine/Code/Tests/UiTooltipComponentTest.cpp index 17eb2c081f..65ca1ec280 100644 --- a/Gems/LyShine/Code/Tests/UiTooltipComponentTest.cpp +++ b/Gems/LyShine/Code/Tests/UiTooltipComponentTest.cpp @@ -163,11 +163,9 @@ namespace UnitTest SSystemGlobalEnvironment* prevEnv = gEnv; gEnv = &env; gEnv->pTimer = &m_timer; + gEnv->pLyShine = nullptr; - UiCanvasComponent* uiCanvasComponent; - UiTooltipDisplayComponent* uiTooltipDisplayComponent; - UiTooltipComponent* uiTooltipComponent; - std::tie(uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent) = CreateUiCanvasWithTooltip(); + auto [uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent] = CreateUiCanvasWithTooltip(); uiTooltipDisplayComponent->SetTriggerMode(UiTooltipDisplayInterface::TriggerMode::OnHover); AZ::Entity* uiTooltipEntity = uiTooltipComponent->GetEntity(); @@ -193,11 +191,9 @@ namespace UnitTest SSystemGlobalEnvironment* prevEnv = gEnv; gEnv = &env; gEnv->pTimer = &m_timer; + gEnv->pLyShine = nullptr; - UiCanvasComponent* uiCanvasComponent; - UiTooltipDisplayComponent* uiTooltipDisplayComponent; - UiTooltipComponent* uiTooltipComponent; - std::tie(uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent) = CreateUiCanvasWithTooltip(); + auto [uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent] = CreateUiCanvasWithTooltip(); uiTooltipDisplayComponent->SetTriggerMode(UiTooltipDisplayInterface::TriggerMode::OnHover); AZ::Entity* uiTooltipEntity = uiTooltipComponent->GetEntity(); @@ -221,11 +217,9 @@ namespace UnitTest SSystemGlobalEnvironment* prevEnv = gEnv; gEnv = &env; gEnv->pTimer = &m_timer; + gEnv->pLyShine = nullptr; - UiCanvasComponent* uiCanvasComponent; - UiTooltipDisplayComponent* uiTooltipDisplayComponent; - UiTooltipComponent* uiTooltipComponent; - std::tie(uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent) = CreateUiCanvasWithTooltip(); + auto [uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent] = CreateUiCanvasWithTooltip(); uiTooltipDisplayComponent->SetTriggerMode(UiTooltipDisplayInterface::TriggerMode::OnPress); AZ::Entity* uiTooltipEntity = uiTooltipComponent->GetEntity(); @@ -249,11 +243,9 @@ namespace UnitTest SSystemGlobalEnvironment* prevEnv = gEnv; gEnv = &env; gEnv->pTimer = &m_timer; + gEnv->pLyShine = nullptr; - UiCanvasComponent* uiCanvasComponent; - UiTooltipDisplayComponent* uiTooltipDisplayComponent; - UiTooltipComponent* uiTooltipComponent; - std::tie(uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent) = CreateUiCanvasWithTooltip(); + auto [uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent] = CreateUiCanvasWithTooltip(); uiTooltipDisplayComponent->SetTriggerMode(UiTooltipDisplayInterface::TriggerMode::OnPress); AZ::Entity* uiTooltipEntity = uiTooltipComponent->GetEntity(); @@ -277,11 +269,9 @@ namespace UnitTest SSystemGlobalEnvironment* prevEnv = gEnv; gEnv = &env; gEnv->pTimer = &m_timer; + gEnv->pLyShine = nullptr; - UiCanvasComponent* uiCanvasComponent; - UiTooltipDisplayComponent* uiTooltipDisplayComponent; - UiTooltipComponent* uiTooltipComponent; - std::tie(uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent) = CreateUiCanvasWithTooltip(); + auto [uiCanvasComponent, uiTooltipDisplayComponent, uiTooltipComponent] = CreateUiCanvasWithTooltip(); uiTooltipDisplayComponent->SetTriggerMode(UiTooltipDisplayInterface::TriggerMode::OnClick); AZ::Entity* uiTooltipEntity = uiTooltipComponent->GetEntity(); diff --git a/Gems/LyShine/Code/lyshine_static_files.cmake b/Gems/LyShine/Code/lyshine_static_files.cmake index 7fdac831b6..0c934eb057 100644 --- a/Gems/LyShine/Code/lyshine_static_files.cmake +++ b/Gems/LyShine/Code/lyshine_static_files.cmake @@ -11,8 +11,11 @@ set(FILES Include/LyShine/Draw2d.h Source/LyShine.cpp Source/LyShine.h + Source/LyShinePassDataBus.h Source/LyShineDebug.cpp Source/LyShineDebug.h + Source/LyShinePass.cpp + Source/LyShinePass.h Source/StringUtfUtils.h Source/UiImageComponent.cpp Source/UiImageComponent.h @@ -28,6 +31,7 @@ set(FILES Source/LyShineLoadScreen.h Source/RenderGraph.cpp Source/RenderGraph.h + Source/RenderToTextureBus.h Source/TextMarkup.cpp Source/TextMarkup.h Source/UiButtonComponent.cpp diff --git a/Gems/LyShine/LyShineScript/LyShinePass.data b/Gems/LyShine/LyShineScript/LyShinePass.data new file mode 100644 index 0000000000..af44db91ed --- /dev/null +++ b/Gems/LyShine/LyShineScript/LyShinePass.data @@ -0,0 +1,20 @@ + { + "Name": "LyShinePass", + "TemplateName": "LyShineParentTemplate", + "Connections": [ + { + "LocalSlot": "ColorInputOutput", + "AttachmentRef": { + "Pass": "DebugOverlayPass", + "Attachment": "InputOutput" + } + }, + { + "LocalSlot": "DepthInputOutput", + "AttachmentRef": { + "Pass": "DepthPrePass", + "Attachment": "Depth" + } + } + ] + } \ No newline at end of file diff --git a/Gems/LyShine/LyShineScript/PatchRenderPipeline.py b/Gems/LyShine/LyShineScript/PatchRenderPipeline.py new file mode 100644 index 0000000000..09a0049e81 --- /dev/null +++ b/Gems/LyShine/LyShineScript/PatchRenderPipeline.py @@ -0,0 +1,71 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT + +""" + +import os +import sys + +# Parse arguments +if len(sys.argv) != 3: + print('Incorrect number of args') + exit() + +engine_path = sys.argv[1] +if not os.path.exists(engine_path): + print(f'Given path {engine_path} does not exist') + exit() + +project_path = sys.argv[2] +if not os.path.exists(project_path): + print(f'Given path {project_path} does not exist') + exit() + +sys.path.insert(0, os.path.join(engine_path, 'Gems/Atom/RPI/Tools/')) + +from atom_rpi_tools.pass_data import PassTemplate +import atom_rpi_tools.utils as utils + +# Folder of this py file +dir_name = os.path.dirname(os.path.realpath(__file__)) + +# Patch render pipeline to insert a custom LyShine parent pass + +# Gem::Atom_Feature_Common gem's path since default render pipeline is comming from this gem +gem_assets_path = os.path.join(engine_path,'Gems/Atom/feature/Common/Assets/') + +pipeline_relatvie_path = 'Passes/MainPipeline.pass' +srcRenderPipeline = os.path.join(gem_assets_path, pipeline_relatvie_path) +destRenderPipeline = os.path.join(project_path, pipeline_relatvie_path) +# If the project doesn't have a customized main pipeline +# copy the default render pipeline from Atom_Common_Feature gem to same path in project folder +utils.find_or_copy_file(destRenderPipeline, srcRenderPipeline) + +# Load project render pipeline +renderPipeline = PassTemplate(destRenderPipeline) + +# Skip if LyShinePass already exist +newPassName = 'LyShinePass' +if renderPipeline.find_pass(newPassName)>-1: + print('Skip merging. LyShinePass already exists') + exit() + +# Insert LyShinePass between DebugOverlayPass and UIPass +refPass = 'DebugOverlayPass' +# The data file for new pass request is in the same folder of the py file +newPassRequestFilePath = os.path.join(dir_name, 'LyShinePass.data') +newPassRequestData = utils.load_json_file(newPassRequestFilePath) +insertIndex = renderPipeline.find_pass(refPass) + 1 +if insertIndex>-1: + renderPipeline.insert_pass_request(insertIndex, newPassRequestData) +else: + print('Failed to find ', refPass) + exit() + +# Update attachment references for the passes following LyShinePass +renderPipeline.replace_references_after(newPassName, 'DebugOverlayPass', 'InputOutput', 'LyShinePass', 'ColorInputOutput') + +# Save the updated render pipeline +renderPipeline.save() diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimNode.cpp b/Gems/Maestro/Code/Source/Cinematics/AnimNode.cpp index e932f21388..828e5ad20f 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/AnimNode.cpp @@ -74,7 +74,7 @@ void CAnimNode::Activate([[maybe_unused]] bool bActivate) ////////////////////////////////////////////////////////////////////////// int CAnimNode::GetTrackCount() const { - return m_tracks.size(); + return static_cast(m_tracks.size()); } const char* CAnimNode::GetParamName(const CAnimParamType& paramType) const diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp b/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp index fd7f99c9b3..9da32d757a 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/AnimPostFXNode.cpp @@ -288,7 +288,7 @@ void CAnimPostFXNode::SerializeAnims(XmlNodeRef& xmlNode, bool bLoading, bool bL //----------------------------------------------------------------------------- unsigned int CAnimPostFXNode::GetParamCount() const { - return m_pDescription->m_nodeParams.size(); + return static_cast(m_pDescription->m_nodeParams.size()); } //----------------------------------------------------------------------------- diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimScreenFaderNode.cpp b/Gems/Maestro/Code/Source/Cinematics/AnimScreenFaderNode.cpp index 22e3cbba86..62cffcefb1 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimScreenFaderNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/AnimScreenFaderNode.cpp @@ -114,7 +114,7 @@ void CAnimScreenFaderNode::Animate(SAnimContext& ac) for (size_t nFaderTrackNo = 0; nFaderTrackNo < nScreenFaderTracksNumber; ++nFaderTrackNo) { - CScreenFaderTrack* pTrack = static_cast(GetTrackForParameter(AnimParamType::ScreenFader, nFaderTrackNo)); + CScreenFaderTrack* pTrack = static_cast(GetTrackForParameter(AnimParamType::ScreenFader, static_cast(nFaderTrackNo))); if (!pTrack) { @@ -298,7 +298,7 @@ void CAnimScreenFaderNode::Reflect(AZ::ReflectContext* context) //----------------------------------------------------------------------------- unsigned int CAnimScreenFaderNode::GetParamCount() const { - return s_screenFaderNodeParams.size(); + return static_cast(s_screenFaderNodeParams.size()); } //----------------------------------------------------------------------------- @@ -350,7 +350,7 @@ bool CAnimScreenFaderNode::IsAnyTextureVisible() const size_t const paramCount = m_tracks.size(); for (size_t paramIndex = 0; paramIndex < paramCount; ++paramIndex) { - CScreenFaderTrack* pTrack = static_cast(GetTrackForParameter(AnimParamType::ScreenFader, paramIndex)); + CScreenFaderTrack* pTrack = static_cast(GetTrackForParameter(AnimParamType::ScreenFader, static_cast(paramIndex))); if (!pTrack) { diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp b/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp index 23017e5779..6caa918227 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/AnimSequence.cpp @@ -66,7 +66,7 @@ CAnimSequence::CAnimSequence() CAnimSequence::~CAnimSequence() { // clear reference to me from all my nodes - for (int i = m_nodes.size(); --i >= 0;) + for (int i = static_cast(m_nodes.size()); --i >= 0;) { if (m_nodes[i]) { @@ -181,7 +181,7 @@ const IAnimSequence* CAnimSequence::GetParentSequence() const ////////////////////////////////////////////////////////////////////////// int CAnimSequence::GetNodeCount() const { - return m_nodes.size(); + return static_cast(m_nodes.size()); } ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Maestro/Code/Source/Cinematics/AnimTrack.h b/Gems/Maestro/Code/Source/Cinematics/AnimTrack.h index 2a1aa970e5..b65dad1323 100644 --- a/Gems/Maestro/Code/Source/Cinematics/AnimTrack.h +++ b/Gems/Maestro/Code/Source/Cinematics/AnimTrack.h @@ -96,7 +96,7 @@ public: } //! Return number of keys in track. - virtual int GetNumKeys() const { return m_keys.size(); }; + virtual int GetNumKeys() const { return static_cast(m_keys.size()); }; //! Return true if keys exists in this track virtual bool HasKeys() const { return !m_keys.empty(); } @@ -575,7 +575,7 @@ inline int TAnimTrack::GetActiveKey(float time, KeyType* key) return -1; } - int nkeys = m_keys.size(); + int nkeys = static_cast(m_keys.size()); if (nkeys == 0) { m_lastTime = time; diff --git a/Gems/Maestro/Code/Source/Cinematics/BoolTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/BoolTrack.cpp index 3b3e9a213c..b64abcc64f 100644 --- a/Gems/Maestro/Code/Source/Cinematics/BoolTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/BoolTrack.cpp @@ -38,7 +38,7 @@ void CBoolTrack::GetValue(float time, bool& value) CheckValid(); - int nkeys = m_keys.size(); + int nkeys = static_cast(m_keys.size()); if (nkeys < 1) { return; diff --git a/Gems/Maestro/Code/Source/Cinematics/CommentNode.cpp b/Gems/Maestro/Code/Source/Cinematics/CommentNode.cpp index a24b207e6e..fc58b91723 100644 --- a/Gems/Maestro/Code/Source/Cinematics/CommentNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/CommentNode.cpp @@ -114,7 +114,7 @@ void CCommentNode::Reflect(AZ::ReflectContext* context) //----------------------------------------------------------------------------- unsigned int CCommentNode::GetParamCount() const { - return s_nodeParameters.size(); + return static_cast(s_nodeParameters.size()); } //----------------------------------------------------------------------------- diff --git a/Gems/Maestro/Code/Source/Cinematics/GotoTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/GotoTrack.cpp index 8fac693496..350741f688 100644 --- a/Gems/Maestro/Code/Source/Cinematics/GotoTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/GotoTrack.cpp @@ -132,7 +132,7 @@ void CGotoTrack::SetKeyAtTime(float time, IKey* key) if (fabs(keyt - time) < MIN_TIME_PRECISION) { key->flags = m_keys[i].flags; // Reserve the flag value. - SetKey(i, key); + SetKey(static_cast(i), key); found = true; break; } diff --git a/Gems/Maestro/Code/Source/Cinematics/LayerNode.cpp b/Gems/Maestro/Code/Source/Cinematics/LayerNode.cpp index fb28fb71a3..8c518f5a54 100644 --- a/Gems/Maestro/Code/Source/Cinematics/LayerNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/LayerNode.cpp @@ -138,7 +138,7 @@ void CLayerNode::Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTr //----------------------------------------------------------------------------- unsigned int CLayerNode::GetParamCount() const { - return s_nodeParams.size(); + return static_cast(s_nodeParams.size()); } //----------------------------------------------------------------------------- diff --git a/Gems/Maestro/Code/Source/Cinematics/MaterialNode.cpp b/Gems/Maestro/Code/Source/Cinematics/MaterialNode.cpp index b045ae0050..08d4d92e8b 100644 --- a/Gems/Maestro/Code/Source/Cinematics/MaterialNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/MaterialNode.cpp @@ -174,7 +174,7 @@ void CAnimMaterialNode::UpdateDynamicParamsInternal() ////////////////////////////////////////////////////////////////////////// unsigned int CAnimMaterialNode::GetParamCount() const { - return s_nodeParams.size() + m_dynamicShaderParamInfos.size(); + return static_cast(s_nodeParams.size() + m_dynamicShaderParamInfos.size()); } ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Maestro/Code/Source/Cinematics/Movie.cpp b/Gems/Maestro/Code/Source/Cinematics/Movie.cpp index b7fb82e0e7..bd586a12c1 100644 --- a/Gems/Maestro/Code/Source/Cinematics/Movie.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/Movie.cpp @@ -379,7 +379,7 @@ IAnimSequence* CMovieSystem::GetSequence(int i) const ////////////////////////////////////////////////////////////////////////// int CMovieSystem::GetNumSequences() const { - return m_sequences.size(); + return static_cast(m_sequences.size()); } ////////////////////////////////////////////////////////////////////////// @@ -398,7 +398,7 @@ IAnimSequence* CMovieSystem::GetPlayingSequence(int i) const ////////////////////////////////////////////////////////////////////////// int CMovieSystem::GetNumPlayingSequences() const { - return m_playingSequences.size(); + return static_cast(m_playingSequences.size()); } ////////////////////////////////////////////////////////////////////////// @@ -410,7 +410,7 @@ void CMovieSystem::AddSequence(IAnimSequence* sequence) ////////////////////////////////////////////////////////////////////////// bool CMovieSystem::IsCutScenePlaying() const { - const uint numPlayingSequences = m_playingSequences.size(); + const uint numPlayingSequences = static_cast(m_playingSequences.size()); for (uint i = 0; i < numPlayingSequences; ++i) { const IAnimSequence* pAnimSequence = m_playingSequences[i].sequence.get(); diff --git a/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp b/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp index be6d18eeb2..d4b894dc92 100644 --- a/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/SceneNode.cpp @@ -254,7 +254,7 @@ void CAnimSceneNode::CreateDefaultTracks() ////////////////////////////////////////////////////////////////////////// unsigned int CAnimSceneNode::GetParamCount() const { - return s_nodeParams.size(); + return static_cast(s_nodeParams.size()); } ////////////////////////////////////////////////////////////////////////// @@ -661,7 +661,7 @@ void CAnimSceneNode::OnStop() ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::ResetSounds() { - for (int i = m_SoundInfo.size(); --i >= 0; ) + for (int i = static_cast(m_SoundInfo.size()); --i >= 0; ) { m_SoundInfo[i].Reset(); } diff --git a/Gems/Maestro/Code/Source/Cinematics/ShadowsSetupNode.cpp b/Gems/Maestro/Code/Source/Cinematics/ShadowsSetupNode.cpp index 0adb27f49f..fd5e30199e 100644 --- a/Gems/Maestro/Code/Source/Cinematics/ShadowsSetupNode.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/ShadowsSetupNode.cpp @@ -81,7 +81,7 @@ void CShadowsSetupNode::OnReset() //----------------------------------------------------------------------------- unsigned int CShadowsSetupNode::GetParamCount() const { - return ShadowSetupNode::s_shadowSetupParams.size(); + return static_cast(ShadowSetupNode::s_shadowSetupParams.size()); } //----------------------------------------------------------------------------- diff --git a/Gems/Maestro/Code/Source/Cinematics/TimeRangesTrack.cpp b/Gems/Maestro/Code/Source/Cinematics/TimeRangesTrack.cpp index 8cce920dc0..2b71aed3b5 100644 --- a/Gems/Maestro/Code/Source/Cinematics/TimeRangesTrack.cpp +++ b/Gems/Maestro/Code/Source/Cinematics/TimeRangesTrack.cpp @@ -69,7 +69,7 @@ void CTimeRangesTrack::GetKeyInfo(int key, const char*& description, float& dura int CTimeRangesTrack::GetActiveKeyIndexForTime(const float time) { - const unsigned int numKeys = m_keys.size(); + const unsigned int numKeys = static_cast(m_keys.size()); if (numKeys == 0 || m_keys[0].time > time) { diff --git a/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp b/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp index 5533bc14a9..4264dd0ab3 100644 --- a/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp +++ b/Gems/Maestro/Code/Source/Components/EditorSequenceAgentComponent.cpp @@ -231,7 +231,7 @@ namespace Maestro // check for paramType specialization attributes on the getter method of the virtual property. if found, reset // to the eAnimParamType enum - this leaves the paramType name unchanged but changes the type. - for (int i = virtualProperty->m_getter->m_attributes.size(); --i >= 0;) + for (int i = static_cast(virtualProperty->m_getter->m_attributes.size()); --i >= 0;) { if (virtualProperty->m_getter->m_attributes[i].first == AZ::Edit::Attributes::PropertyPosition) { diff --git a/Gems/MessagePopup/Code/Source/MessagePopupManager.h b/Gems/MessagePopup/Code/Source/MessagePopupManager.h index 7fdaf8d918..7dde587416 100644 --- a/Gems/MessagePopup/Code/Source/MessagePopupManager.h +++ b/Gems/MessagePopup/Code/Source/MessagePopupManager.h @@ -27,7 +27,7 @@ namespace MessagePopup bool RemovePopup(AZ::u32 _popupID); void* GetPopupClientData(AZ::u32 _popupID); MessagePopupInfo* GetPopupInfo(AZ::u32 _popupID); - AZ::u32 GetNumActivePopups() const { return m_currentPopups.size(); } + AZ::u32 GetNumActivePopups() const { return static_cast(m_currentPopups.size()); } protected: ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Microphone/Code/Source/Platform/Windows/MicrophoneSystemComponent_Windows.cpp b/Gems/Microphone/Code/Source/Platform/Windows/MicrophoneSystemComponent_Windows.cpp index 80e42cf208..c182ec4f3b 100644 --- a/Gems/Microphone/Code/Source/Platform/Windows/MicrophoneSystemComponent_Windows.cpp +++ b/Gems/Microphone/Code/Source/Platform/Windows/MicrophoneSystemComponent_Windows.cpp @@ -384,7 +384,7 @@ namespace Audio src_short_to_float_array( reinterpret_cast(m_conversionBufferIn.m_data), reinterpret_cast(m_conversionBufferOut.m_data), - numFrames * m_config.m_numChannels + static_cast(numFrames * m_config.m_numChannels) ); // Swap to move the 'working' buffer back to the 'In' buffer. @@ -397,8 +397,8 @@ namespace Audio { // Setup Conversion Data m_srcData.end_of_input = 0; - m_srcData.input_frames = numFrames; - m_srcData.output_frames = numFrames; + m_srcData.input_frames = static_cast(numFrames); + m_srcData.output_frames = static_cast(numFrames); m_srcData.data_in = reinterpret_cast(m_conversionBufferIn.m_data); m_srcData.data_out = reinterpret_cast(m_conversionBufferOut.m_data); @@ -478,7 +478,7 @@ namespace Audio src_float_to_short_array( reinterpret_cast(m_conversionBufferIn.m_data), *reinterpret_cast(outputData), - numFrames * m_config.m_numChannels + static_cast(numFrames * m_config.m_numChannels) ); } else diff --git a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp index 23578e5c18..242db95ecb 100644 --- a/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/LocalPredictionPlayerInputComponent.cpp @@ -201,7 +201,7 @@ namespace Multiplayer // Produce correction for client AzNetworking::PacketEncodingBuffer correction; correction.Resize(correction.GetCapacity()); - AzNetworking::NetworkInputSerializer serializer(correction.GetBuffer(), correction.GetCapacity()); + AzNetworking::NetworkInputSerializer serializer(correction.GetBuffer(), static_cast(correction.GetCapacity())); // only deserialize if we have data (for client/server profile/debug mismatches) if (correction.GetSize() > 0) @@ -221,7 +221,7 @@ namespace Multiplayer { // In debug, show which states caused the correction // Write in client state - AzNetworking::NetworkOutputSerializer clientStateSerializer(clientState.GetBuffer(), clientState.GetSize()); + AzNetworking::NetworkOutputSerializer clientStateSerializer(clientState.GetBuffer(), static_cast(clientState.GetSize())); GetNetBindComponent()->SerializeEntityCorrection(clientStateSerializer); // Read out state values @@ -229,7 +229,7 @@ namespace Multiplayer GetNetBindComponent()->SerializeEntityCorrection(clientValues); // Restore server state - AzNetworking::NetworkOutputSerializer serverStateSerializer(correction.GetBuffer(), correction.GetSize()); + AzNetworking::NetworkOutputSerializer serverStateSerializer(correction.GetBuffer(), static_cast(correction.GetSize())); GetNetBindComponent()->SerializeEntityCorrection(serverStateSerializer); // Read out state values @@ -355,7 +355,7 @@ namespace Multiplayer m_lastCorrectionInputId = inputId; // Apply the correction - AzNetworking::TrackChangedSerializer serializer(correction.GetBuffer(), correction.GetSize()); + AzNetworking::TrackChangedSerializer serializer(correction.GetBuffer(), static_cast(correction.GetSize())); GetNetBindComponent()->SerializeEntityCorrection(serializer); m_correctionEvent.Signal(); @@ -367,7 +367,7 @@ namespace Multiplayer GetCorrectionDataString(GetNetBindComponent()).c_str() ); - const uint32_t inputHistorySize = m_inputHistory.Size(); + const uint32_t inputHistorySize = static_cast(m_inputHistory.Size()); const uint32_t historicalDelta = aznumeric_cast(m_clientInputId - inputId); // Do not replay the move we just corrected, that was already processed by the server // If this correction is for a move outside our input history window, just start replaying from the oldest move we have available @@ -528,7 +528,7 @@ namespace Multiplayer #ifndef AZ_RELEASE_BUILD if (cl_EnableDesyncDebugging) { - AzNetworking::NetworkInputSerializer processInputResultSerializer(processInputResult.GetBuffer(), processInputResult.GetCapacity()); + AzNetworking::NetworkInputSerializer processInputResultSerializer(processInputResult.GetBuffer(), static_cast(processInputResult.GetCapacity())); GetNetBindComponent()->SerializeEntityCorrection(processInputResultSerializer); processInputResult.Resize(processInputResultSerializer.GetSize()); } diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp index deb53bacab..fc398182ef 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp @@ -32,6 +32,7 @@ namespace Multiplayer { m_networkEditorInterface = AZ::Interface::Get()->CreateNetworkInterface( AZ::Name(MPEditorInterfaceName), ProtocolType::Tcp, TrustZone::ExternalClientToServer, *this); + m_networkEditorInterface->SetTimeoutEnabled(false); if (editorsv_isDedicated) { uint16_t editorServerPort = DefaultServerEditorPort; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp index 9030b150e6..d557c65215 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp @@ -147,13 +147,9 @@ namespace Multiplayer processLaunchInfo.m_showWindow = true; processLaunchInfo.m_processPriority = AzFramework::ProcessPriority::PROCESSPRIORITY_NORMAL; - // Launch the Server and give it a few seconds to boot up + // Launch the Server AzFramework::ProcessWatcher* outProcess = AzFramework::ProcessWatcher::LaunchProcess( processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); - if (outProcess) - { - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(15000)); - } return outProcess; } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index b9e9a9a87e..b8a77dab58 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -769,7 +769,7 @@ namespace Multiplayer return HandleEntityDeleteMessage(entityReplicator, packetHeader, updateMessage); } - AzNetworking::TrackChangedSerializer outputSerializer(updateMessage.GetData()->GetBuffer(), updateMessage.GetData()->GetSize()); + AzNetworking::TrackChangedSerializer outputSerializer(updateMessage.GetData()->GetBuffer(), static_cast(updateMessage.GetData()->GetSize())); PrefabEntityId prefabEntityId; if (updateMessage.GetHasValidPrefabId()) @@ -1102,7 +1102,7 @@ namespace Multiplayer // Send an update packet if it needs one propPublisher->GenerateRecord(); bool needsNetworkPropertyUpdate = propPublisher->PrepareSerialization(); - AzNetworking::NetworkInputSerializer inputSerializer(message.m_propertyUpdateData.GetBuffer(), message.m_propertyUpdateData.GetCapacity()); + AzNetworking::NetworkInputSerializer inputSerializer(message.m_propertyUpdateData.GetBuffer(), static_cast(message.m_propertyUpdateData.GetCapacity())); if (needsNetworkPropertyUpdate) { // Write out entity state into the buffer @@ -1127,7 +1127,7 @@ namespace Multiplayer { if (message.m_propertyUpdateData.GetSize() > 0) { - AzNetworking::TrackChangedSerializer outputSerializer(message.m_propertyUpdateData.GetBuffer(), message.m_propertyUpdateData.GetSize()); + AzNetworking::TrackChangedSerializer outputSerializer(message.m_propertyUpdateData.GetBuffer(), static_cast(message.m_propertyUpdateData.GetSize())); if (!HandlePropertyChangeMessage ( replicator, diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp index 93fd3ea652..eb51c3c478 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp @@ -430,7 +430,7 @@ namespace Multiplayer updateMessage.SetPrefabEntityId(netBindComponent->GetPrefabEntityId()); } - AzNetworking::NetworkInputSerializer inputSerializer(updateMessage.ModifyData().GetBuffer(), updateMessage.ModifyData().GetCapacity()); + AzNetworking::NetworkInputSerializer inputSerializer(updateMessage.ModifyData().GetBuffer(), static_cast(updateMessage.ModifyData().GetCapacity())); m_propertyPublisher->UpdateSerialization(inputSerializer); updateMessage.ModifyData().Resize(inputSerializer.GetSize()); diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index 1460d015fa..cff05b9151 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -75,7 +75,7 @@ namespace Multiplayer uint32_t NetworkEntityManager::GetEntityCount() const { - return m_networkEntityTracker.size(); + return static_cast(m_networkEntityTracker.size()); } NetworkEntityHandle NetworkEntityManager::AddEntityToEntityMap(NetEntityId netEntityId, AZ::Entity* entity) diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp index 85fc7118cc..5f4b849eac 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityRpcMessage.cpp @@ -97,7 +97,7 @@ namespace Multiplayer + sizeof(RpcIndex); // 2-byte size header + the actual blob payload itself - const uint32_t sizeOfBlob = (m_data != nullptr) ? sizeof(uint16_t) + m_data->GetSize() : 0; + const uint32_t sizeOfBlob = static_cast((m_data != nullptr) ? sizeof(uint16_t) + m_data->GetSize() : 0); // No sliceId, remote replicator already exists so we don't need to know what type of entity this is return sizeOfFields + sizeOfBlob; @@ -135,7 +135,7 @@ namespace Multiplayer m_data = AZStd::make_unique(); } - AzNetworking::NetworkInputSerializer serializer(m_data->GetBuffer(), m_data->GetCapacity()); + AzNetworking::NetworkInputSerializer serializer(m_data->GetBuffer(), static_cast(m_data->GetCapacity())); if (params.Serialize(serializer)) { m_data->Resize(serializer.GetSize()); @@ -154,7 +154,7 @@ namespace Multiplayer return false; } - AzNetworking::NetworkOutputSerializer serializer(m_data->GetBuffer(), m_data->GetSize()); + AzNetworking::NetworkOutputSerializer serializer(m_data->GetBuffer(), static_cast(m_data->GetSize())); return outParams.Serialize(serializer); } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp index 1bf10d0ad0..4a2f12ce17 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityUpdateMessage.cpp @@ -128,7 +128,7 @@ namespace Multiplayer } // 2-byte size header + the actual blob payload itself - const uint32_t sizeOfBlob = (m_data != nullptr) ? sizeof(PropertyIndex) + m_data->GetSize() : 0; + const uint32_t sizeOfBlob = static_cast((m_data != nullptr) ? sizeof(PropertyIndex) + m_data->GetSize() : 0); if (m_hasValidPrefabId) { diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetBindMarkerComponent.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetBindMarkerComponent.cpp index 9b3187d46d..c8abac25cb 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetBindMarkerComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetBindMarkerComponent.cpp @@ -67,7 +67,7 @@ namespace Multiplayer AZ::Name spawnableName = AZ::Interface::Get()->GetSpawnableNameFromAssetId(spawnableAssetId); PrefabEntityId prefabEntityId; prefabEntityId.m_prefabName = spawnableName; - prefabEntityId.m_entityOffset = netEntityIndex; + prefabEntityId.m_entityOffset = static_cast(netEntityIndex); AZ::Interface::Get()->SetupNetEntity(netEntity, prefabEntityId, NetEntityRole::Authority); } else diff --git a/Gems/MultiplayerCompression/Code/Source/LZ4Compressor.cpp b/Gems/MultiplayerCompression/Code/Source/LZ4Compressor.cpp index a9001d0e80..351935d0bb 100644 --- a/Gems/MultiplayerCompression/Code/Source/LZ4Compressor.cpp +++ b/Gems/MultiplayerCompression/Code/Source/LZ4Compressor.cpp @@ -20,7 +20,7 @@ namespace MultiplayerCompression size_t LZ4Compressor::GetMaxCompressedBufferSize(size_t uncompSize) const { - return LZ4_compressBound(uncompSize); + return LZ4_compressBound(static_cast(uncompSize)); } AzNetworking::CompressorError LZ4Compressor::Compress @@ -46,7 +46,7 @@ namespace MultiplayerCompression return AzNetworking::CompressorError::Uninitialized; } - const int compWorstCaseSize = LZ4_compressBound(uncompSize); + const int compWorstCaseSize = LZ4_compressBound(static_cast(uncompSize)); if (compWorstCaseSize == 0) { AZ_Warning("Multiplayer Compressor", false, "Input size (%lu) passed to Compress() is greater than max allowed (%lu)", uncompSize, LZ4_MAX_INPUT_SIZE); @@ -56,7 +56,7 @@ namespace MultiplayerCompression AZ_Warning("Multiplayer Compressor", compDataSize >= compWorstCaseSize, "Outbuffer size (%lu B) passed to Compress() is less than estimated worst case (%lu B)", compDataSize, compWorstCaseSize); // Note that this returns a non-negative int so we are narrowing into a size_t here - compSize = LZ4_compressHC(reinterpret_cast(uncompData), reinterpret_cast(compData), uncompSize); + compSize = LZ4_compressHC(reinterpret_cast(uncompData), reinterpret_cast(compData), static_cast(uncompSize)); if (compSize == 0) { @@ -84,7 +84,7 @@ namespace MultiplayerCompression return AzNetworking::CompressorError::Uninitialized; } - const int uncompSize = LZ4_decompress_safe(reinterpret_cast(compData), reinterpret_cast(uncompData), compDataSize, uncompDataSize); + const int uncompSize = LZ4_decompress_safe(reinterpret_cast(compData), reinterpret_cast(uncompData), static_cast(compDataSize), static_cast(uncompDataSize)); consumedSizeOut = compDataSize; if (uncompSize < 0) diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothColliders.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothColliders.cpp index 660220c446..1e57999b6e 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothColliders.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothColliders.cpp @@ -112,7 +112,7 @@ namespace NvCloth colliderConfig.get(), static_cast(shapeConfigPair.second.get()), static_cast(jointIndex), - sphereCount); + static_cast(sphereCount)); sphereColliders.push_back(sphereCollider); ++sphereCount; @@ -144,9 +144,9 @@ namespace NvCloth colliderConfig.get(), static_cast(shapeConfigPair.second.get()), static_cast(jointIndex), - capsuleCount * 2, // Each capsule holds 2 sphere indices - sphereCount + 0, // First sphere index - sphereCount + 1); // Second sphere index + static_cast(capsuleCount * 2), // Each capsule holds 2 sphere indices + static_cast(sphereCount + 0), // First sphere index + static_cast(sphereCount + 1)); // Second sphere index capsuleColliders.push_back(capsuleCollider); ++capsuleCount; diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothSkinning.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothSkinning.cpp index d42d66293b..5359ed6ad5 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothSkinning.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ActorClothSkinning.cpp @@ -481,13 +481,13 @@ namespace NvCloth if (remappedIndex >= 0) { - actorClothSkinning->m_simulatedVertices[remappedIndex] = vertexIndex; + actorClothSkinning->m_simulatedVertices[remappedIndex] = static_cast(vertexIndex); } if (remappedIndex < 0 || originalMeshParticles[vertexIndex].GetW() == 0.0f) { - actorClothSkinning->m_nonSimulatedVertices.emplace_back(vertexIndex); + actorClothSkinning->m_nonSimulatedVertices.emplace_back(static_cast(vertexIndex)); } } actorClothSkinning->m_nonSimulatedVertices.shrink_to_fit(); diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp index bcce080752..5a7564d72a 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp @@ -556,7 +556,7 @@ namespace NvCloth for (size_t index = 0; index < numVertices; ++index) { - const int renderVertexIndex = firstVertex + index; + const int renderVertexIndex = static_cast(firstVertex + index); const SimParticleFormat& renderParticle = renderParticles[renderVertexIndex]; destVerticesBuffer[index].Set( diff --git a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp index 383ea9e5f6..a2683be2ab 100644 --- a/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp +++ b/Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRule.cpp @@ -37,7 +37,15 @@ namespace NvCloth const AZ::SceneAPI::Containers::SceneGraph& graph, const size_t numVertices) const { - const auto meshNodeIndex = graph.Find(GetMeshNodeName()); + const AZ::SceneAPI::Containers::SceneGraph::NodeIndex meshNodeIndex = [this, &graph]() + { + if (const auto index = graph.Find(GetMeshNodeName() + AZStd::string(AZ::SceneAPI::Utilities::OptimizedMeshSuffix)); index.IsValid()) + { + return index; + } + return graph.Find(GetMeshNodeName()); + }(); + if (!meshNodeIndex.IsValid()) { return {}; diff --git a/Gems/NvCloth/Code/Tests/System/ClothTest.cpp b/Gems/NvCloth/Code/Tests/System/ClothTest.cpp index 63d8c78dff..15940570f7 100644 --- a/Gems/NvCloth/Code/Tests/System/ClothTest.cpp +++ b/Gems/NvCloth/Code/Tests/System/ClothTest.cpp @@ -145,7 +145,7 @@ namespace UnitTest }}; nv::cloth::Vector::Type nvEmpty; - nv::cloth::Vector::Type nvValues(azValues.size()); + nv::cloth::Vector::Type nvValues(static_cast(azValues.size())); nv::cloth::Range nvEmptyRange(nvEmpty.begin(), nvEmpty.end()); nv::cloth::Range nvValuesRange(nvValues.begin(), nvValues.end()); @@ -192,7 +192,7 @@ namespace UnitTest }}; nv::cloth::Vector::Type nvEmpty; - nv::cloth::Vector::Type nvValues(azValues.size()); + nv::cloth::Vector::Type nvValues(static_cast(azValues.size())); nv::cloth::Range nvEmptyRange(nvEmpty.begin(), nvEmpty.end()); nv::cloth::Range nvValuesRange(nvValues.begin(), nvValues.end()); @@ -336,7 +336,7 @@ namespace UnitTest const nv::cloth::MappedRange nvClothPreviousParticles = nv::cloth::readPreviousParticles(*m_nvCloth); for (size_t i = 0; i < newParticles.size(); ++i) { - EXPECT_NEAR(newParticles[i].GetW(), nvClothPreviousParticles[i].w, Tolerance); + EXPECT_NEAR(newParticles[i].GetW(), nvClothPreviousParticles[static_cast(i)].w, Tolerance); } } @@ -364,7 +364,7 @@ namespace UnitTest const nv::cloth::MappedRange nvClothPreviousParticles = nv::cloth::readPreviousParticles(*m_nvCloth); for (size_t i = 0; i < newParticles.size(); ++i) { - EXPECT_NEAR(newParticles[i].GetW(), nvClothPreviousParticles[i].w, Tolerance); + EXPECT_NEAR(newParticles[i].GetW(), nvClothPreviousParticles[static_cast(i)].w, Tolerance); } } @@ -378,7 +378,7 @@ namespace UnitTest EXPECT_EQ(nvClothCurrentParticles.size(), nvClothPreviousParticles.size()); for (size_t i = 0; i < nvClothCurrentParticles.size(); ++i) { - ExpectEq(nvClothCurrentParticles[i], nvClothPreviousParticles[i]); + ExpectEq(nvClothCurrentParticles[static_cast(i)], nvClothPreviousParticles[static_cast(i)]); } } @@ -468,7 +468,7 @@ namespace UnitTest EXPECT_EQ(nvClothCurrentParticles.size(), nvClothPreviousParticles.size()); for (size_t i = 0; i < nvClothCurrentParticles.size(); ++i) { - ExpectEq(nvClothCurrentParticles[i], nvClothPreviousParticles[i]); + ExpectEq(nvClothCurrentParticles[static_cast(i)], nvClothPreviousParticles[static_cast(i)]); } } @@ -504,8 +504,8 @@ namespace UnitTest EXPECT_EQ(initialParticles.size(), nvClothPreviousParticles.size()); for (size_t i = 0; i < initialParticles.size(); ++i) { - ExpectEq(initialParticles[i], nvClothCurrentParticles[i]); - ExpectEq(initialParticles[i], nvClothPreviousParticles[i]); + ExpectEq(initialParticles[i], nvClothCurrentParticles[static_cast(i)]); + ExpectEq(initialParticles[i], nvClothPreviousParticles[static_cast(i)]); } } @@ -614,7 +614,7 @@ namespace UnitTest const nv::cloth::MappedRange nvClothPreviousParticles = nv::cloth::readPreviousParticles(*m_nvCloth); for (size_t i = 0; i < initialParticles.size(); ++i) { - EXPECT_NEAR(nvClothPreviousParticles[i].w, initialParticles[i].GetW() / globalMass, Tolerance); + EXPECT_NEAR(nvClothPreviousParticles[static_cast(i)].w, initialParticles[i].GetW() / globalMass, Tolerance); } } } // namespace UnitTest diff --git a/Gems/PhysX/Code/Editor/MaterialIdWidget.cpp b/Gems/PhysX/Code/Editor/MaterialIdWidget.cpp index 7bbdf91c20..4fba93da39 100644 --- a/Gems/PhysX/Code/Editor/MaterialIdWidget.cpp +++ b/Gems/PhysX/Code/Editor/MaterialIdWidget.cpp @@ -69,7 +69,7 @@ namespace PhysX auto lockToDefault = [gui]() { - gui->addItem(QLatin1String(Physics::DefaultPhysicsMaterialLabel.data(), Physics::DefaultPhysicsMaterialLabel.size())); + gui->addItem(QLatin1String(Physics::DefaultPhysicsMaterialLabel.data(), static_cast(Physics::DefaultPhysicsMaterialLabel.size()))); gui->setCurrentIndex(0); return false; }; @@ -98,7 +98,7 @@ namespace PhysX // Add default physics material first m_libraryIds.push_back(Physics::MaterialId()); - gui->addItem(QLatin1String(Physics::DefaultPhysicsMaterialLabel.data(), Physics::DefaultPhysicsMaterialLabel.size())); + gui->addItem(QLatin1String(Physics::DefaultPhysicsMaterialLabel.data(), static_cast(Physics::DefaultPhysicsMaterialLabel.size()))); for (const auto& material : materials) { diff --git a/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp b/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp index 6dc845199a..e4c65c8667 100644 --- a/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp +++ b/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp @@ -24,7 +24,7 @@ namespace PhysX { - constexpr const char* DefaultAssetFilename = "SurfaceTypeMaterialLibrary"; + constexpr const char* DefaultAssetFilePath = "Physics/SurfaceTypeMaterialLibrary"; constexpr const char* TemplateAssetFilename = "PhysX/TemplateMaterialLibrary"; static AZStd::optional> GetMaterialLibraryTemplate() @@ -227,7 +227,7 @@ namespace PhysX const AZStd::string& assetExtension = assetTypeExtensions[0]; // Use the path relative to the asset root to avoid hardcoding full path in the configuration - AZStd::string relativePath = DefaultAssetFilename; + AZStd::string relativePath = DefaultAssetFilePath; AzFramework::StringFunc::Path::ReplaceExtension(relativePath, assetExtension.c_str()); // Try to find an already existing material library @@ -237,9 +237,9 @@ namespace PhysX if (!resultAssetId.IsValid()) { // No file for the default material library, create it - const char* assetRoot = AZ::IO::FileIOBase::GetInstance()->GetAlias("@devassets@"); + const char* assetRoot = AZ::IO::FileIOBase::GetInstance()->GetAlias("@projectsourceassets@"); AZStd::string fullPath; - AzFramework::StringFunc::Path::ConstructFull(assetRoot, DefaultAssetFilename, assetExtension.c_str(), fullPath); + AzFramework::StringFunc::Path::ConstructFull(assetRoot, DefaultAssetFilePath, assetExtension.c_str(), fullPath); if (auto materialLibraryOpt = CreateMaterialLibrary(fullPath, relativePath)) { diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index 1409760742..c1056bdd73 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -780,7 +780,7 @@ namespace PhysX entityRigidbody->GetRigidBody()->IsKinematic() == false) { AZStd::string assetPath = m_shapeConfiguration.m_physicsAsset.m_configuration.m_asset.GetHint().c_str(); - const uint lastSlash = assetPath.rfind('/'); + const uint lastSlash = static_cast(assetPath.rfind('/')); if (lastSlash != AZStd::string::npos) { assetPath = assetPath.substr(lastSlash + 1); @@ -831,7 +831,7 @@ namespace PhysX if (shapeConfiguration) { - m_colliderDebugDraw.BuildMeshes(*shapeConfiguration, shapeIndex); + m_colliderDebugDraw.BuildMeshes(*shapeConfiguration, static_cast(shapeIndex)); } } } @@ -917,7 +917,7 @@ namespace PhysX const AZ::Vector3 overallScale = Utils::GetTransformScale(GetEntityId()) * m_cachedNonUniformScale * assetScale; m_colliderDebugDraw.DrawMesh(debugDisplay, *colliderConfiguration, *cookedMeshShapeConfiguration, - overallScale, shapeIndex); + overallScale, static_cast(shapeIndex)); break; } case Physics::ShapeType::Sphere: diff --git a/Gems/PhysX/Code/Source/Material.cpp b/Gems/PhysX/Code/Source/Material.cpp index be9e6385a1..813f86de0b 100644 --- a/Gems/PhysX/Code/Source/Material.cpp +++ b/Gems/PhysX/Code/Source/Material.cpp @@ -420,14 +420,14 @@ namespace PhysX if (physicsMaterialNameFromPhysicsAsset.empty() || physicsMaterialNameFromPhysicsAsset == Physics::DefaultPhysicsMaterialLabel) { - materialSelection.SetMaterialId(Physics::MaterialId(), slotIndex); + materialSelection.SetMaterialId(Physics::MaterialId(), static_cast(slotIndex)); continue; } if (auto it = FindOrCreateMaterial(physicsMaterialNameFromPhysicsAsset); it != m_materials.end()) { - materialSelection.SetMaterialId(Physics::MaterialId::FromUUID(it->first), slotIndex); + materialSelection.SetMaterialId(Physics::MaterialId::FromUUID(it->first), static_cast(slotIndex)); } else { @@ -435,7 +435,7 @@ namespace PhysX "UpdateMaterialSelectionFromPhysicsAsset: Physics material '%s' not found in the material library. Mesh material '%s' will use the default physics material.", physicsMaterialNameFromPhysicsAsset.c_str(), meshAsset->m_assetData.m_materialNames[slotIndex].c_str()); - materialSelection.SetMaterialId(Physics::MaterialId(), slotIndex); + materialSelection.SetMaterialId(Physics::MaterialId(), static_cast(slotIndex)); } } } diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp index 5d3f6bf0e1..038a1e2ee7 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp @@ -36,9 +36,6 @@ namespace PhysX } } // namespace Internal - // PhysX::Ragdoll - /*static*/ AZStd::mutex Ragdoll::m_sceneEventMutex; - void Ragdoll::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); @@ -109,14 +106,15 @@ namespace PhysX }) { m_sceneOwner = sceneHandle; + if (auto* sceneInterface = AZ::Interface::Get()) + { + sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler); + } } Ragdoll::~Ragdoll() { - { - AZStd::scoped_lock lock(m_sceneEventMutex); - m_sceneStartSimHandler.Disconnect(); - } + m_sceneStartSimHandler.Disconnect(); m_nodes.clear(); //the nodes destructor will remove the simulated body from the scene. } @@ -214,13 +212,6 @@ namespace PhysX } } - // the handler is also connected in EnableSimulationQueued(), - // which will call this function, so if called from that path dont connect here. - if (!m_sceneStartSimHandler.IsConnected()) - { - AZStd::scoped_lock lock(m_sceneEventMutex); - sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler); - } sceneInterface->EnableSimulationOfBody(m_sceneOwner, m_bodyHandle); } @@ -231,12 +222,6 @@ namespace PhysX return; } - if (auto* sceneInterface = AZ::Interface::Get()) - { - AZStd::scoped_lock lock(m_sceneEventMutex); - sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler); - } - m_queuedInitialState = initialState; } @@ -253,11 +238,6 @@ namespace PhysX return; } - { - AZStd::scoped_lock lock(m_sceneEventMutex); - m_sceneStartSimHandler.Disconnect(); - } - physx::PxScene* pxScene = Internal::GetPxScene(m_sceneOwner); const size_t numNodes = m_nodes.size(); diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h index 94a39d9732..c9d0d5d661 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h +++ b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h @@ -81,6 +81,5 @@ namespace PhysX bool m_queuedDisableSimulation = false; AzPhysics::SceneEvents::OnSceneSimulationStartHandler m_sceneStartSimHandler; - static AZStd::mutex m_sceneEventMutex; }; } // namespace PhysX diff --git a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp index 068e0f68df..412e53d0da 100644 --- a/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp +++ b/Gems/PhysX/Code/Source/Pipeline/MeshExporter.cpp @@ -155,13 +155,13 @@ namespace PhysX if (materialIndexIter != materialIndexByName.end()) { - return materialIndexIter->second; + return static_cast(materialIndexIter->second); } // Add it to the list otherwise sourceSceneMaterialNames.push_back(materialName); - AZ::u16 newIndex = sourceSceneMaterialNames.size() - 1; + AZ::u16 newIndex = static_cast(sourceSceneMaterialNames.size() - 1); materialIndexByName[materialName] = newIndex; return newIndex; @@ -417,7 +417,7 @@ namespace PhysX AZ_Assert(pxCooking, "Failed to create PxCooking"); physx::PxBoundedData strideData; - strideData.count = vertices.size(); + strideData.count = static_cast(vertices.size()); strideData.stride = sizeof(Vec3); strideData.data = vertices.data(); @@ -453,7 +453,7 @@ namespace PhysX physx::PxTriangleMeshDesc meshDesc; meshDesc.points = strideData; - meshDesc.triangles.count = indices.size() / 3; + meshDesc.triangles.count = static_cast(indices.size() / 3); meshDesc.triangles.stride = sizeof(AZ::u32) * 3; meshDesc.triangles.data = indices.data(); @@ -638,9 +638,9 @@ namespace PhysX { decomposer->Compute( vhacdVertices.data(), - vhacdVertices.size() / 3, + static_cast(vhacdVertices.size() / 3), nodeExportData.m_indices.data(), - nodeExportData.m_indices.size() / 3, + static_cast(nodeExportData.m_indices.size() / 3), vhacdParams ); } @@ -656,9 +656,9 @@ namespace PhysX decomposer->Compute( vhacdVertices.data(), - vhacdVertices.size() / 3, + static_cast(vhacdVertices.size() / 3), vhacdIndices.data(), - vhacdIndices.size() / 3, + static_cast(vhacdIndices.size() / 3), vhacdParams ); } @@ -841,7 +841,7 @@ namespace PhysX // by the amount of vertices already added in the last iteration for (const NodeCollisionGeomExportData& exportData : totalExportData) { - vtx_idx startingIndex = mergedVertices.size(); + vtx_idx startingIndex = static_cast(mergedVertices.size()); mergedVertices.insert(mergedVertices.end(), exportData.m_vertices.begin(), exportData.m_vertices.end()); diff --git a/Gems/PhysX/Code/Source/Pipeline/PrimitiveShapeFitter/PrimitiveShapeFitter.cpp b/Gems/PhysX/Code/Source/Pipeline/PrimitiveShapeFitter/PrimitiveShapeFitter.cpp index 1c73a48a09..1482e9438a 100644 --- a/Gems/PhysX/Code/Source/Pipeline/PrimitiveShapeFitter/PrimitiveShapeFitter.cpp +++ b/Gems/PhysX/Code/Source/Pipeline/PrimitiveShapeFitter/PrimitiveShapeFitter.cpp @@ -279,7 +279,7 @@ namespace PhysX::Pipeline { if (volumeTermWeight >= 0.0 && volumeTermWeight < 1.0) { - const AZ::u32 numberOfVertices = vertices.size(); + const AZ::u32 numberOfVertices = static_cast(vertices.size()); // Convert vertices and compute the mean of the vertex cloud. AZStd::vector verticesConverted(numberOfVertices, Vector{{ 0.0, 0.0, 0.0 }}); diff --git a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp index b57f8c0fef..a47f0ba16f 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp +++ b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp @@ -680,7 +680,7 @@ namespace PhysX if (m_freeSceneSlots.empty()) { m_simulatedBodies.emplace_back(newBodyCrc, newBody); - index = m_simulatedBodies.size() - 1; + index = static_cast(m_simulatedBodies.size() - 1); } else { @@ -867,7 +867,7 @@ namespace PhysX if (newJoint != nullptr) { - AzPhysics::JointIndex index = index = m_joints.size(); + AzPhysics::JointIndex index = static_cast(m_joints.size()); m_joints.emplace_back(newJointCrc, newJoint); const AzPhysics::JointHandle newJointHandle(newJointCrc, index); diff --git a/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationFilterCallback.cpp b/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationFilterCallback.cpp index d902fb91ca..e103913cdf 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationFilterCallback.cpp +++ b/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationFilterCallback.cpp @@ -55,7 +55,9 @@ namespace PhysX size_t SceneSimulationFilterCallback::CollisionPairHasher::operator()(const CollisionActorPair& collisionPair) const { size_t hash{ 0 }; - AZStd::hash_combine(hash, collisionPair.m_actorA, collisionPair.m_actorB); + // Order elements so {1,2} and {2,1} would generate the same hash + auto [smallerVal, biggerVal] = AZStd::minmax(collisionPair.m_actorA, collisionPair.m_actorB); + AZStd::hash_combine(hash, smallerVal, biggerVal); return hash; } diff --git a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp index 353085d1c1..cc55255e24 100644 --- a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp +++ b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp @@ -219,7 +219,7 @@ namespace PhysX if (m_sceneList.size() < std::numeric_limits::max()) //add a new scene if it is under the limit { - const AzPhysics::SceneHandle sceneHandle(AZ::Crc32(config.m_sceneName), (m_sceneList.size())); + const AzPhysics::SceneHandle sceneHandle(AZ::Crc32(config.m_sceneName), static_cast(m_sceneList.size())); m_sceneList.emplace_back(AZStd::make_unique(config, sceneHandle)); m_sceneAddedEvent.Signal(sceneHandle); return sceneHandle; diff --git a/Gems/PhysXDebug/Code/Source/SystemComponent.cpp b/Gems/PhysXDebug/Code/Source/SystemComponent.cpp index f46c8e229a..0495fc521b 100644 --- a/Gems/PhysXDebug/Code/Source/SystemComponent.cpp +++ b/Gems/PhysXDebug/Code/Source/SystemComponent.cpp @@ -561,7 +561,7 @@ namespace PhysXDebug static void physx_CullingBoxSize([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) { - const int argumentCount = arguments.size(); + const size_t argumentCount = arguments.size(); if (argumentCount == 1) { float newCullingBoxSize = (float)strtol(AZ::CVarFixedString(arguments[0]).c_str(), nullptr, 10); @@ -577,7 +577,7 @@ namespace PhysXDebug static void physx_Debug([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) { - const int argumentCount = arguments.size(); + const size_t argumentCount = arguments.size(); if (argumentCount == 1) { diff --git a/Gems/QtForPython/Editor/Scripts/show_object_tree.py b/Gems/QtForPython/Editor/Scripts/show_object_tree.py index d68a288a3e..48fb5e585b 100755 --- a/Gems/QtForPython/Editor/Scripts/show_object_tree.py +++ b/Gems/QtForPython/Editor/Scripts/show_object_tree.py @@ -220,6 +220,8 @@ class ObjectTreeDialog(QDialog): return for child in obj.children(): object_type = type(child).__name__ + if child.metaObject().className() != object_type: + object_type = f"{child.metaObject().className()} ({object_type})" object_name = child.objectName() text = icon_text = title = window_title = geometry_str = classes = "(N/A)" if isinstance(child, QtGui.QWindow): diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp index 6bc47476f8..7541e2fce7 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp @@ -651,7 +651,7 @@ namespace AZ::SceneGenerationComponents const auto& faceInfo = optimizedMesh->GetFaceInfo(optimizedMesh->GetFaceCount() - 1); AZStd::copy(AZStd::begin(faceInfo.vertexIndex), AZStd::end(faceInfo.vertexIndex), AZStd::inserter(usedIndexes, usedIndexes.begin())); } - indexOffset += usedIndexes.size(); + indexOffset += static_cast(usedIndexes.size()); } AZStd::unique_ptr optimizedSkinWeights; diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerators/BlendShapeMikkTGenerator.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerators/BlendShapeMikkTGenerator.cpp index b472aa4e09..c4b0888f13 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerators/BlendShapeMikkTGenerator.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/TangentGenerator/TangentGenerators/BlendShapeMikkTGenerator.cpp @@ -55,7 +55,7 @@ namespace AZ::TangentGeneration::BlendShape::MikkT { MikktCustomData* customData = static_cast(context->m_pUserData); const AZ::u32 vertexIndex = customData->m_blendShapeData->GetFaceVertexIndex(face, vert); - const AZ::Vector2& uv = customData->m_blendShapeData->GetUV(vertexIndex, customData->m_uvSetIndex); + const AZ::Vector2& uv = customData->m_blendShapeData->GetUV(vertexIndex, static_cast(customData->m_uvSetIndex)); texOut[0] = uv.GetX(); texOut[1] = uv.GetY(); } @@ -105,7 +105,7 @@ namespace AZ::TangentGeneration::BlendShape::MikkT AZ::SceneAPI::DataTypes::MikkTSpaceMethod tSpaceMethod) { // Create tangent and bitangent data sets and relate them to the given UV set. - const AZStd::vector& uvSet = blendShapeData->GetUVs(uvSetIndex); + const AZStd::vector& uvSet = blendShapeData->GetUVs(static_cast(uvSetIndex)); if (uvSet.empty()) { AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index 2a9814e281..87bf4cf23c 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -1384,7 +1384,7 @@ namespace ScriptCanvasEditor AZStd::string assetPath = scriptCanvasAsset.GetAbsolutePath(); if (!assetPath.empty() && !m_loadingNewlySavedFile) { - int eraseCount = m_loadingWorkspaceAssets.erase(fileAssetId); + const size_t eraseCount = m_loadingWorkspaceAssets.erase(fileAssetId); if (eraseCount == 0) { @@ -2529,7 +2529,7 @@ namespace ScriptCanvasEditor AZ::Data::AssetId fileAssetId = memoryAsset.GetFileAssetId(); AZ::Data::AssetId memoryAssetId = memoryAsset.GetId(); - int eraseCount = m_loadingAssets.erase(fileAssetId); + size_t eraseCount = m_loadingAssets.erase(fileAssetId); if (eraseCount > 0) { diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp index 1f6a93b9a2..b9aff660f2 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp @@ -651,9 +651,9 @@ namespace ScriptCanvasEditor return; } - m_ui->tableWidget->insertRow(m_inspectedAssets); + m_ui->tableWidget->insertRow(static_cast(m_inspectedAssets)); QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); - m_ui->tableWidget->setItem(m_inspectedAssets, ColumnAsset, rowName); + m_ui->tableWidget->setItem(static_cast(m_inspectedAssets), static_cast(ColumnAsset), rowName); if (!graphComponent->GetVersion().IsLatest()) { @@ -675,9 +675,9 @@ namespace ScriptCanvasEditor AZ::SystemTickBus::ExecuteQueuedEvents(); }); - m_ui->tableWidget->setCellWidget(m_inspectedAssets, ColumnAction, rowGoToButton); + m_ui->tableWidget->setCellWidget(static_cast(m_inspectedAssets), static_cast(ColumnAction), rowGoToButton); - m_ui->tableWidget->setCellWidget(m_inspectedAssets, ColumnStatus, spinner); + m_ui->tableWidget->setCellWidget(static_cast(m_inspectedAssets), static_cast(ColumnStatus), spinner); } QToolButton* browseButton = new QToolButton(this); @@ -705,7 +705,7 @@ namespace ScriptCanvasEditor connect(browseButton, &QPushButton::clicked, [absolutePath] { AzQtComponents::ShowFileOnDesktop(absolutePath); }); - m_ui->tableWidget->setCellWidget(m_inspectedAssets, ColumnBrowse, browseButton); + m_ui->tableWidget->setCellWidget(static_cast(m_inspectedAssets), static_cast(ColumnBrowse), browseButton); ++m_inspectedAssets; ++m_currentAssetIndex; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp index 83d8b6f52b..e01a3a0e7a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp @@ -699,7 +699,7 @@ namespace ScriptCanvas ActivationData data(args.runtimeOverrides, storage); ActivationInputRange range = Execution::Context::CreateActivateInputRange(data, args.executionState->GetEntityId()); PushActivationArgs(lua, range.inputs, range.totalCount); - return range.totalCount; + return static_cast(range.totalCount); } int UnpackDependencyConstructionArgs(lua_State* lua) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h index c4fee491a3..670c9f31a1 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector2Nodes.h @@ -243,6 +243,22 @@ namespace ScriptCanvas } SCRIPT_CANVAS_GENERIC_FUNCTION_NODE(ToPerpendicular, k_categoryName, "{CC4DC102-8B50-4828-BA94-0586F34E0D37}", "returns the vector (-Source.y, Source.x), a 90 degree, positive rotation", "Source"); + AZ_INLINE void DirectionToDefaults(Node& node) + { + SetDefaultValuesByIndex<0>::_(node, Data::Vector2Type()); + SetDefaultValuesByIndex<1>::_(node, Data::Vector2Type()); + SetDefaultValuesByIndex<2>::_(node, Data::NumberType(1.)); + } + + AZ_INLINE std::tuple DirectionTo(const Vector2Type from, const Vector2Type to, NumberType optionalScale = 1.f) + { + Vector2Type r = to - from; + float length = r.NormalizeWithLength(); + r.SetLength(optionalScale); + return std::make_tuple(r, length); + } + SCRIPT_CANVAS_GENERIC_FUNCTION_NODE_WITH_DEFAULTS(DirectionTo, DirectionToDefaults, k_categoryName, "{49A2D7F6-6CD3-420E-8A79-D46B00DB6CED}", "Returns a direction vector between two points and the distance between them, by default the direction will be normalized, but it may be optionally scaled using the Scale parameter if different from 1.0", "From", "To", "Scale"); + using Registrar = RegistrarGeneric < AbsoluteNode , AddNode @@ -295,6 +311,7 @@ namespace ScriptCanvas , SlerpNode , SubtractNode , ToPerpendicularNode + , DirectionToNode > ; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h index 5962cee487..492bc83e33 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector3Nodes.h @@ -329,6 +329,23 @@ namespace ScriptCanvas } SCRIPT_CANVAS_GENERIC_FUNCTION_NODE(ZAxisCross, k_categoryName, "{29206E84-392C-412E-9DD5-781B2759260D}", "returns the vector cross product of Z-Axis X Source", "Source"); + AZ_INLINE void DirectionToDefaults(Node& node) + { + SetDefaultValuesByIndex<0>::_(node, Data::Vector3Type()); + SetDefaultValuesByIndex<1>::_(node, Data::Vector3Type()); + SetDefaultValuesByIndex<2>::_(node, Data::NumberType(1.)); + } + + AZ_INLINE std::tuple DirectionTo(const Vector3Type from, const Vector3Type to, NumberType optionalScale = 1.f) + { + Vector3Type r = to - from; + float length = r.NormalizeWithLength(); + r.SetLength(optionalScale); + return std::make_tuple(r, length); + } + SCRIPT_CANVAS_GENERIC_FUNCTION_NODE_WITH_DEFAULTS(DirectionTo, DirectionToDefaults, k_categoryName, "{28FBD529-4C9A-4E34-B8A0-A13B5DB3C331}", "Returns a direction vector between two points and the distance between them, by default the direction will be normalized, but it may be optionally scaled using the Scale parameter if different from 1.0", "From", "To", "Scale"); + + using Registrar = RegistrarGeneric < AbsoluteNode , AddNode @@ -403,6 +420,7 @@ namespace ScriptCanvas , SlerpNode , SubtractNode + , DirectionToNode #if ENABLE_EXTENDED_MATH_SUPPORT , XAxisCrossNode diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h index 4522ba07dc..14256fc969 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Math/Vector4Nodes.h @@ -214,6 +214,22 @@ namespace ScriptCanvas } SCRIPT_CANVAS_GENERIC_FUNCTION_NODE_DEPRECATED(Subtract, k_categoryName, "{A5FA6465-9C39-4A44-BD7C-E8ECF9503E46}", "This node is deprecated, use Subtract (-), it provides contextual type and slots", "A", "B"); + AZ_INLINE void DirectionToDefaults(Node& node) + { + SetDefaultValuesByIndex<0>::_(node, Data::Vector4Type()); + SetDefaultValuesByIndex<1>::_(node, Data::Vector4Type()); + SetDefaultValuesByIndex<2>::_(node, Data::NumberType(1.)); + } + + AZ_INLINE std::tuple DirectionTo(const Vector4Type from, const Vector4Type to, NumberType optionalScale = 1.f) + { + Vector4Type r = to - from; + float length = r.NormalizeWithLength(); + r.SetLength(optionalScale); + return std::make_tuple(r, length); + } + SCRIPT_CANVAS_GENERIC_FUNCTION_NODE_WITH_DEFAULTS(DirectionTo, DirectionToDefaults, k_categoryName, "{463762DE-E541-4AFE-80C2-FED1C5273319}", "Returns a direction vector between two points and the distance between them, by default the direction will be normalized, but it may be optionally scaled using the Scale parameter if different from 1.0", "From", "To", "Scale"); + using Registrar = RegistrarGeneric < AbsoluteNode, AddNode, @@ -260,7 +276,8 @@ namespace ScriptCanvas #endif ReciprocalNode, - SubtractNode + SubtractNode, + DirectionToNode > ; } diff --git a/Gems/SliceFavorites/Code/Source/FavoriteDataModel.cpp b/Gems/SliceFavorites/Code/Source/FavoriteDataModel.cpp index a686b54b9d..94b9d78247 100644 --- a/Gems/SliceFavorites/Code/Source/FavoriteDataModel.cpp +++ b/Gems/SliceFavorites/Code/Source/FavoriteDataModel.cpp @@ -473,14 +473,14 @@ namespace SliceFavorites for (size_t index = 0; index < currentList.size(); index++) { - FavoriteData* current = currentList[index]; + FavoriteData* current = currentList[static_cast(index)]; if (!current) { continue; } - settings.setArrayIndex(index); + settings.setArrayIndex(static_cast(index)); settings.setValue("name", current->m_name); AZStd::string assetIdString; diff --git a/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h b/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h index 1ebeec5880..2f45d22748 100644 --- a/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h +++ b/Gems/SurfaceData/Code/Include/SurfaceData/Tests/SurfaceDataTestMocks.h @@ -265,7 +265,7 @@ namespace UnitTest { // Keep a list of registered entries. Use the "list index + 1" as the handle. (We add +1 because 0 is used to mean "invalid handle") entryList.emplace_back(entry); - return entryList.size(); + return static_cast(entryList.size()); } void UnregisterEntry(const SurfaceData::SurfaceDataRegistryHandle& handle, AZStd::vector& entryList) diff --git a/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp b/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp index 93995faaf6..7ce1a2c0a3 100644 --- a/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp @@ -1010,7 +1010,7 @@ namespace Vegetation if (m_debugData) { - m_debugData->m_areaTaskQueueCount.store(m_vegetationThreadTasks.size(), AZStd::memory_order_relaxed); + m_debugData->m_areaTaskQueueCount.store(static_cast(m_vegetationThreadTasks.size()), AZStd::memory_order_relaxed); } } @@ -1025,8 +1025,8 @@ namespace Vegetation if (m_debugData) { - m_debugData->m_areaTaskQueueCount.store(m_vegetationThreadTasks.size(), AZStd::memory_order_relaxed); - m_debugData->m_areaTaskActiveCount.store(tasks.size(), AZStd::memory_order_relaxed); + m_debugData->m_areaTaskQueueCount.store(static_cast(m_vegetationThreadTasks.size()), AZStd::memory_order_relaxed); + m_debugData->m_areaTaskActiveCount.store(static_cast(tasks.size()), AZStd::memory_order_relaxed); } } diff --git a/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp b/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp index 88581aaea0..b373edf051 100644 --- a/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp @@ -528,7 +528,7 @@ namespace Vegetation AZ::u32 SpawnerComponent::GetProductCount() const { AZStd::lock_guard claimInstanceMappingMutexLock(m_claimInstanceMappingMutex); - return m_claimInstanceMapping.size(); + return static_cast(m_claimInstanceMapping.size()); } void SpawnerComponent::OnCompositionChanged() diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp index bfe74a8b28..b415a7c41c 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp @@ -599,8 +599,8 @@ namespace DebugUtility timing.m_lowestTimeUs = AZ::GetMin(timeSpan, timing.m_lowestTimeUs); timing.m_peakTimeUs = AZ::GetMax(timeSpan, timing.m_peakTimeUs); timing.m_totalUpdateTimeUs += timeSpan; - timing.m_numInstancesCreated += datum.m_numInstancesCreated; - timing.m_numClaimPointsRemaining += datum.m_numClaimPointsRemaining; + timing.m_numInstancesCreated += static_cast(datum.m_numInstancesCreated); + timing.m_numClaimPointsRemaining += static_cast(datum.m_numClaimPointsRemaining); ++timing.m_totalCount; timing.m_averageTimeUs = timing.m_totalUpdateTimeUs / timing.m_totalCount; @@ -615,8 +615,8 @@ namespace DebugUtility timing.m_peakTimeUs = timeSpan; timing.m_averageTimeUs = timeSpan; timing.m_totalUpdateTimeUs = timeSpan; - timing.m_numInstancesCreated = datum.m_numInstancesCreated; - timing.m_numClaimPointsRemaining = datum.m_numClaimPointsRemaining; + timing.m_numInstancesCreated = static_cast(datum.m_numInstancesCreated); + timing.m_numClaimPointsRemaining = static_cast(datum.m_numClaimPointsRemaining); timing.m_totalCount = 1; mergeData(datum, timing); @@ -876,7 +876,7 @@ void DebugComponent::PrepareNextReport() { AreaSectorTiming& areaSectorTiming = iterator->second; areaSectorTiming.m_totalTime += AZStd::chrono::microseconds(sectorAreaData.m_end - sectorAreaData.m_start).count(); - areaSectorTiming.m_numInstances += sectorAreaData.m_numInstancesCreated; + areaSectorTiming.m_numInstances += static_cast(sectorAreaData.m_numInstancesCreated); for( const auto& reasonValue : sectorAreaData.m_numInstancesRejectedByFilters ) { DebugComponentUtilities::IncrementFilterReason(areaSectorTiming.m_numInstancesRejectedByFilters, reasonValue.first, reasonValue.second); @@ -887,7 +887,7 @@ void DebugComponent::PrepareNextReport() { AreaSectorTiming newAreaSectorTiming; newAreaSectorTiming.m_totalTime = AZStd::chrono::microseconds(sectorAreaData.m_end - sectorAreaData.m_start).count(); - newAreaSectorTiming.m_numInstances = sectorAreaData.m_numInstancesCreated; + newAreaSectorTiming.m_numInstances = static_cast(sectorAreaData.m_numInstancesCreated); newAreaSectorTiming.m_numInstancesRejectedByFilters = sectorAreaData.m_numInstancesRejectedByFilters; newAreaSectorTiming.m_filteredByMasks = sectorAreaData.m_filteredByMasks; sectorTiming.m_perAreaData[areaId] = newAreaSectorTiming; @@ -913,7 +913,7 @@ void DebugComponent::PrepareNextReport() AreaSectorTiming& areaSectorTiming = iterator->second; areaSectorTiming.m_totalTime += AZStd::chrono::microseconds(areaTracker.m_end - areaTracker.m_start).count(); - areaSectorTiming.m_numInstances += areaTracker.m_numInstancesCreated; + areaSectorTiming.m_numInstances += static_cast(areaTracker.m_numInstancesCreated); for (const auto& filterReasonEntry : areaTracker.m_numInstancesRejectedByFilters) { DebugComponentUtilities::IncrementFilterReason(areaSectorTiming.m_numInstancesRejectedByFilters, filterReasonEntry.first, filterReasonEntry.second); @@ -925,7 +925,7 @@ void DebugComponent::PrepareNextReport() { AreaSectorTiming newAreaSectorTiming; newAreaSectorTiming.m_totalTime = AZStd::chrono::microseconds(areaTracker.m_end - areaTracker.m_start).count(); - newAreaSectorTiming.m_numInstances = areaTracker.m_numInstancesCreated; + newAreaSectorTiming.m_numInstances = static_cast(areaTracker.m_numInstancesCreated); newAreaSectorTiming.m_numInstancesRejectedByFilters = areaTracker.m_numInstancesRejectedByFilters; newAreaSectorTiming.m_filteredByMasks = areaTracker.m_filteredByMasks; areaTiming.m_perSectorData[areaTracker.m_sectorId] = newAreaSectorTiming; diff --git a/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp b/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp index 0e2fc582e9..74fb2696ea 100644 --- a/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp @@ -483,7 +483,7 @@ namespace Vegetation AZStd::lock_guard scopedLock(m_instanceMapMutex); AZ_Assert(m_instanceMap.find(instanceData.m_instanceId) == m_instanceMap.end(), "InstanceId %llu is already in use!", instanceData.m_instanceId); m_instanceMap[instanceData.m_instanceId] = AZStd::make_pair(instanceData.m_descriptorPtr, opaqueInstanceData); - m_instanceCount = m_instanceMap.size(); + m_instanceCount = static_cast(m_instanceMap.size()); } } @@ -503,7 +503,7 @@ namespace Vegetation opaqueInstanceData = instanceItr->second.second; m_instanceMap.erase(instanceItr); } - m_instanceCount = m_instanceMap.size(); + m_instanceCount = static_cast(m_instanceMap.size()); } if (opaqueInstanceData) diff --git a/Gems/WhiteBox/Code/Source/Core/WhiteBoxToolApi.cpp b/Gems/WhiteBox/Code/Source/Core/WhiteBoxToolApi.cpp index bc4bc42abd..3bcd2dbd94 100644 --- a/Gems/WhiteBox/Code/Source/Core/WhiteBoxToolApi.cpp +++ b/Gems/WhiteBox/Code/Source/Core/WhiteBoxToolApi.cpp @@ -1400,7 +1400,7 @@ namespace WhiteBox HalfedgeHandle EdgeHalfedgeHandle( const WhiteBoxMesh& whiteBox, const EdgeHandle edgeHandle, const EdgeHalfedge edgeHalfedge) { - return wb_heh(whiteBox.mesh.halfedge_handle(om_eh(edgeHandle), EdgeHalfedgeMapping(edgeHalfedge))); + return wb_heh(whiteBox.mesh.halfedge_handle(om_eh(edgeHandle), static_cast(EdgeHalfedgeMapping(edgeHalfedge)))); } HalfedgeHandles EdgeHalfedgeHandles(const WhiteBoxMesh& whiteBox, EdgeHandle edgeHandle) diff --git a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxBuffer.h b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxBuffer.h index e3602da7ed..a96ccd98be 100644 --- a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxBuffer.h +++ b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxBuffer.h @@ -85,7 +85,7 @@ namespace WhiteBox template Buffer::Buffer(const AZStd::vector& data) { - const uint32_t elementCount = data.size(); + const uint32_t elementCount = static_cast(data.size()); const uint32_t elementSize = sizeof(VertexStreamDataType); const uint32_t bufferSize = elementCount * elementSize; @@ -166,7 +166,7 @@ namespace WhiteBox return false; } - const uint32_t elementCount = data.size(); + const uint32_t elementCount = static_cast(data.size()); const uint32_t elementSize = sizeof(VertexStreamDataType); const uint32_t bufferSize = elementCount * elementSize; diff --git a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxMeshAtomData.cpp b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxMeshAtomData.cpp index 63f16d32fc..e15ee37632 100644 --- a/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxMeshAtomData.cpp +++ b/Gems/WhiteBox/Code/Source/Rendering/Atom/WhiteBoxMeshAtomData.cpp @@ -58,9 +58,9 @@ namespace WhiteBox for (size_t i = 0; i < vertCount; i++) { - const auto normal = tangentSpaceCalculation.GetNormal(i); - const auto tangent = tangentSpaceCalculation.GetTangent(i); - const auto bitangent = tangentSpaceCalculation.GetBitangent(i); + const auto normal = tangentSpaceCalculation.GetNormal(static_cast(i)); + const auto tangent = tangentSpaceCalculation.GetTangent(static_cast(i)); + const auto bitangent = tangentSpaceCalculation.GetBitangent(static_cast(i)); m_aabb.AddPoint(positions[i]); @@ -75,7 +75,7 @@ namespace WhiteBox const uint32_t WhiteBoxMeshAtomData::VertexCount() const { - return m_indices.size(); + return static_cast(m_indices.size()); } const AZStd::vector& WhiteBoxMeshAtomData::GetIndices() const diff --git a/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxEdgeScaleModifier.cpp b/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxEdgeScaleModifier.cpp index ac8d929599..0024a1cb6f 100644 --- a/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxEdgeScaleModifier.cpp +++ b/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxEdgeScaleModifier.cpp @@ -106,7 +106,7 @@ namespace WhiteBox WhiteBoxMesh* whiteBox = nullptr; EditorWhiteBoxComponentRequestBus::EventResult( whiteBox, m_entityComponentIdPair, &EditorWhiteBoxComponentRequests::GetWhiteBoxMesh); - m_selectedHandleIndex = vertexIndex; + m_selectedHandleIndex = static_cast(vertexIndex); InitializeScaleModifier(whiteBox, action); }); diff --git a/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxVertexTranslationModifier.cpp b/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxVertexTranslationModifier.cpp index 15917a768f..daa81c9aa3 100644 --- a/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxVertexTranslationModifier.cpp +++ b/Gems/WhiteBox/Code/Source/Viewport/WhiteBoxVertexTranslationModifier.cpp @@ -89,7 +89,7 @@ namespace WhiteBox const auto screenLength = std::fabs(currentAction.ScreenOffset().Dot(screenAxis)); if (screenLength > maxLength) { - axisIndex = actionIndex; + axisIndex = static_cast(actionIndex); maxLength = screenLength; } } diff --git a/README.md b/README.md index c129fffb6c..a783139eef 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Open 3D Engine +# O3DE (Open 3D Engine) -Open 3D Engine (O3DE) is an open-source, real-time, multi-platform 3D engine that enables developers and content creators to build AAA games, cinema-quality 3D worlds, and high-fidelity simulations without any fees or commercial obligations. +O3DE (Open 3D Engine) is an open-source, real-time, multi-platform 3D engine that enables developers and content creators to build AAA games, cinema-quality 3D worlds, and high-fidelity simulations without any fees or commercial obligations. ## Contribute For information about contributing to Open 3D Engine, visit https://o3de.org/docs/contributing/ diff --git a/Tools/LyTestTools/ly_test_tools/benchmark/data_aggregator.py b/Tools/LyTestTools/ly_test_tools/benchmark/data_aggregator.py index 8a62c2e150..b5b75508ec 100644 --- a/Tools/LyTestTools/ly_test_tools/benchmark/data_aggregator.py +++ b/Tools/LyTestTools/ly_test_tools/benchmark/data_aggregator.py @@ -10,6 +10,7 @@ import json from pathlib import Path import time import subprocess +import os from ly_test_tools.mars.filebeat_client import FilebeatClient @@ -21,7 +22,7 @@ class BenchmarkDataAggregator(object): def __init__(self, workspace, logger, test_suite): self.build_dir = workspace.paths.build_directory() self.results_dir = Path(workspace.paths.project(), 'user/Scripts/PerformanceBenchmarks') - self.test_suite = test_suite + self.test_suite = test_suite if os.environ.get('CI') else 'local' self.filebeat_client = FilebeatClient(logger) def _update_pass(self, pass_stats, entry): diff --git a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py index 50021080fe..57454930eb 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py @@ -594,7 +594,7 @@ class AssetProcessor(object): output_list = None if capture_output: if decode: - output_list = run_result.stdout.decode('utf-8').splitlines() + output_list = run_result.stdout.decode('utf-8', errors="replace").splitlines() else: output_list = run_result.stdout.splitlines() diff --git a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake index 41de1bd6a0..4024e45bad 100644 --- a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake +++ b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake @@ -41,7 +41,6 @@ ly_append_configurations_options( /wd4018 # signed/unsigned mismatch /wd4244 # conversion, possible loss of data /wd4245 # conversion, signed/unsigned mismatch - /wd4267 # conversion, possible loss of data /wd4389 # comparison, signed/unsigned mismatch # Enabling warnings that are disabled by default from /W4 diff --git a/cmake/Platform/Windows/Packaging/Bootstrapper.wxs b/cmake/Platform/Windows/Packaging/Bootstrapper.wxs index 6971e32ca2..079c20e212 100644 --- a/cmake/Platform/Windows/Packaging/Bootstrapper.wxs +++ b/cmake/Platform/Windows/Packaging/Bootstrapper.wxs @@ -33,6 +33,7 @@ LogoFile="$(var.CPACK_WIX_PRODUCT_LOGO)" ThemeFile="$(var.CPACK_BOOTSTRAP_THEME_FILE).xml" LocalizationFile="$(var.CPACK_BOOTSTRAP_THEME_FILE).wxl" + ShowFilesInUse="yes" ShowVersion="yes" /> @@ -44,6 +45,7 @@ LogoFile="$(var.CPACK_WIX_PRODUCT_LOGO)" ThemeFile="$(var.CPACK_BOOTSTRAP_THEME_FILE).xml" LocalizationFile="$(var.CPACK_BOOTSTRAP_THEME_FILE).wxl" + ShowFilesInUse="yes" ShowVersion="yes" /> diff --git a/cmake/Platform/Windows/Packaging/BootstrapperTheme.wxl.in b/cmake/Platform/Windows/Packaging/BootstrapperTheme.wxl.in index 6c5d16fd49..7d221913d5 100644 --- a/cmake/Platform/Windows/Packaging/BootstrapperTheme.wxl.in +++ b/cmake/Platform/Windows/Packaging/BootstrapperTheme.wxl.in @@ -39,6 +39,14 @@ Setup will install [WixBundleName] on your computer. Click install to continue, Execution Progress &Cancel + + Files In Use + The following applications are using files that need to be modified: + Close the &applications + &Do not close applications, may cause unexpected side effects + &OK + &Cancel + Setup Successful Installation Successfully Completed diff --git a/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in b/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in index 8d8416539e..b340d23467 100644 --- a/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in +++ b/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in @@ -70,6 +70,21 @@ + + + #(loc.FilesInUseHeader) + + #(loc.FilesInUseLabel) + + + + + + + + + + #(loc.SuccessHeader) diff --git a/cmake/Platform/Windows/Packaging_windows.cmake b/cmake/Platform/Windows/Packaging_windows.cmake index 7c62a4984c..5bb9928b61 100644 --- a/cmake/Platform/Windows/Packaging_windows.cmake +++ b/cmake/Platform/Windows/Packaging_windows.cmake @@ -17,6 +17,10 @@ else() return() endif() +# IMPORTANT: CPACK_WIX_ROOT is a built-in variable that is required to propagate the path supplied +# via command line down to the cpack internals +set(CPACK_WIX_ROOT ${LY_INSTALLER_WIX_ROOT}) + set(CPACK_GENERATOR WIX) set(_cmake_package_name "cmake-${CPACK_DESIRED_CMAKE_VERSION}-windows-x86_64") diff --git a/scripts/o3de/o3de/enable_gem.py b/scripts/o3de/o3de/enable_gem.py index 67e1624086..1614dc4eda 100644 --- a/scripts/o3de/o3de/enable_gem.py +++ b/scripts/o3de/o3de/enable_gem.py @@ -16,7 +16,7 @@ import os import pathlib import sys -from o3de import cmake, manifest, validation +from o3de import cmake, manifest, register, validation logger = logging.getLogger() logging.basicConfig() @@ -87,8 +87,7 @@ def enable_gem_in_project(gem_name: str = None, if not enabled_gem_file.is_file(): logger.error(f'Enabled gem file {enabled_gem_file} is not present.') return 1 - # add the gem - ret_val = cmake.add_gem_dependency(enabled_gem_file, gem_json_data['gem_name']) + project_enabled_gem_file = enabled_gem_file else: # Find the path to enabled gem file. @@ -96,8 +95,21 @@ def enable_gem_in_project(gem_name: str = None, project_enabled_gem_file = cmake.get_enabled_gem_cmake_file(project_path=project_path) if not project_enabled_gem_file.is_file(): project_enabled_gem_file.touch() - # add the gem - ret_val = cmake.add_gem_dependency(project_enabled_gem_file, gem_json_data['gem_name']) + + # Before adding the gem_dependency check if the project is registered in either the project or engine + # manifest + buildable_gems = manifest.get_engine_gems() + buildable_gems.extend(manifest.get_project_gems(project_path)) + # Convert each path to pathlib.Path object and filter out duplictes using dict.fromkeys + buildable_gems = list(dict.fromkeys(map(lambda gem_path_string: pathlib.Path(gem_path_string), buildable_gems))) + + ret_val = 0 + # If the gem is not part of buildable set, it needs to be registered + if not gem_path in buildable_gems: + ret_val = register.register(gem_path=gem_path, external_subdir_project_path=project_path) + + # add the gem if it is registered in either the project.json or engine.json + ret_val = ret_val or cmake.add_gem_dependency(project_enabled_gem_file, gem_json_data['gem_name']) return ret_val diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index 8481c5fae0..7e182b5d2d 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -285,14 +285,14 @@ def register_o3de_object_path(json_data: dict, manifest_data = None if engine_path: - manifest_data = manifest.get_engine_json_data(json_data, engine_path) + manifest_data = manifest.get_engine_json_data(None, engine_path) if not manifest_data: logger.error(f'Cannot load engine.json data at path {engine_path}') return 1 save_path = engine_path / 'engine.json' elif project_path: - manifest_data = manifest.get_project_json_data(json_data, project_path) + manifest_data = manifest.get_project_json_data(None, project_path) if not manifest_data: logger.error(f'Cannot load project.json data at path {project_path}') return 1 @@ -329,7 +329,7 @@ def register_o3de_object_path(json_data: dict, try: o3de_object_path = o3de_object_path.relative_to(save_path.parent) except ValueError: - pass # It is OK relative path cannot be formed + pass # It is OK relative path cannot be formed manifest_data[o3de_object_key].insert(0, o3de_object_path.as_posix()) if save_path: manifest.save_o3de_manifest(manifest_data, save_path) diff --git a/scripts/o3de/tests/CMakeLists.txt b/scripts/o3de/tests/CMakeLists.txt index 1cd6eac7ee..de8e9e4974 100644 --- a/scripts/o3de/tests/CMakeLists.txt +++ b/scripts/o3de/tests/CMakeLists.txt @@ -25,6 +25,13 @@ ly_add_pytest( EXCLUDE_TEST_RUN_TARGET_FROM_IDE ) +ly_add_pytest( + NAME o3de_enable_gem + PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_enable_gem.py + TEST_SUITE smoke + EXCLUDE_TEST_RUN_TARGET_FROM_IDE +) + ly_add_pytest( NAME o3de_global_project PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_global_project.py diff --git a/scripts/o3de/tests/unit_test_enable_gem.py b/scripts/o3de/tests/unit_test_enable_gem.py new file mode 100644 index 0000000000..9165fd5d08 --- /dev/null +++ b/scripts/o3de/tests/unit_test_enable_gem.py @@ -0,0 +1,160 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +import io +import json +import logging + +import pytest +import pathlib +from unittest.mock import patch + +from o3de import enable_gem + + +TEST_PROJECT_JSON_PAYLOAD = ''' +{ + "project_name": "TestProject", + "origin": "The primary repo for TestProject goes here: i.e. http://www.mydomain.com", + "license": "What license TestProject uses goes here: i.e. https://opensource.org/licenses/MIT", + "display_name": "TestProject", + "summary": "A short description of TestProject.", + "canonical_tags": [ + "Project" + ], + "user_tags": [ + "TestProject" + ], + "icon_path": "preview.png", + "engine": "o3de-install", + "restricted_name": "projects", + "external_subdirectories": [ + ] +} +''' + +TEST_GEM_JSON_PAYLOAD = ''' +{ + "gem_name": "TestGem", + "display_name": "TestGem", + "license": "What license TestGem uses goes here: i.e. https://opensource.org/licenses/MIT", + "origin": "The primary repo for TestGem goes here: i.e. http://www.mydomain.com", + "type": "Code", + "summary": "A short description of TestGem.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "TestGem" + ], + "icon_path": "preview.png", + "requirements": "" +} +''' + +TEST_O3DE_MANIFEST_JSON_PAYLOAD = ''' +{ + "o3de_manifest_name": "testuser", + "origin": "C:/Users/testuser/.o3de", + "default_engines_folder": "C:/Users/testuser/.o3de/Engines", + "default_projects_folder": "C:/Users/testuser/.o3de/Projects", + "default_gems_folder": "C:/Users/testuser/.o3de/Gems", + "default_templates_folder": "C:/Users/testuser/.o3de/Templates", + "default_restricted_folder": "C:/Users/testuser/.o3de/Restricted", + "default_third_party_folder": "C:/Users/testuser/.o3de/3rdParty", + "projects": [ + "D:/MinimalProject" + ], + "external_subdirectories": [], + "templates": [], + "restricted": [], + "repos": [], + "engines": [ + "D:/o3de/o3de" + ], + "engines_path": { + "o3de": "D:/o3de/o3de" + } +} +''' + +@pytest.fixture(scope='class') +def init_enable_gem_data(request): + class EnableGemData: + def __init__(self): + self.project_data = json.loads(TEST_PROJECT_JSON_PAYLOAD) + self.gem_data = json.loads(TEST_GEM_JSON_PAYLOAD) + request.cls.enable_gem = EnableGemData() + + +@pytest.mark.usefixtures('init_enable_gem_data') +class TestEnableGemCommand: + @pytest.mark.parametrize("gem_path, project_path, gem_registered_with_project, gem_registered_with_engine," + "expected_result", [ + pytest.param(pathlib.PurePath('TestProject/TestGem'), pathlib.PurePath('TestProject'), False, True, 0), + pytest.param(pathlib.PurePath('TestProject/TestGem'), pathlib.PurePath('TestProject'), False, False, 0), + pytest.param(pathlib.PurePath('TestProject/TestGem'), pathlib.PurePath('TestProject'), True, False, 0), + ] + ) + def test_enable_gem_registers_gem_as_well(self, gem_path, project_path, gem_registered_with_project, gem_registered_with_engine, + expected_result): + + def get_registered_path(project_name: str = None, gem_name: str = None) -> pathlib.Path: + if project_name: + return project_path + elif gem_name: + return gem_path + return None + + def get_registered_gem_path(gem_name: str) -> pathlib.Path: + return gem_path + + def save_o3de_manifest(new_project_data: dict, manifest_path: pathlib.Path = None) -> bool: + if manifest_path == project_path: + self.enable_gem.project_data = new_project_data + return True + + def load_o3de_manifest(manifest_path: pathlib.Path = None) -> dict: + if not manifest_path: + return json.loads(TEST_O3DE_MANIFEST_JSON_PAYLOAD) + return None + + def get_project_json_data(json_data: pathlib.Path, project_path: pathlib.Path): + return self.enable_gem.project_data + + def get_gem_json_data(gem_path: pathlib.Path, project_path: pathlib.Path): + return self.enable_gem.gem_data + + def get_project_gems(project_path: pathlib.Path): + return [gem_path] if gem_registered_with_project else [] + + def get_engine_gems(): + return [gem_path] if gem_registered_with_engine else [] + + def add_gem_dependency(enable_gem_cmake_file: pathlib.Path, gem_name: str): + return 0 + + with patch('pathlib.Path.is_dir', return_value=True) as pathlib_is_dir_patch,\ + patch('pathlib.Path.is_file', return_value=True) as pathlib_is_file_patch, \ + patch('o3de.manifest.load_o3de_manifest', side_effect=load_o3de_manifest) as load_o3de_manifest_patch, \ + patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch,\ + patch('o3de.manifest.get_registered', side_effect=get_registered_path) as get_registered_patch,\ + patch('o3de.manifest.get_gem_json_data', side_effect=get_gem_json_data) as get_gem_json_data_patch,\ + patch('o3de.manifest.get_project_json_data', side_effect=get_project_json_data) as get_gem_json_data_patch,\ + patch('o3de.manifest.get_project_gems', side_effect=get_project_gems) as get_project_gems_patch,\ + patch('o3de.manifest.get_engine_gems', side_effect=get_engine_gems) as get_engine_gems_patch,\ + patch('o3de.cmake.add_gem_dependency', side_effect=add_gem_dependency) as add_gem_dependency_patch,\ + patch('o3de.validation.valid_o3de_gem_json', return_value=True) as valid_gem_json_patch: + result = enable_gem.enable_gem_in_project(gem_path=gem_path, project_path=project_path) + assert result == expected_result + # If the gem isn't registered with the engine or project already it should now be registered with the project + if not gem_registered_with_engine and gem_registered_with_project: + # Prepend the project path to each external subdirectory + project_relative_subdirs = map(lambda subdir: (pathlib.Path(project_path) / subdir).as_posix(), + self.enable_gem.project_data.get('external_subdirectories', [])) + assert gem_path.as_posix() in project_relative_subdirs diff --git a/scripts/o3de/tests/unit_test_project_properties.py b/scripts/o3de/tests/unit_test_project_properties.py index f72a4dfe4c..0236e6cf90 100644 --- a/scripts/o3de/tests/unit_test_project_properties.py +++ b/scripts/o3de/tests/unit_test_project_properties.py @@ -6,33 +6,41 @@ # # +import json import pytest import pathlib from unittest.mock import patch from o3de import project_properties -TEST_DEFAULT_PROJECT_DATA = { - "template_name": "DefaultProject", - "restricted_name": "o3de", - "restricted_platform_relative_path": "Templates", - "origin": "The primary repo for DefaultProject goes here: i.e. http://www.mydomain.com", - "license": "What license DefaultProject uses goes here: i.e. https://opensource.org/licenses/MIT", - "display_name": "Default", - "summary": "A short description of DefaultProject.", - "included_gems": ["Atom","Camera","EMotionFX","UI","Maestro","Input","ImGui"], - "canonical_tags": [], - "user_tags": [ - "DefaultProject" +TEST_PROJECT_JSON_PAYLOAD = ''' +{ + "project_name": "TestProject", + "origin": "The primary repo for TestProject goes here: i.e. http://www.mydomain.com", + "license": "What license TestProject uses goes here: i.e. https://opensource.org/licenses/MIT", + "display_name": "TestProject", + "summary": "A short description of TestProject.", + "canonical_tags": [ + "Project" ], - "icon_path": "preview.png" + "user_tags": [ + "TestProject" + ], + "icon_path": "preview.png", + "engine": "o3de-install", + "restricted_name": "projects", + "external_subdirectories": [ + "D:/TestGem" + ] } +''' + @pytest.fixture(scope='class') def init_project_json_data(request): class ProjectJsonData: def __init__(self): - self.data = TEST_DEFAULT_PROJECT_DATA + self.data = json.loads(TEST_PROJECT_JSON_PAYLOAD) request.cls.project_json = ProjectJsonData() @pytest.mark.usefixtures('init_project_json_data')