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 9f1921395c..1bc00fdc3f 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/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 4bfc6a319d..efeb7cdd19 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)
@@ -2579,75 +2576,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())
@@ -2901,7 +2829,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 af0fbb0971..9406b37ea2 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 43f599b191..9421198de7 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)
SetFileAttributes(filename.toUtf8().data(), 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 LPCTSTR levelFilePath)
+QString CCryEditDoc::GetCryIndexPath(const LPCTSTR 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 574f8eb7da..d32e8e5bb1 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 LPCTSTR levelFilePath);
+ QString GetCryIndexPath(const LPCTSTR 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/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 ff322b79ac..8309d99691 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/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 8f86c74b25..eef2ca0461 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);
@@ -745,6 +748,8 @@ void SEditorSettings::Load()
consoleBackgroundColorTheme = AzToolsFramework::ConsoleColorTheme::Dark;
}
+ LoadValue("Settings", "ClearConsoleOnGameModeStart", clearConsoleOnGameModeStart);
+
LoadValue("Settings", "ShowTimeInConsole", bShowTimeInConsole);
LoadValue("Settings", "EnableSceneInspector", enableSceneInspector);
@@ -1083,7 +1088,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 \"|\"") };
}
@@ -1101,7 +1106,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/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/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/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/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/UdpTransport/UdpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp
index e3ab11c117..d50b20831f 100644
--- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp
+++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp
@@ -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();
@@ -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/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/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/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/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/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/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/ModelAssetBuilderComponent.cpp
index a574127f42..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)
}
}
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/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/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/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/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