diff --git a/Assets/Editor/Icons/Components/NonUniformScale.svg b/Assets/Editor/Icons/Components/NonUniformScale.svg
new file mode 100644
index 0000000000..f377232d62
--- /dev/null
+++ b/Assets/Editor/Icons/Components/NonUniformScale.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
index aafa2ff9b7..f84e367d1d 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
@@ -27,6 +27,155 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
@pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponentsMain(object):
- # It requires at least one test
- def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
- pass
+ @pytest.mark.test_case_id(
+ "C32078130", # Display Mapper
+ "C32078129", # Light
+ "C32078131", # Radius Weight Modifier
+ "C32078127", # PostFX Layer
+ "C32078125", # Physical Sky
+ "C32078115", # Global Skylight (IBL)
+ "C32078121", # Exposure Control
+ "C32078120", # Directional Light
+ "C32078119", # DepthOfField
+ "C32078118") # Decal (Atom)
+ def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
+ cfg_args = [level]
+
+ expected_lines = [
+ # Decal (Atom) Component
+ "Decal (Atom) Entity successfully created",
+ "Decal (Atom)_test: Component added to the entity: True",
+ "Decal (Atom)_test: Component removed after UNDO: True",
+ "Decal (Atom)_test: Component added after REDO: True",
+ "Decal (Atom)_test: Entered game mode: True",
+ "Decal (Atom)_test: Exit game mode: True",
+ "Decal (Atom) Controller|Configuration|Material: SUCCESS",
+ "Decal (Atom)_test: Entity is hidden: True",
+ "Decal (Atom)_test: Entity is shown: True",
+ "Decal (Atom)_test: Entity deleted: True",
+ "Decal (Atom)_test: UNDO entity deletion works: True",
+ "Decal (Atom)_test: REDO entity deletion works: True",
+ # DepthOfField Component
+ "DepthOfField Entity successfully created",
+ "DepthOfField_test: Component added to the entity: True",
+ "DepthOfField_test: Component removed after UNDO: True",
+ "DepthOfField_test: Component added after REDO: True",
+ "DepthOfField_test: Entered game mode: True",
+ "DepthOfField_test: Exit game mode: True",
+ "DepthOfField_test: Entity disabled initially: True",
+ "DepthOfField_test: Entity enabled after adding required components: True",
+ "DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
+ "DepthOfField_test: Entity is hidden: True",
+ "DepthOfField_test: Entity is shown: True",
+ "DepthOfField_test: Entity deleted: True",
+ "DepthOfField_test: UNDO entity deletion works: True",
+ "DepthOfField_test: REDO entity deletion works: True",
+ # Exposure Control Component
+ "Exposure Control Entity successfully created",
+ "Exposure Control_test: Component added to the entity: True",
+ "Exposure Control_test: Component removed after UNDO: True",
+ "Exposure Control_test: Component added after REDO: True",
+ "Exposure Control_test: Entered game mode: True",
+ "Exposure Control_test: Exit game mode: True",
+ "Exposure Control_test: Entity disabled initially: True",
+ "Exposure Control_test: Entity enabled after adding required components: True",
+ "Exposure Control_test: Entity is hidden: True",
+ "Exposure Control_test: Entity is shown: True",
+ "Exposure Control_test: Entity deleted: True",
+ "Exposure Control_test: UNDO entity deletion works: True",
+ "Exposure Control_test: REDO entity deletion works: True",
+ # Global Skylight (IBL) Component
+ "Global Skylight (IBL) Entity successfully created",
+ "Global Skylight (IBL)_test: Component added to the entity: True",
+ "Global Skylight (IBL)_test: Component removed after UNDO: True",
+ "Global Skylight (IBL)_test: Component added after REDO: True",
+ "Global Skylight (IBL)_test: Entered game mode: True",
+ "Global Skylight (IBL)_test: Exit game mode: True",
+ "Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
+ "Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
+ "Global Skylight (IBL)_test: Entity is hidden: True",
+ "Global Skylight (IBL)_test: Entity is shown: True",
+ "Global Skylight (IBL)_test: Entity deleted: True",
+ "Global Skylight (IBL)_test: UNDO entity deletion works: True",
+ "Global Skylight (IBL)_test: REDO entity deletion works: True",
+ # Physical Sky Component
+ "Physical Sky Entity successfully created",
+ "Physical Sky component was added to entity",
+ "Entity has a Physical Sky component",
+ "Physical Sky_test: Component added to the entity: True",
+ "Physical Sky_test: Component removed after UNDO: True",
+ "Physical Sky_test: Component added after REDO: True",
+ "Physical Sky_test: Entered game mode: True",
+ "Physical Sky_test: Exit game mode: True",
+ "Physical Sky_test: Entity is hidden: True",
+ "Physical Sky_test: Entity is shown: True",
+ "Physical Sky_test: Entity deleted: True",
+ "Physical Sky_test: UNDO entity deletion works: True",
+ "Physical Sky_test: REDO entity deletion works: True",
+ # PostFX Layer Component
+ "PostFX Layer Entity successfully created",
+ "PostFX Layer_test: Component added to the entity: True",
+ "PostFX Layer_test: Component removed after UNDO: True",
+ "PostFX Layer_test: Component added after REDO: True",
+ "PostFX Layer_test: Entered game mode: True",
+ "PostFX Layer_test: Exit game mode: True",
+ "PostFX Layer_test: Entity is hidden: True",
+ "PostFX Layer_test: Entity is shown: True",
+ "PostFX Layer_test: Entity deleted: True",
+ "PostFX Layer_test: UNDO entity deletion works: True",
+ "PostFX Layer_test: REDO entity deletion works: True",
+ # Radius Weight Modifier Component
+ "Radius Weight Modifier Entity successfully created",
+ "Radius Weight Modifier_test: Component added to the entity: True",
+ "Radius Weight Modifier_test: Component removed after UNDO: True",
+ "Radius Weight Modifier_test: Component added after REDO: True",
+ "Radius Weight Modifier_test: Entered game mode: True",
+ "Radius Weight Modifier_test: Exit game mode: True",
+ "Radius Weight Modifier_test: Entity is hidden: True",
+ "Radius Weight Modifier_test: Entity is shown: True",
+ "Radius Weight Modifier_test: Entity deleted: True",
+ "Radius Weight Modifier_test: UNDO entity deletion works: True",
+ "Radius Weight Modifier_test: REDO entity deletion works: True",
+ # Light Component
+ "Light Entity successfully created",
+ "Light_test: Component added to the entity: True",
+ "Light_test: Component removed after UNDO: True",
+ "Light_test: Component added after REDO: True",
+ "Light_test: Entered game mode: True",
+ "Light_test: Exit game mode: True",
+ "Light_test: Entity is hidden: True",
+ "Light_test: Entity is shown: True",
+ "Light_test: Entity deleted: True",
+ "Light_test: UNDO entity deletion works: True",
+ "Light_test: REDO entity deletion works: True",
+ # Display Mapper Component
+ "Display Mapper Entity successfully created",
+ "Display Mapper_test: Component added to the entity: True",
+ "Display Mapper_test: Component removed after UNDO: True",
+ "Display Mapper_test: Component added after REDO: True",
+ "Display Mapper_test: Entered game mode: True",
+ "Display Mapper_test: Exit game mode: True",
+ "Display Mapper_test: Entity is hidden: True",
+ "Display Mapper_test: Entity is shown: True",
+ "Display Mapper_test: Entity deleted: True",
+ "Display Mapper_test: UNDO entity deletion works: True",
+ "Display Mapper_test: REDO entity deletion works: True",
+ ]
+
+ unexpected_lines = [
+ "failed to open",
+ "Traceback (most recent call last):",
+ ]
+
+ hydra.launch_and_validate_results(
+ request,
+ TEST_DIRECTORY,
+ editor,
+ "hydra_AtomEditorComponents_AddedToEntity.py",
+ timeout=EDITOR_TIMEOUT,
+ expected_lines=expected_lines,
+ unexpected_lines=unexpected_lines,
+ halt_on_unexpected=True,
+ null_renderer=True,
+ cfg_args=cfg_args,
+ )
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py
index 8ca5b5aa31..0fb873e677 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py
@@ -19,170 +19,6 @@ import pytest
@pytest.mark.parametrize("level", ["auto_test"])
class TestAtomEditorComponentsSandbox(object):
- @pytest.mark.test_case_id(
- "C32078117", # Area Light
- "C32078130", # Display Mapper
- "C32078129", # Light
- "C32078131", # Radius Weight Modifier
- "C32078127", # PostFX Layer
- "C32078126", # Point Light
- "C32078125", # Physical Sky
- "C32078115", # Global Skylight (IBL)
- "C32078121", # Exposure Control
- "C32078120", # Directional Light
- "C32078119", # DepthOfField
- "C32078118") # Decal
- def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
- cfg_args = [level]
-
- expected_lines = [
- # Decal Component
- "Decal (Atom) Entity successfully created",
- "Decal (Atom)_test: Component added to the entity: True",
- "Decal (Atom)_test: Component removed after UNDO: True",
- "Decal (Atom)_test: Component added after REDO: True",
- "Decal (Atom)_test: Entered game mode: True",
- "Decal (Atom)_test: Exit game mode: True",
- "Decal (Atom) Controller|Configuration|Material: SUCCESS",
- "Decal (Atom)_test: Entity is hidden: True",
- "Decal (Atom)_test: Entity is shown: True",
- "Decal (Atom)_test: Entity deleted: True",
- "Decal (Atom)_test: UNDO entity deletion works: True",
- "Decal (Atom)_test: REDO entity deletion works: True",
- # DepthOfField Component
- "DepthOfField Entity successfully created",
- "DepthOfField_test: Component added to the entity: True",
- "DepthOfField_test: Component removed after UNDO: True",
- "DepthOfField_test: Component added after REDO: True",
- "DepthOfField_test: Entered game mode: True",
- "DepthOfField_test: Exit game mode: True",
- "DepthOfField_test: Entity disabled initially: True",
- "DepthOfField_test: Entity enabled after adding required components: True",
- "DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
- "DepthOfField_test: Entity is hidden: True",
- "DepthOfField_test: Entity is shown: True",
- "DepthOfField_test: Entity deleted: True",
- "DepthOfField_test: UNDO entity deletion works: True",
- "DepthOfField_test: REDO entity deletion works: True",
- # Directional Light Component
- "Directional Light Entity successfully created",
- "Directional Light_test: Component added to the entity: True",
- "Directional Light_test: Component removed after UNDO: True",
- "Directional Light_test: Component added after REDO: True",
- "Directional Light_test: Entered game mode: True",
- "Directional Light_test: Exit game mode: True",
- "Directional Light Controller|Configuration|Shadow|Camera: SUCCESS",
- "Directional Light_test: Entity is hidden: True",
- "Directional Light_test: Entity is shown: True",
- "Directional Light_test: Entity deleted: True",
- "Directional Light_test: UNDO entity deletion works: True",
- "Directional Light_test: REDO entity deletion works: True",
- # Exposure Control Component
- "Exposure Control Entity successfully created",
- "Exposure Control_test: Component added to the entity: True",
- "Exposure Control_test: Component removed after UNDO: True",
- "Exposure Control_test: Component added after REDO: True",
- "Exposure Control_test: Entered game mode: True",
- "Exposure Control_test: Exit game mode: True",
- "Exposure Control_test: Entity disabled initially: True",
- "Exposure Control_test: Entity enabled after adding required components: True",
- "Exposure Control_test: Entity is hidden: True",
- "Exposure Control_test: Entity is shown: True",
- "Exposure Control_test: Entity deleted: True",
- "Exposure Control_test: UNDO entity deletion works: True",
- "Exposure Control_test: REDO entity deletion works: True",
- # Global Skylight (IBL) Component
- "Global Skylight (IBL) Entity successfully created",
- "Global Skylight (IBL)_test: Component added to the entity: True",
- "Global Skylight (IBL)_test: Component removed after UNDO: True",
- "Global Skylight (IBL)_test: Component added after REDO: True",
- "Global Skylight (IBL)_test: Entered game mode: True",
- "Global Skylight (IBL)_test: Exit game mode: True",
- "Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
- "Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
- "Global Skylight (IBL)_test: Entity is hidden: True",
- "Global Skylight (IBL)_test: Entity is shown: True",
- "Global Skylight (IBL)_test: Entity deleted: True",
- "Global Skylight (IBL)_test: UNDO entity deletion works: True",
- "Global Skylight (IBL)_test: REDO entity deletion works: True",
- # Physical Sky Component
- "Physical Sky Entity successfully created",
- "Physical Sky component was added to entity",
- "Entity has a Physical Sky component",
- "Physical Sky_test: Component added to the entity: True",
- "Physical Sky_test: Component removed after UNDO: True",
- "Physical Sky_test: Component added after REDO: True",
- "Physical Sky_test: Entered game mode: True",
- "Physical Sky_test: Exit game mode: True",
- "Physical Sky_test: Entity is hidden: True",
- "Physical Sky_test: Entity is shown: True",
- "Physical Sky_test: Entity deleted: True",
- "Physical Sky_test: UNDO entity deletion works: True",
- "Physical Sky_test: REDO entity deletion works: True",
- # PostFX Layer Component
- "PostFX Layer Entity successfully created",
- "PostFX Layer_test: Component added to the entity: True",
- "PostFX Layer_test: Component removed after UNDO: True",
- "PostFX Layer_test: Component added after REDO: True",
- "PostFX Layer_test: Entered game mode: True",
- "PostFX Layer_test: Exit game mode: True",
- "PostFX Layer_test: Entity is hidden: True",
- "PostFX Layer_test: Entity is shown: True",
- "PostFX Layer_test: Entity deleted: True",
- "PostFX Layer_test: UNDO entity deletion works: True",
- "PostFX Layer_test: REDO entity deletion works: True",
- # Radius Weight Modifier Component
- "Radius Weight Modifier Entity successfully created",
- "Radius Weight Modifier_test: Component added to the entity: True",
- "Radius Weight Modifier_test: Component removed after UNDO: True",
- "Radius Weight Modifier_test: Component added after REDO: True",
- "Radius Weight Modifier_test: Entered game mode: True",
- "Radius Weight Modifier_test: Exit game mode: True",
- "Radius Weight Modifier_test: Entity is hidden: True",
- "Radius Weight Modifier_test: Entity is shown: True",
- "Radius Weight Modifier_test: Entity deleted: True",
- "Radius Weight Modifier_test: UNDO entity deletion works: True",
- "Radius Weight Modifier_test: REDO entity deletion works: True",
- # Light Component
- "Light Entity successfully created",
- "Light_test: Component added to the entity: True",
- "Light_test: Component removed after UNDO: True",
- "Light_test: Component added after REDO: True",
- "Light_test: Entered game mode: True",
- "Light_test: Exit game mode: True",
- "Light_test: Entity is hidden: True",
- "Light_test: Entity is shown: True",
- "Light_test: Entity deleted: True",
- "Light_test: UNDO entity deletion works: True",
- "Light_test: REDO entity deletion works: True",
- # Display Mapper Component
- "Display Mapper Entity successfully created",
- "Display Mapper_test: Component added to the entity: True",
- "Display Mapper_test: Component removed after UNDO: True",
- "Display Mapper_test: Component added after REDO: True",
- "Display Mapper_test: Entered game mode: True",
- "Display Mapper_test: Exit game mode: True",
- "Display Mapper_test: Entity is hidden: True",
- "Display Mapper_test: Entity is shown: True",
- "Display Mapper_test: Entity deleted: True",
- "Display Mapper_test: UNDO entity deletion works: True",
- "Display Mapper_test: REDO entity deletion works: True",
- ]
-
- unexpected_lines = [
- "failed to open",
- "Traceback (most recent call last):",
- ]
-
- hydra.launch_and_validate_results(
- request,
- TEST_DIRECTORY,
- editor,
- "hydra_AtomEditorComponents_AddedToEntity.py",
- timeout=EDITOR_TIMEOUT,
- expected_lines=expected_lines,
- unexpected_lines=unexpected_lines,
- halt_on_unexpected=True,
- null_renderer=True,
- cfg_args=cfg_args,
- )
+ # It requires at least one test
+ def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
+ pass
diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_ReturnSetType_Successfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_ReturnSetType_Successfully.py
new file mode 100644
index 0000000000..aa9abd110b
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_ReturnSetType_Successfully.py
@@ -0,0 +1,112 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+Test Case Title: Event can return a value of set type successfully
+"""
+
+
+# fmt: off
+class Tests():
+ level_created = ("Successfully created temporary level", "Failed to create temporary level")
+ entity_created = ("Successfully created test entity", "Failed to create test entity")
+ enter_game_mode = ("Successfully entered game mode", "Failed to enter game mode")
+ lines_found = ("Successfully found expected message", "Failed to find expected message")
+ exit_game_mode = ("Successfully exited game mode", "Failed to exit game mode")
+# fmt: on
+
+
+def ScriptEvents_ReturnSetType_Successfully():
+ """
+ Summary: A temporary level is created with an Entity having ScriptCanvas component.
+ ScriptEvent(T92569006_ScriptEvent.scriptevents) is created with one Method that has a return value.
+ ScriptCanvas(T92569006_ScriptCanvas.scriptcanvas) is attached to Entity. Graph has Send node that sends the Method
+ of the ScriptEvent and prints the returned result ( On Entity Activated -> Send node -> Print) and Receive node is
+ set to return custom value ( Receive node -> Print).
+ Verify that the entity containing T92569006_ScriptCanvas.scriptcanvas should print the custom value set in both
+ Send and Receive nodes.
+
+ Expected Behavior:
+ After entering game mode, the graph on the entity should print an expected message to the console
+
+ Test Steps:
+ 1) Create test level
+ 2) Create test entity
+ 3) Start Tracer
+ 4) Enter Game Mode
+ 5) Read for line
+ 6) Exit Game Mode
+
+ Note:
+ - This test file must be called from the Open 3D Engine Editor command terminal
+ - Any passed and failed tests are written to the Editor.log file.
+ Parsing the file or running a log_monitor are required to observe the test results.
+
+ :return: None
+ """
+ import os
+ from editor_entity_utils import EditorEntity as Entity
+ from utils import Report
+ from utils import TestHelper as helper
+ from utils import Tracer
+
+ import azlmbr.legacy.general as general
+ import azlmbr.asset as asset
+ import azlmbr.math as math
+ import azlmbr.bus as bus
+
+ LEVEL_NAME = "tmp_level"
+ WAIT_TIME = 3.0 # SECONDS
+ EXPECTED_LINES = ["T92569006_ScriptEvent_Sent", "T92569006_ScriptEvent_Received"]
+ SC_ASSET_PATH = os.path.join("ScriptCanvas", "T92569006_ScriptCanvas.scriptcanvas")
+
+ def create_editor_entity(name, sc_asset):
+ entity = Entity.create_editor_entity(name)
+ sc_comp = entity.add_component("Script Canvas")
+ asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", sc_asset, math.Uuid(), False)
+ sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", asset_id)
+ Report.critical_result(Tests.entity_created, entity.id.isValid())
+
+ def locate_expected_lines(line_list: list):
+ found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints]
+
+ return all(line in found_lines for line in line_list)
+
+ # 1) Create temp level
+ general.idle_enable(True)
+ result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True)
+ Report.critical_result(Tests.level_created, result == 0)
+ helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME)
+ general.close_pane("Error Report")
+
+ # 2) Create test entity
+ create_editor_entity("TestEntity", SC_ASSET_PATH)
+
+ # 3) Start Tracer
+ with Tracer() as section_tracer:
+
+ # 4) Enter Game Mode
+ helper.enter_game_mode(Tests.enter_game_mode)
+
+ # 5) Read for line
+ lines_located = helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME)
+ Report.result(Tests.lines_found, lines_located)
+
+ # 6) Exit Game Mode
+ helper.exit_game_mode(Tests.exit_game_mode)
+
+
+if __name__ == "__main__":
+ import ImportPathHelper as imports
+
+ imports.init()
+
+ from utils import Report
+
+ Report.start_test(ScriptEvents_ReturnSetType_Successfully)
diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py
index d87f2986bf..152dea93cd 100755
--- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py
+++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py
@@ -183,6 +183,16 @@ class TestAutomation(TestAutomationBase):
from . import ScriptEvents_SendReceiveSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
+ @pytest.mark.parametrize("level", ["tmp_level"])
+ def test_ScriptEvents_ReturnSetType_Successfully(self, request, workspace, editor, launcher_platform, project, level):
+ def teardown():
+ file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
+ request.addfinalizer(teardown)
+ file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
+ from . import ScriptEvents_ReturnSetType_Successfully as test_module
+ self._run_test(request, workspace, editor, test_module)
+
+
# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method
# fails because of pyside_utils import
@pytest.mark.SUITE_periodic
diff --git a/AutomatedTesting/ScriptCanvas/T92569006_ScriptCanvas.scriptcanvas b/AutomatedTesting/ScriptCanvas/T92569006_ScriptCanvas.scriptcanvas
new file mode 100644
index 0000000000..626ee29d96
--- /dev/null
+++ b/AutomatedTesting/ScriptCanvas/T92569006_ScriptCanvas.scriptcanvas
@@ -0,0 +1,1952 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/TestAssets/T92569006.scriptevents b/AutomatedTesting/TestAssets/T92569006.scriptevents
new file mode 100644
index 0000000000..518b1b5733
--- /dev/null
+++ b/AutomatedTesting/TestAssets/T92569006.scriptevents
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp
index d31f122d9b..8818dfa0d9 100644
--- a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp
+++ b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp
@@ -108,10 +108,11 @@ bool CLevelInfo::ReadInfo()
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
+ // Set up a default game type for legacy code.
+ m_defaultGameTypeName = "Mission0";
+
if (usePrefabSystemForLevels)
{
- // Set up a default game type for legacy code.
- m_defaultGameTypeName = "Mission0";
return true;
}
diff --git a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
index 90b9ba5afd..1016027966 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
+++ b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
@@ -53,6 +53,10 @@ namespace AZ
//! RemoveableByUser : A bool which determines if the component can be removed by the user.
//! Setting this to false prevents the user from removing this component. Default behavior is removeable by user.
const static AZ::Crc32 RemoveableByUser = AZ_CRC("RemoveableByUser", 0x32c7fd50);
+ //! An int which, if specified, causes a component to be forced to a particular position in the sorted list of
+ //! components on an entity, and prevents dragging or moving operations which would affect that position.
+ const static AZ::Crc32 FixedComponentListIndex = AZ_CRC_CE("FixedComponentListIndex");
+
const static AZ::Crc32 AppearsInAddComponentMenu = AZ_CRC("AppearsInAddComponentMenu", 0x53790e31);
const static AZ::Crc32 ForceAutoExpand = AZ_CRC("ForceAutoExpand", 0x1a5c79d2); // Ignores expansion state set by user, enforces expansion.
const static AZ::Crc32 AutoExpand = AZ_CRC("AutoExpand", 0x306ff5c0); // Expands automatically unless user changes expansion state.
diff --git a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp
index 095d986fa1..57f14ddb38 100644
--- a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp
@@ -36,6 +36,8 @@ namespace AzFramework
void NonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
+ incompatible.push_back(AZ_CRC_CE("NonUniformScaleService"));
+
incompatible.push_back(AZ_CRC_CE("DebugDrawObbService"));
incompatible.push_back(AZ_CRC_CE("DebugDrawService"));
incompatible.push_back(AZ_CRC_CE("EMotionFXActorService"));
diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.h b/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.h
index 2649655f50..c324104027 100644
--- a/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.h
+++ b/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.h
@@ -48,15 +48,21 @@ namespace AzFramework
};
//! The interface used by MultiViewportController to manage individual instances.
+ template
class MultiViewportControllerInstanceInterface
{
public:
- explicit MultiViewportControllerInstanceInterface(ViewportId viewport)
+ using ControllerType = TController;
+
+ MultiViewportControllerInstanceInterface(ViewportId viewport, ControllerType* controller)
: m_viewportId(viewport)
+ , m_controller(controller)
{
}
ViewportId GetViewportId() const { return m_viewportId; }
+ ControllerType* GetController() { return m_controller; }
+ const ControllerType* GetController() const { return m_controller; }
virtual bool HandleInputChannelEvent([[maybe_unused]]const ViewportControllerInputEvent& event) { return false; }
virtual void ResetInputChannels() {}
@@ -64,6 +70,7 @@ namespace AzFramework
private:
ViewportId m_viewportId;
+ ControllerType* m_controller;
};
} //namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.inl b/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.inl
index cc59418dac..4d82acdfba 100644
--- a/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.inl
+++ b/Code/Framework/AzFramework/AzFramework/Viewport/MultiViewportController.inl
@@ -17,8 +17,8 @@ namespace AzFramework
MultiViewportController::~MultiViewportController()
{
static_assert(
- AZStd::is_constructible::value,
- "TViewportControllerInstance must implement a TViewportControllerInstance(ViewportId) constructor"
+ AZStd::is_same::value,
+ "TViewportControllerInstance must implement a TViewportControllerInstance(ViewportId, ViewportController) constructor"
);
}
@@ -50,7 +50,7 @@ namespace AzFramework
template
void MultiViewportController::RegisterViewportContext(ViewportId viewport)
{
- m_instances[viewport] = AZStd::make_unique(viewport);
+ m_instances[viewport] = AZStd::make_unique(viewport, static_cast(this));
}
template
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h
index 35b2e485b5..1959183fa0 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h
@@ -31,6 +31,10 @@ namespace AzToolsFramework
//! Allows a component to get the list of selected entities
//! \param selectedEntityIds the return vector holding the entities required
virtual void GetSelectedEntities(EntityIdList& selectedEntityIds) = 0;
+
+ //! Explicitly sets a component as having been the most recently added.
+ //! This means that the next time the UI refreshes, that component will be ensured to be visible.
+ virtual void SetNewComponentId(AZ::ComponentId componentId) = 0;
};
using EntityPropertyEditorRequestBus = AZ::EBus;
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
index 475510c52f..d4485f8e99 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
@@ -182,6 +182,22 @@ namespace AzToolsFramework
instanceToParentUnder = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
parent = instanceToParentUnder->get().GetContainerEntityId();
}
+
+ //Detect whether this instantiation would produce a cyclical dependency
+ auto relativePath = m_prefabLoaderInterface->GetRelativePathToProject(filePath);
+ Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath);
+
+ // If the template isn't currently loaded, there's no way for it to be in the hierarchy so we just skip the check.
+ if (templateId != Prefab::InvalidTemplateId && IsPrefabInInstanceAncestorHierarchy(templateId, instanceToParentUnder->get()))
+ {
+ return AZ::Failure(
+ AZStd::string::format(
+ "Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).",
+ relativePath.Native().c_str(),
+ instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str()
+ )
+ );
+ }
{
// Initialize Undo Batch object
@@ -192,7 +208,7 @@ namespace AzToolsFramework
instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
// Instantiate the Prefab
- auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(filePath, instanceToParentUnder);
+ auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(relativePath, instanceToParentUnder);
if (!instanceToCreate)
{
@@ -242,6 +258,23 @@ namespace AzToolsFramework
return AZ::Success();
}
+ bool PrefabPublicHandler::IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance)
+ {
+ InstanceOptionalConstReference currentInstance = instance;
+
+ while (currentInstance.has_value())
+ {
+ if (currentInstance->get().GetTemplateId() == prefabTemplateId)
+ {
+ return true;
+ }
+
+ currentInstance = currentInstance->get().GetParentInstance();
+ }
+
+ return false;
+ }
+
void PrefabPublicHandler::CreateLink(
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
index 5ade666a40..03b3827328 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
@@ -106,6 +106,14 @@ namespace AzToolsFramework
const AZStd::vector& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
+ /* Detects whether an instance of prefabTemplateId is present in the hierarchy of ancestors of instance.
+ *
+ * \param prefabTemplateId The template id to test for
+ * \param instance The instance whose ancestor hierarchy prefabTemplateId will be tested against.
+ * \return true if an instance of the template of id prefabTemplateId could be found in the ancestor hierarchy of instance, false otherwise.
+ */
+ bool IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance);
+
static Instance* GetParentInstance(Instance* instance);
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation);
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp
index 4413586e77..3910e80f75 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp
@@ -721,6 +721,8 @@ namespace AzToolsFramework
TemplateId PrefabSystemComponent::GetTemplateIdFromFilePath(AZ::IO::PathView filePath) const
{
+ AZ_Assert(!filePath.IsAbsolute(), "Prefab - GetTemplateIdFromFilePath was passed an absolute path. Prefabs use paths relative to the project folder.");
+
auto found = m_templateFilePathToIdMap.find(filePath);
if (found != m_templateFilePathToIdMap.end())
{
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp
index 5e928a382a..989398f196 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp
@@ -39,9 +39,10 @@ namespace AzToolsFramework
editContext->Class("Non-uniform Scale",
"Non-uniform scale for this entity only (does not propagate through hierarchy)")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
- ->Attribute(AZ::Edit::Attributes::Category, "Non-uniform Scale")
- ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
- ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
+ ->Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 1)
+ ->Attribute(AZ::Edit::Attributes::RemoveableByUser, true)
+ ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NonUniformScale.svg")
+ ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/NonUniformScale.svg")
->DataElement(
AZ::Edit::UIHandlers::Default, &EditorNonUniformScaleComponent::m_scale, "Non-uniform Scale",
"Non-uniform scale for this entity only (does not propagate through hierarchy)")
@@ -61,6 +62,8 @@ namespace AzToolsFramework
void EditorNonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
+ incompatible.push_back(AZ_CRC_CE("NonUniformScaleService"));
+
incompatible.push_back(AZ_CRC_CE("DebugDrawObbService"));
incompatible.push_back(AZ_CRC_CE("DebugDrawService"));
incompatible.push_back(AZ_CRC_CE("EMotionFXActorService"));
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp
index dcced5b705..f8d02b6581 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp
@@ -25,11 +25,15 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
#include
#include
+#include
+#include
#include
#include
@@ -1196,6 +1200,66 @@ namespace AzToolsFramework
destinationComponent->SetWorldTM(const_cast(sourceComponent)->GetWorldTM());
}
+ AZ::Component* TransformComponent::FindPresentOrPendingComponent(AZ::Uuid componentUuid)
+ {
+ // first check if the component is present and valid
+ if (AZ::Component* foundComponent = GetEntity()->FindComponent(componentUuid))
+ {
+ return foundComponent;
+ }
+
+ // then check to see if there's a component pending because it's in an invalid state
+ AZStd::vector pendingComponents;
+ AzToolsFramework::EditorPendingCompositionRequestBus::Event(GetEntityId(),
+ &AzToolsFramework::EditorPendingCompositionRequests::GetPendingComponents, pendingComponents);
+
+ for (const auto pendingComponent : pendingComponents)
+ {
+ if (pendingComponent->RTTI_IsTypeOf(componentUuid))
+ {
+ return pendingComponent;
+ }
+ }
+
+ return nullptr;
+ }
+
+ bool TransformComponent::IsAddNonUniformScaleButtonReadOnly()
+ {
+ return FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid()) != nullptr;
+ }
+
+ AZ::Crc32 TransformComponent::OnAddNonUniformScaleButtonPressed()
+ {
+ // if there is already a non-uniform scale component, do nothing
+ if (FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid()))
+ {
+ return AZ::Edit::PropertyRefreshLevels::None;
+ }
+
+ const AZStd::vector entityList = { GetEntityId() };
+ const AZ::ComponentTypeList componentsToAdd = { EditorNonUniformScaleComponent::TYPEINFO_Uuid() };
+
+ AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome addComponentsOutcome;
+ AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(addComponentsOutcome,
+ &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd);
+
+ const auto nonUniformScaleComponent = FindPresentOrPendingComponent(EditorNonUniformScaleComponent::RTTI_Type());
+ AZ::ComponentId nonUniformScaleComponentId =
+ nonUniformScaleComponent ? nonUniformScaleComponent->GetId() : AZ::InvalidComponentId;
+
+ if (!addComponentsOutcome.IsSuccess() || !nonUniformScaleComponent)
+ {
+ AZ_Warning("Transform component", false, "Failed to add non-uniform scale component.");
+ return AZ::Edit::PropertyRefreshLevels::None;
+ }
+
+ AzToolsFramework::EntityPropertyEditorRequestBus::Broadcast(
+ &AzToolsFramework::EntityPropertyEditorRequests::SetNewComponentId, nonUniformScaleComponentId);
+
+ return AZ::Edit::PropertyRefreshLevels::EntireTree;
+ }
+
void TransformComponent::Reflect(AZ::ReflectContext* context)
{
// reflect data for script, serialization, editing..
@@ -1211,6 +1275,7 @@ namespace AzToolsFramework
serializeContext->Class()->
Field("Parent Entity", &TransformComponent::m_parentEntityId)->
Field("Transform Data", &TransformComponent::m_editorTransform)->
+ Field("AddNonUniformScaleButton", &TransformComponent::m_addNonUniformScaleButton)->
Field("Cached World Transform", &TransformComponent::m_cachedWorldTransform)->
Field("Cached World Transform Parent", &TransformComponent::m_cachedWorldTransformParent)->
Field("Parent Activation Transform Mode", &TransformComponent::m_parentActivationTransformMode)->
@@ -1224,6 +1289,7 @@ namespace AzToolsFramework
{
ptrEdit->Class("Transform", "Controls the placement of the entity in the world in 3d")->
ClassElement(AZ::Edit::ClassElements::EditorData, "")->
+ Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 0)->
Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Transform.svg")->
Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Transform.png")->
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
@@ -1234,6 +1300,10 @@ namespace AzToolsFramework
DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_editorTransform, "Values", "")->
Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::TransformChanged)->
Attribute(AZ::Edit::Attributes::AutoExpand, true)->
+ DataElement(AZ::Edit::UIHandlers::Button, &TransformComponent::m_addNonUniformScaleButton, "", "")->
+ Attribute(AZ::Edit::Attributes::ButtonText, "Add non-uniform scale")->
+ Attribute(AZ::Edit::Attributes::ReadOnly, &TransformComponent::IsAddNonUniformScaleButtonReadOnly)->
+ Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::OnAddNonUniformScaleButtonPressed)->
DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_parentActivationTransformMode,
"Parent activation", "Configures relative transform behavior when parent activates.")->
EnumAttribute(AZ::TransformConfig::ParentActivationTransformMode::MaintainOriginalRelativeTransform, "Original relative transform")->
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h
index 8327c5f128..3d1e1ed672 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include "EditorComponentBase.h"
#include "TransformComponentBus.h"
@@ -228,6 +229,10 @@ namespace AzToolsFramework
void CheckApplyCachedWorldTransform(const AZ::Transform& parentWorld);
+ AZ::Component* FindPresentOrPendingComponent(AZ::Uuid componentUuid);
+ bool IsAddNonUniformScaleButtonReadOnly();
+ AZ::Crc32 OnAddNonUniformScaleButtonPressed();
+
// Drives transform behavior when parent activates. See AZ::TransformConfig::ParentActivationTransformMode for details.
AZ::TransformConfig::ParentActivationTransformMode m_parentActivationTransformMode;
@@ -260,6 +265,10 @@ namespace AzToolsFramework
bool m_worldTransformDirty = true;
bool m_isStatic = false;
+ // This is a workaround for a bug which causes the button to appear with incorrect placement if a UI
+ // element is used rather than a data element.
+ bool m_addNonUniformScaleButton = false;
+
// Deprecated
AZ::InterpolationMode m_interpolatePosition;
AZ::InterpolationMode m_interpolateRotation;
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp
index 181f5b9a9d..bfb2ff4256 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp
@@ -63,6 +63,7 @@ AZ_POP_DISABLE_WARNING
#include
#include
#include
+#include
#include
#include
#include
@@ -494,6 +495,11 @@ namespace AzToolsFramework
}
}
+ void EntityPropertyEditor::SetNewComponentId(AZ::ComponentId componentId)
+ {
+ m_newComponentId = componentId;
+ }
+
void EntityPropertyEditor::SetOverrideEntityIds(const AzToolsFramework::EntityIdSet& entities)
{
m_overrideSelectedEntityIds = entities;
@@ -1039,15 +1045,23 @@ namespace AzToolsFramework
sortedComponents.end(),
[=](const OrderedSortComponentEntry& component1, const OrderedSortComponentEntry& component2)
{
- // Transform component must be first, always
- // If component 1 is a transform component, it is sorted earlier
- if (component1.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId))
+ AZStd::optional fixedComponentListIndex1 = GetFixedComponentListIndex(component1.m_component);
+ AZStd::optional fixedComponentListIndex2 = GetFixedComponentListIndex(component2.m_component);
+
+ // If both components have fixed list indices, sort based on those indices
+ if (fixedComponentListIndex1.has_value() && fixedComponentListIndex2.has_value())
+ {
+ return fixedComponentListIndex1.value() < fixedComponentListIndex2.value();
+ }
+
+ // If component 1 has a fixed list index, sort it first
+ if (fixedComponentListIndex1.has_value())
{
return true;
}
- // If component 2 is a transform component, component 1 is never sorted earlier
- if (component2.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId))
+ // If component 2 has a fixed list index, component 1 should not be sorted before it
+ if (fixedComponentListIndex2.has_value())
{
return false;
}
@@ -1128,10 +1142,7 @@ namespace AzToolsFramework
{
if (auto attributeData = azdynamic_cast*>(attribute))
{
- if (!attributeData->Get(nullptr))
- {
- return false;
- }
+ return attributeData->Get(nullptr);
}
}
}
@@ -1166,6 +1177,36 @@ namespace AzToolsFramework
return true;
}
+ AZStd::optional EntityPropertyEditor::GetFixedComponentListIndex(const AZ::Component* component)
+ {
+ auto componentClassData = component ? GetComponentClassData(component) : nullptr;
+ if (componentClassData && componentClassData->m_editData)
+ {
+ if (auto editorDataElement = componentClassData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData))
+ {
+ if (auto attribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::FixedComponentListIndex))
+ {
+ if (auto attributeData = azdynamic_cast*>(attribute))
+ {
+ return { attributeData->Get(nullptr) };
+ }
+ }
+ }
+ }
+ return {};
+ }
+
+ bool EntityPropertyEditor::IsComponentDraggable(const AZ::Component* component)
+ {
+ return !GetFixedComponentListIndex(component).has_value();
+ }
+
+ bool EntityPropertyEditor::AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const
+ {
+ return AZStd::all_of(
+ components.begin(), components.end(), [](AZ::Component* component) { return IsComponentDraggable(component); });
+ }
+
bool EntityPropertyEditor::AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const
{
return AreComponentsCopyable(components, m_componentFilter);
@@ -3367,7 +3408,9 @@ namespace AzToolsFramework
sourceComponents.size() == m_selectedEntityIds.size() &&
targetComponents.size() == m_selectedEntityIds.size() &&
AreComponentsRemovable(sourceComponents) &&
- AreComponentsRemovable(targetComponents);
+ AreComponentsRemovable(targetComponents) &&
+ AreComponentsDraggable(sourceComponents) &&
+ AreComponentsDraggable(targetComponents);
}
bool EntityPropertyEditor::IsMoveComponentsUpAllowed() const
@@ -3681,14 +3724,38 @@ namespace AzToolsFramework
void EntityPropertyEditor::ScrollToNewComponent()
{
- //force new components to be visible, assuming they are added to the end of the list and layout
- auto componentEditor = GetComponentEditorsFromIndex(m_componentEditorsUsed - 1);
+ // force new components to be visible
+ // if no component has been explicitly set at the most recently added,
+ // assume new components are added to the end of the list and layout
+ AZ::s32 newComponentIndex = m_componentEditorsUsed - 1;
+
+ // if there is a component id explicitly set as the most recently added, try to find it and make sure it is visible
+ if (m_newComponentId.has_value() && m_newComponentId.value() != AZ::InvalidComponentId)
+ {
+ AZ::ComponentId newComponentId = m_newComponentId.value();
+ for (AZ::s32 componentIndex = 0; componentIndex < m_componentEditorsUsed; ++componentIndex)
+ {
+ if (m_componentEditors[componentIndex])
+ {
+ for (const auto component : m_componentEditors[componentIndex]->GetComponents())
+ {
+ if (component->GetId() == newComponentId)
+ {
+ newComponentIndex = componentIndex;
+ }
+ }
+ }
+ }
+ }
+
+ auto componentEditor = GetComponentEditorsFromIndex(newComponentIndex);
if (componentEditor)
{
m_gui->m_componentList->ensureWidgetVisible(componentEditor);
}
m_shouldScrollToNewComponents = false;
m_shouldScrollToNewComponentsQueued = false;
+ m_newComponentId.reset();
}
void EntityPropertyEditor::QueueScrollToNewComponent()
@@ -4073,7 +4140,8 @@ namespace AzToolsFramework
{
if (!componentEditor ||
!componentEditor->isVisible() ||
- !AreComponentsRemovable(componentEditor->GetComponents()))
+ !AreComponentsRemovable(componentEditor->GetComponents()) ||
+ !AreComponentsDraggable(componentEditor->GetComponents()))
{
return false;
}
@@ -4223,6 +4291,7 @@ namespace AzToolsFramework
while (targetComponentEditor
&& (targetComponentEditor->IsDragged()
|| !AreComponentsRemovable(targetComponentEditor->GetComponents())
+ || !AreComponentsDraggable(targetComponentEditor->GetComponents())
|| (globalRect.center().y() > GetWidgetGlobalRect(targetComponentEditor).center().y())))
{
if (targetItr == m_componentEditors.end() || targetComponentEditor == m_componentEditors.back() || !targetComponentEditor->isVisible())
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx
index 677dc98277..9cd380ae06 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx
@@ -211,6 +211,7 @@ namespace AzToolsFramework
// EntityPropertEditorRequestBus
void GetSelectedAndPinnedEntities(EntityIdList& selectedEntityIds) override;
void GetSelectedEntities(EntityIdList& selectedEntityIds) override;
+ void SetNewComponentId(AZ::ComponentId componentId) override;
bool IsEntitySelected(const AZ::EntityId& id) const;
bool IsSingleEntitySelected(const AZ::EntityId& id) const;
@@ -237,6 +238,9 @@ namespace AzToolsFramework
static bool DoesComponentPassFilter(const AZ::Component* component, const ComponentFilter& filter);
static bool IsComponentRemovable(const AZ::Component* component);
bool AreComponentsRemovable(const AZ::Entity::ComponentArrayType& components) const;
+ static AZStd::optional GetFixedComponentListIndex(const AZ::Component* component);
+ static bool IsComponentDraggable(const AZ::Component* component);
+ bool AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const;
bool AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const;
void AddMenuOptionsForComponents(QMenu& menu, const QPoint& position);
@@ -568,6 +572,9 @@ namespace AzToolsFramework
void ConnectToEntityBuses(const AZ::EntityId& entityId);
void DisconnectFromEntityBuses(const AZ::EntityId& entityId);
+ //! Stores a component id to be focused on next time the UI updates.
+ AZStd::optional m_newComponentId;
+
private slots:
void OnPropertyRefreshRequired(); // refresh is needed for a property.
void UpdateContents();
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h
index 4e7a520698..ee95412376 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h
@@ -178,6 +178,24 @@ namespace AzToolsFramework
~ViewportInteractionRequests() = default;
};
+ /// Interface to return only viewport specific settings (e.g. snapping).
+ class ViewportSettings
+ {
+ public:
+ virtual ~ViewportSettings() = default;
+
+ /// Return if grid snapping is enabled.
+ virtual bool GridSnappingEnabled() const = 0;
+ /// Return the grid snapping size.
+ virtual float GridSize() const = 0;
+ /// Does the grid currently want to be displayed.
+ virtual bool ShowGrid() const = 0;
+ /// Return if angle snapping is enabled.
+ virtual bool AngleSnappingEnabled() const = 0;
+ /// Return the angle snapping/step size.
+ virtual float AngleStep() const = 0;
+ };
+
/// Type to inherit to implement ViewportInteractionRequests.
using ViewportInteractionRequestBus = AZ::EBus;
diff --git a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp
index 3017df737d..d0f93bfdf8 100644
--- a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp
+++ b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp
@@ -17,13 +17,13 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
-#include
#include
#include
@@ -55,7 +55,7 @@ namespace UnitTest
TEST(EntityPropertyEditorTests, PrioritySort_NonTransformAsFirstItem_TransformMovesToTopRemainderUnchanged)
{
- ComponentApplication app;
+ ToolsApplication app;
AZ::Entity::ComponentArrayType unorderedComponents;
AZ::Entity::ComponentArrayType orderedComponents;
@@ -68,12 +68,18 @@ namespace UnitTest
Entity* systemEntity = app.Create(desc, startupParams);
+ // Need to reflect the components so that edit attribute used for sorting, such as FixedComponentListIndex, get set.
+ app.RegisterComponentDescriptor(AzToolsFramework::Components::TransformComponent::CreateDescriptor());
+ app.RegisterComponentDescriptor(AzToolsFramework::Components::ScriptEditorComponent::CreateDescriptor());
+ app.RegisterComponentDescriptor(AZ::AssetManagerComponent::CreateDescriptor());
+
// Add more than 31 components, as we are testing the case where the sort fails when there are 32 or more items.
const int numFillerItems = 32;
for (int commentIndex = 0; commentIndex < numFillerItems; commentIndex++)
{
- unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent(AZ::StreamerComponent::RTTI_Type()));
+ unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent(
+ AzToolsFramework::Components::ScriptEditorComponent::RTTI_Type()));
}
// Add a TransformComponent at the end which should be sorted to the beginning by the priority sort.
diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp
index d9344746a2..0b3ff87e43 100644
--- a/Code/Sandbox/Editor/EditorViewportWidget.cpp
+++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp
@@ -106,6 +106,15 @@ AZ_CVAR(
EditorViewportWidget* EditorViewportWidget::m_pPrimaryViewport = nullptr;
+namespace AzFramework
+{
+ extern InputChannelId CameraFreeLookButton;
+ extern InputChannelId CameraFreePanButton;
+ extern InputChannelId CameraOrbitLookButton;
+ extern InputChannelId CameraOrbitDollyButton;
+ extern InputChannelId CameraOrbitPanButton;
+}
+
#if AZ_TRAIT_OS_PLATFORM_APPLE
void StopFixedCursorMode();
void StartFixedCursorMode(QObject *viewport);
@@ -161,6 +170,7 @@ EditorViewportWidget::EditorViewportWidget(const QString& name, QWidget* parent)
, m_camFOV(gSettings.viewports.fDefaultFov)
, m_defaultViewName(name)
, m_renderViewport(nullptr) //m_renderViewport is initialized later, in SetViewportId
+ , m_editorViewportSettings(this)
{
// need this to be set in order to allow for language switching on Windows
setAttribute(Qt::WA_InputMethodEnabled);
@@ -1098,32 +1108,6 @@ AzFramework::CameraState EditorViewportWidget::GetCameraState()
return m_renderViewport->GetCameraState();
}
-bool EditorViewportWidget::GridSnappingEnabled()
-{
- return GetViewManager()->GetGrid()->IsEnabled();
-}
-
-float EditorViewportWidget::GridSize()
-{
- const CGrid* grid = GetViewManager()->GetGrid();
- return grid->scale * grid->size;
-}
-
-bool EditorViewportWidget::ShowGrid()
-{
- return gSettings.viewports.bShowGridGuide;
-}
-
-bool EditorViewportWidget::AngleSnappingEnabled()
-{
- return GetViewManager()->GetGrid()->IsAngleSnapEnabled();
-}
-
-float EditorViewportWidget::AngleStep()
-{
- return GetViewManager()->GetGrid()->GetAngleSnap();
-}
-
AZ::Vector3 EditorViewportWidget::PickTerrain(const AzFramework::ScreenPoint& point)
{
FUNCTION_PROFILER(GetIEditor()->GetSystem(), PROFILE_EDITOR);
@@ -1227,13 +1211,47 @@ void EditorViewportWidget::SetViewportId(int id)
if (ed_useNewCameraSystem)
{
AzFramework::ReloadCameraKeyBindings();
- m_renderViewport->GetControllerList()->Add(AZStd::make_shared());
+
+ auto controller = AZStd::make_shared();
+ controller->SetCameraListBuilderCallback([](AzFramework::Cameras& cameras)
+ {
+ auto firstPersonRotateCamera = AZStd::make_shared(AzFramework::CameraFreeLookButton);
+ auto firstPersonPanCamera =
+ AZStd::make_shared(AzFramework::CameraFreePanButton, AzFramework::LookPan);
+ auto firstPersonTranslateCamera = AZStd::make_shared(AzFramework::LookTranslation);
+ auto firstPersonWheelCamera = AZStd::make_shared();
+
+ auto orbitCamera = AZStd::make_shared();
+ auto orbitRotateCamera = AZStd::make_shared(AzFramework::CameraOrbitLookButton);
+ auto orbitTranslateCamera = AZStd::make_shared(AzFramework::OrbitTranslation);
+ auto orbitDollyWheelCamera = AZStd::make_shared();
+ auto orbitDollyMoveCamera =
+ AZStd::make_shared(AzFramework::CameraOrbitDollyButton);
+ auto orbitPanCamera =
+ AZStd::make_shared(AzFramework::CameraOrbitPanButton, AzFramework::OrbitPan);
+
+ orbitCamera->m_orbitCameras.AddCamera(orbitRotateCamera);
+ orbitCamera->m_orbitCameras.AddCamera(orbitTranslateCamera);
+ orbitCamera->m_orbitCameras.AddCamera(orbitDollyWheelCamera);
+ orbitCamera->m_orbitCameras.AddCamera(orbitDollyMoveCamera);
+ orbitCamera->m_orbitCameras.AddCamera(orbitPanCamera);
+
+ cameras.AddCamera(firstPersonRotateCamera);
+ cameras.AddCamera(firstPersonPanCamera);
+ cameras.AddCamera(firstPersonTranslateCamera);
+ cameras.AddCamera(firstPersonWheelCamera);
+ cameras.AddCamera(orbitCamera);
+ });
+
+ m_renderViewport->GetControllerList()->Add(controller);
}
else
{
m_renderViewport->GetControllerList()->Add(AZStd::make_shared());
}
+ m_renderViewport->SetViewportSettings(&m_editorViewportSettings);
+
UpdateScene();
if (m_pPrimaryViewport == this)
@@ -2853,4 +2871,35 @@ void EditorViewportWidget::SetAsActiveViewport()
}
}
+EditorViewportSettings::EditorViewportSettings(const EditorViewportWidget* editorViewportWidget)
+ : m_editorViewportWidget(editorViewportWidget)
+{
+}
+
+bool EditorViewportSettings::GridSnappingEnabled() const
+{
+ return m_editorViewportWidget->GetViewManager()->GetGrid()->IsEnabled();
+}
+
+float EditorViewportSettings::GridSize() const
+{
+ const CGrid* grid = m_editorViewportWidget->GetViewManager()->GetGrid();
+ return grid->scale * grid->size;
+}
+
+bool EditorViewportSettings::ShowGrid() const
+{
+ return gSettings.viewports.bShowGridGuide;
+}
+
+bool EditorViewportSettings::AngleSnappingEnabled() const
+{
+ return m_editorViewportWidget->GetViewManager()->GetGrid()->IsAngleSnapEnabled();
+}
+
+float EditorViewportSettings::AngleStep() const
+{
+ return m_editorViewportWidget->GetViewManager()->GetGrid()->GetAngleSnap();
+}
+
#include
diff --git a/Code/Sandbox/Editor/EditorViewportWidget.h b/Code/Sandbox/Editor/EditorViewportWidget.h
index 09474200f1..8675c035f6 100644
--- a/Code/Sandbox/Editor/EditorViewportWidget.h
+++ b/Code/Sandbox/Editor/EditorViewportWidget.h
@@ -65,6 +65,23 @@ namespace AzToolsFramework
class ManipulatorManager;
}
+class EditorViewportWidget;
+
+//! Viewport settings for the EditorViewportWidget
+struct EditorViewportSettings : public AzToolsFramework::ViewportInteraction::ViewportSettings
+{
+ explicit EditorViewportSettings(const EditorViewportWidget* editorViewportWidget);
+
+ bool GridSnappingEnabled() const override;
+ float GridSize() const override;
+ bool ShowGrid() const override;
+ bool AngleSnappingEnabled() const override;
+ float AngleStep() const override;
+
+private:
+ const EditorViewportWidget* m_editorViewportWidget = nullptr;
+};
+
// EditorViewportWidget window
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
@@ -189,13 +206,7 @@ public:
virtual void OnStartPlayInEditor();
virtual void OnStopPlayInEditor();
- // AzToolsFramework::ViewportInteractionRequestBus
AzFramework::CameraState GetCameraState();
- bool GridSnappingEnabled();
- float GridSize();
- bool ShowGrid();
- bool AngleSnappingEnabled();
- float AngleStep();
AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition);
// AzToolsFramework::ViewportFreezeRequestBus
@@ -596,5 +607,7 @@ private:
AZ::Name m_defaultViewportContextName;
+ EditorViewportSettings m_editorViewportSettings;
+
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
diff --git a/Code/Sandbox/Editor/GameExporter.cpp b/Code/Sandbox/Editor/GameExporter.cpp
index 31f3fafe84..1b42f75ba3 100644
--- a/Code/Sandbox/Editor/GameExporter.cpp
+++ b/Code/Sandbox/Editor/GameExporter.cpp
@@ -295,6 +295,17 @@ void CGameExporter::ExportLevelData(const QString& path, bool /*bExportMission*/
CCryMemFile fileAction;
fileAction.Write(xmlDataAction.c_str(), xmlDataAction.length());
m_levelPak.m_pakFile.UpdateFile(levelDataActionFile.toUtf8().data(), fileAction);
+
+ AZStd::vector entitySaveBuffer;
+ AZ::IO::ByteContainerStream > entitySaveStream(&entitySaveBuffer);
+ bool savedEntities = false;
+ EBUS_EVENT_RESULT(savedEntities, AzToolsFramework::EditorEntityContextRequestBus, SaveToStreamForGame, entitySaveStream, AZ::DataStream::ST_BINARY);
+ if (savedEntities)
+ {
+ QString entitiesFile;
+ entitiesFile = QStringLiteral("%1%2.entities_xml").arg(path, "Mission0");
+ m_levelPak.m_pakFile.UpdateFile(entitiesFile.toUtf8().data(), entitySaveBuffer.begin(), entitySaveBuffer.size());
+ }
}
//////////////////////////////////////////////////////////////////////////
diff --git a/Code/Sandbox/Editor/LegacyViewportCameraController.cpp b/Code/Sandbox/Editor/LegacyViewportCameraController.cpp
index 518b17f898..56bf986cfc 100644
--- a/Code/Sandbox/Editor/LegacyViewportCameraController.cpp
+++ b/Code/Sandbox/Editor/LegacyViewportCameraController.cpp
@@ -28,8 +28,8 @@
namespace SandboxEditor
{
-LegacyViewportCameraControllerInstance::LegacyViewportCameraControllerInstance(AzFramework::ViewportId viewportId)
- : AzFramework::MultiViewportControllerInstanceInterface(viewportId)
+LegacyViewportCameraControllerInstance::LegacyViewportCameraControllerInstance(AzFramework::ViewportId viewportId, LegacyViewportCameraController* controller)
+ : AzFramework::MultiViewportControllerInstanceInterface(viewportId, controller)
{
}
diff --git a/Code/Sandbox/Editor/LegacyViewportCameraController.h b/Code/Sandbox/Editor/LegacyViewportCameraController.h
index 129a2409da..84a8fe2301 100644
--- a/Code/Sandbox/Editor/LegacyViewportCameraController.h
+++ b/Code/Sandbox/Editor/LegacyViewportCameraController.h
@@ -28,11 +28,14 @@ namespace AzFramework
namespace SandboxEditor
{
+ class LegacyViewportCameraControllerInstance;
+ using LegacyViewportCameraController = AzFramework::MultiViewportController;
+
class LegacyViewportCameraControllerInstance final
- : public AzFramework::MultiViewportControllerInstanceInterface
+ : public AzFramework::MultiViewportControllerInstanceInterface
{
public:
- explicit LegacyViewportCameraControllerInstance(AzFramework::ViewportId viewport);
+ LegacyViewportCameraControllerInstance(AzFramework::ViewportId viewport, LegacyViewportCameraController* controller);
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
void ResetInputChannels() override;
@@ -69,5 +72,4 @@ namespace SandboxEditor
bool m_capturingCursor = false;
};
- using LegacyViewportCameraController = AzFramework::MultiViewportController;
} //namespace SandboxEditor
diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.cpp b/Code/Sandbox/Editor/ModernViewportCameraController.cpp
index 4725721f0e..1c2771514f 100644
--- a/Code/Sandbox/Editor/ModernViewportCameraController.cpp
+++ b/Code/Sandbox/Editor/ModernViewportCameraController.cpp
@@ -22,15 +22,6 @@
#include
#include
-namespace AzFramework
-{
- extern InputChannelId CameraFreeLookButton;
- extern InputChannelId CameraFreePanButton;
- extern InputChannelId CameraOrbitLookButton;
- extern InputChannelId CameraOrbitDollyButton;
- extern InputChannelId CameraOrbitPanButton;
-}
-
namespace SandboxEditor
{
static void DrawPreviewAxis(AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, const float axisLength)
@@ -60,36 +51,23 @@ namespace SandboxEditor
return viewportContext;
}
- ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance(const AzFramework::ViewportId viewportId)
- : MultiViewportControllerInstanceInterface(viewportId)
+ void ModernViewportCameraController::SetCameraListBuilderCallback(const CameraListBuilder& builder)
{
- // LYN-2315 TODO - move setup out of constructor, pass cameras in
- auto firstPersonRotateCamera = AZStd::make_shared(AzFramework::CameraFreeLookButton);
- auto firstPersonPanCamera =
- AZStd::make_shared(AzFramework::CameraFreePanButton, AzFramework::LookPan);
- auto firstPersonTranslateCamera = AZStd::make_shared(AzFramework::LookTranslation);
- auto firstPersonWheelCamera = AZStd::make_shared();
+ m_cameraListBuilder = builder;
+ }
- auto orbitCamera = AZStd::make_shared();
- auto orbitRotateCamera = AZStd::make_shared(AzFramework::CameraOrbitLookButton);
- auto orbitTranslateCamera = AZStd::make_shared(AzFramework::OrbitTranslation);
- auto orbitDollyWheelCamera = AZStd::make_shared();
- auto orbitDollyMoveCamera =
- AZStd::make_shared(AzFramework::CameraOrbitDollyButton);
- auto orbitPanCamera =
- AZStd::make_shared(AzFramework::CameraOrbitPanButton, AzFramework::OrbitPan);
+ void ModernViewportCameraController::SetupCameras(AzFramework::Cameras& cameras)
+ {
+ if (m_cameraListBuilder)
+ {
+ m_cameraListBuilder(cameras);
+ }
+ }
- orbitCamera->m_orbitCameras.AddCamera(orbitRotateCamera);
- orbitCamera->m_orbitCameras.AddCamera(orbitTranslateCamera);
- orbitCamera->m_orbitCameras.AddCamera(orbitDollyWheelCamera);
- orbitCamera->m_orbitCameras.AddCamera(orbitDollyMoveCamera);
- orbitCamera->m_orbitCameras.AddCamera(orbitPanCamera);
-
- m_cameraSystem.m_cameras.AddCamera(firstPersonRotateCamera);
- m_cameraSystem.m_cameras.AddCamera(firstPersonPanCamera);
- m_cameraSystem.m_cameras.AddCamera(firstPersonTranslateCamera);
- m_cameraSystem.m_cameras.AddCamera(firstPersonWheelCamera);
- m_cameraSystem.m_cameras.AddCamera(orbitCamera);
+ ModernViewportCameraControllerInstance::ModernViewportCameraControllerInstance(const AzFramework::ViewportId viewportId, ModernViewportCameraController* controller)
+ : MultiViewportControllerInstanceInterface(viewportId, controller)
+ {
+ controller->SetupCameras(m_cameraSystem.m_cameras);
if (auto viewportContext = RetrieveViewportContext(GetViewportId()))
{
diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.h b/Code/Sandbox/Editor/ModernViewportCameraController.h
index 56345ad0da..b1ff8d1039 100644
--- a/Code/Sandbox/Editor/ModernViewportCameraController.h
+++ b/Code/Sandbox/Editor/ModernViewportCameraController.h
@@ -19,12 +19,29 @@
namespace SandboxEditor
{
- class ModernViewportCameraControllerInstance final : public AzFramework::MultiViewportControllerInstanceInterface,
- private AzFramework::ViewportDebugDisplayEventBus::Handler
+ class ModernViewportCameraControllerInstance;
+ class ModernViewportCameraController
+ : public AzFramework::MultiViewportController
{
public:
- explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId);
- ~ModernViewportCameraControllerInstance();
+ using CameraListBuilder = AZStd::function;
+ //! Sets the camera list builder callback used to populate new ModernViewportCameraControllerInstances
+ void SetCameraListBuilderCallback(const CameraListBuilder& builder);
+
+ //! Sets up a camera list based on this controller's CameraListBuilderCallback
+ void SetupCameras(AzFramework::Cameras& cameras);
+
+ private:
+ CameraListBuilder m_cameraListBuilder;
+ };
+
+ class ModernViewportCameraControllerInstance final
+ : public AzFramework::MultiViewportControllerInstanceInterface
+ , private AzFramework::ViewportDebugDisplayEventBus::Handler
+ {
+ public:
+ explicit ModernViewportCameraControllerInstance(AzFramework::ViewportId viewportId, ModernViewportCameraController* controller);
+ ~ModernViewportCameraControllerInstance() override;
// MultiViewportControllerInstanceInterface overrides ...
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
@@ -51,6 +68,4 @@ namespace SandboxEditor
AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraViewMatrixChangeHandler;
};
-
- using ModernViewportCameraController = AzFramework::MultiViewportController;
} // namespace SandboxEditor
diff --git a/Code/Sandbox/Editor/ViewportManipulatorController.cpp b/Code/Sandbox/Editor/ViewportManipulatorController.cpp
index 43d2fb1f2c..0bf2bbc412 100644
--- a/Code/Sandbox/Editor/ViewportManipulatorController.cpp
+++ b/Code/Sandbox/Editor/ViewportManipulatorController.cpp
@@ -27,8 +27,8 @@ static const auto InteractionPriority = AzFramework::ViewportControllerPriority:
namespace SandboxEditor
{
-ViewportManipulatorControllerInstance::ViewportManipulatorControllerInstance(AzFramework::ViewportId viewport)
- : AzFramework::MultiViewportControllerInstanceInterface(viewport)
+ViewportManipulatorControllerInstance::ViewportManipulatorControllerInstance(AzFramework::ViewportId viewport, ViewportManipulatorController* controller)
+ : AzFramework::MultiViewportControllerInstanceInterface(viewport, controller)
{
}
diff --git a/Code/Sandbox/Editor/ViewportManipulatorController.h b/Code/Sandbox/Editor/ViewportManipulatorController.h
index 03a823fa64..d5540229c4 100644
--- a/Code/Sandbox/Editor/ViewportManipulatorController.h
+++ b/Code/Sandbox/Editor/ViewportManipulatorController.h
@@ -19,11 +19,14 @@
namespace SandboxEditor
{
+ class ViewportManipulatorControllerInstance;
+ using ViewportManipulatorController = AzFramework::MultiViewportController;
+
class ViewportManipulatorControllerInstance final
- : public AzFramework::MultiViewportControllerInstanceInterface
+ : public AzFramework::MultiViewportControllerInstanceInterface
{
public:
- explicit ViewportManipulatorControllerInstance(AzFramework::ViewportId viewport);
+ explicit ViewportManipulatorControllerInstance(AzFramework::ViewportId viewport, ViewportManipulatorController* controller);
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
void ResetInputChannels() override;
@@ -40,6 +43,4 @@ namespace SandboxEditor
AZStd::unordered_map m_pendingDoubleClicks;
AZ::ScriptTimePoint m_curTime;
};
-
- using ViewportManipulatorController = AzFramework::MultiViewportController;
} //namespace SandboxEditor
diff --git a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp
index 30a7978c50..19b516b681 100644
--- a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp
+++ b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp
@@ -124,131 +124,29 @@ namespace AssetProcessor
NativeLegacyRCCompiler::NativeLegacyRCCompiler()
: m_resourceCompilerInitialized(false)
- , m_systemRoot()
- , m_rcExecutableFullPath()
, m_requestedQuit(false)
{
}
-
- bool NativeLegacyRCCompiler::Initialize(const QString& systemRoot, const QString& rcExecutableFullPath)
+
+ bool NativeLegacyRCCompiler::Initialize()
{
- // QFile::exists(normalizedPath)
- if (!QDir(systemRoot).exists())
- {
- AZ_TracePrintf(AssetProcessor::DebugChannel, QString("Cannot locate system root dir %1").arg(systemRoot).toUtf8().data());
- return false;
- }
-
- if (!AZ::IO::SystemFile::Exists(rcExecutableFullPath.toUtf8().data()))
- {
- AZ_TracePrintf(AssetProcessor::DebugChannel, QString("Invalid executable path '%1'").arg(rcExecutableFullPath).toUtf8().data());
- return false;
- }
- this->m_systemRoot.setPath(systemRoot);
- this->m_rcExecutableFullPath = rcExecutableFullPath;
this->m_resourceCompilerInitialized = true;
return true;
}
- bool NativeLegacyRCCompiler::Execute(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier,
- const QString& params, const QString& dest, const AssetBuilderSDK::JobCancelListener* jobCancelListener, Result& result) const
+ bool NativeLegacyRCCompiler::Execute(
+ [[maybe_unused]] const QString& inputFile,
+ [[maybe_unused]] const QString& watchFolder,
+ [[maybe_unused]] const QString& platformIdentifier,
+ [[maybe_unused]] const QString& params,
+ [[maybe_unused]] const QString& dest,
+ [[maybe_unused]] const AssetBuilderSDK::JobCancelListener* jobCancelListener,
+ [[maybe_unused]] Result& result) const
{
- if (!this->m_resourceCompilerInitialized)
- {
- result.m_exitCode = JobExitCode_RCCouldNotBeLaunched;
- result.m_crashed = false;
- AZ_Warning("RC Builder", false, "RC Compiler has not been initialized before use.");
- return false;
- }
+ // running RC.EXE is deprecated.
+ AZ_Error("RC Builder", false, "running RC.EXE is deprecated");
- // build the command line:
- QString commandString = NativeLegacyRCCompiler::BuildCommand(inputFile, watchFolder, platformIdentifier, params, dest);
-
- AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
-
- // while it might be tempting to set the executable in processLaunchInfo.m_processExecutableString, it turns out that RC.EXE
- // won't work if you do that because it assumes the first command line param is the exe name, which is not the case if you do it that way...
-
- QString formatter("\"%1\" %2");
- processLaunchInfo.m_commandlineParameters = QString(formatter).arg(m_rcExecutableFullPath).arg(commandString).toUtf8().data();
- processLaunchInfo.m_showWindow = false;
- processLaunchInfo.m_workingDirectory = m_systemRoot.absolutePath().toUtf8().data();
- processLaunchInfo.m_processPriority = AzFramework::ProcessPriority::PROCESSPRIORITY_IDLE;
-
- AZ_TracePrintf("RC Builder", "Executing RC.EXE: '%s' ...\n", processLaunchInfo.m_commandlineParameters.c_str());
- AZ_TracePrintf("Rc Builder", "Executing RC.EXE with working directory: '%s' ...\n", processLaunchInfo.m_workingDirectory.c_str());
-
- AzFramework::ProcessWatcher* watcher = AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT);
-
- if (!watcher)
- {
- result.m_exitCode = JobExitCode_RCCouldNotBeLaunched;
- result.m_crashed = false;
- AZ_Error("RC Builder", false, "RC failed to execute\n");
-
- return false;
- }
-
- QElapsedTimer ticker;
- ticker.start();
-
- // it created the process, wait for it to exit:
- bool finishedOK = false;
- {
- CommunicatorTracePrinter tracer(watcher->GetCommunicator(), "RC Builder"); // allow this to go out of scope...
- while ((!m_requestedQuit) && (!finishedOK))
- {
- AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(NativeLegacyRCCompiler::s_maxSleepTime));
-
- tracer.Pump();
-
- if (ticker.elapsed() > s_jobMaximumWaitTime || (jobCancelListener && jobCancelListener->IsCancelled()))
- {
- break;
- }
-
- AZ::u32 exitCode = 0;
- if (!watcher->IsProcessRunning(&exitCode))
- {
- finishedOK = true; // we either cant wait for it, or it finished.
- result.m_exitCode = exitCode;
- result.m_crashed = (exitCode == 100) || (exitCode == 101); // these indicate fatal errors.
- break;
- }
- }
- tracer.Pump(); // empty whats left if possible.
- }
- if (!finishedOK)
- {
- if (watcher->IsProcessRunning())
- {
- watcher->TerminateProcess(0xFFFFFFFF);
- }
-
- if (!this->m_requestedQuit)
- {
- if (jobCancelListener == nullptr || !jobCancelListener->IsCancelled())
- {
- AZ_Error("RC Builder", false, "RC failed to complete within the maximum allowed time and was terminated. please see %s/rc_log.log for details", result.m_outputDir.toUtf8().data());
- }
- else
- {
- AZ_TracePrintf("RC Builder", "RC was terminated. There was a request to cancel the job.\n");
- result.m_exitCode = JobExitCode_JobCancelled;
- }
- }
- else
- {
- AZ_Warning("RC Builder", false, "RC terminated because the application is shutting down.\n");
- result.m_exitCode = JobExitCode_JobCancelled;
- }
- result.m_crashed = false;
- }
- AZ_TracePrintf("RC Builder", "RC.EXE execution has ended\n");
-
- delete watcher;
-
- return finishedOK;
+ return false;
}
QString NativeLegacyRCCompiler::BuildCommand(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params, const QString& dest)
@@ -438,22 +336,7 @@ namespace AssetProcessor
bool InternalRecognizerBasedBuilder::Initialize(const RecognizerConfiguration& recognizerConfig)
{
InitializeAssetRecognizers(recognizerConfig.GetAssetRecognizerContainer());
-
- // Get the engine root since rc.exe will exist there and not in any external project folder
- QString systemRoot;
- QString rcFullPath;
-
- // Validate that the engine root contains the necessary rc.exe
- if (!FindRC(rcFullPath))
- {
- return false;
- }
- if (!m_rcCompiler->Initialize(systemRoot, rcFullPath))
- {
- AssetBuilderSDK::BuilderLog(m_internalRecognizerBuilderUuid, "Unable to find rc.exe from the engine root (%1).", rcFullPath.toUtf8().data());
- return false;
- }
- return true;
+ return m_rcCompiler->Initialize();
}
diff --git a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.h b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.h
index 06facc5eba..56c0091aee 100644
--- a/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.h
+++ b/Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.h
@@ -31,7 +31,7 @@ namespace AssetProcessor
};
virtual ~RCCompiler() = default;
- virtual bool Initialize(const QString& systemRoot, const QString& rcExecutableFullPath) = 0;
+ virtual bool Initialize() = 0;
virtual bool Execute(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params,
const QString& dest, const AssetBuilderSDK::JobCancelListener* jobCancelListener, Result& result) const = 0;
virtual void RequestQuit() = 0;
@@ -44,7 +44,7 @@ namespace AssetProcessor
public:
NativeLegacyRCCompiler();
- bool Initialize(const QString& systemRoot, const QString& rcExecutableFullPath) override;
+ bool Initialize() override;
bool Execute(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params, const QString& dest,
const AssetBuilderSDK::JobCancelListener* jobCancelListener, Result& result) const override;
static QString BuildCommand(const QString& inputFile, const QString& watchFolder, const QString& platformIdentifier, const QString& params, const QString& dest);
@@ -53,8 +53,6 @@ namespace AssetProcessor
static const int s_maxSleepTime;
static const unsigned int s_jobMaximumWaitTime;
bool m_resourceCompilerInitialized;
- QDir m_systemRoot;
- QString m_rcExecutableFullPath;
volatile bool m_requestedQuit;
};
diff --git a/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.cpp b/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.cpp
index 07d0a5b85d..86f02be330 100644
--- a/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.cpp
+++ b/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.cpp
@@ -43,19 +43,6 @@ TEST_F(RCBuilderTest, Shutdown_NormalShutdown_Requested)
}
-TEST_F(RCBuilderTest, Initialize_StandardInitialization_Fail)
-{
- MockRCCompiler* mockRC = new MockRCCompiler();
- TestInternalRecognizerBasedBuilder test(mockRC);
-
- MockRecognizerConfiguration configuration;
-
- mockRC->SetResultInitialize(false);
- bool initialization_result = test.Initialize(configuration);
- ASSERT_FALSE(initialization_result);
-}
-
-
TEST_F(RCBuilderTest, Initialize_StandardInitializationWithDuplicateAndInvalidRecognizers_Valid)
{
MockRCCompiler* mockRC = new MockRCCompiler();
diff --git a/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.h b/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.h
index 1e401aa3f0..379db316f9 100644
--- a/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.h
+++ b/Code/Tools/AssetProcessor/native/tests/resourcecompiler/RCBuilderTest.h
@@ -34,7 +34,7 @@ public:
{
}
- bool Initialize([[maybe_unused]] const QString& systemRoot, [[maybe_unused]] const QString& rcExecutableFullPath) override
+ bool Initialize() override
{
m_initialize++;
return m_initializeResult;
diff --git a/Code/Tools/AssetProcessor/native/unittests/MockApplicationManager.cpp b/Code/Tools/AssetProcessor/native/unittests/MockApplicationManager.cpp
index e918dbc678..9a93fe9a63 100644
--- a/Code/Tools/AssetProcessor/native/unittests/MockApplicationManager.cpp
+++ b/Code/Tools/AssetProcessor/native/unittests/MockApplicationManager.cpp
@@ -47,7 +47,7 @@ namespace AssetProcessor
{
}
- bool Initialize([[maybe_unused]] const QString& systemRoot, [[maybe_unused]] const QString& rcExecutableFullPath) override
+ bool Initialize() override
{
m_initialize++;
return m_initializeResult;
diff --git a/Code/Tools/ProjectManager/Resources/Android.svg b/Code/Tools/ProjectManager/Resources/Android.svg
new file mode 100644
index 0000000000..a4b610a3d6
--- /dev/null
+++ b/Code/Tools/ProjectManager/Resources/Android.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/Code/Tools/ProjectManager/Resources/Linux.svg b/Code/Tools/ProjectManager/Resources/Linux.svg
new file mode 100644
index 0000000000..843d60cd82
--- /dev/null
+++ b/Code/Tools/ProjectManager/Resources/Linux.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/Code/Tools/ProjectManager/Resources/Windows.svg b/Code/Tools/ProjectManager/Resources/Windows.svg
new file mode 100644
index 0000000000..46da6693a1
--- /dev/null
+++ b/Code/Tools/ProjectManager/Resources/Windows.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/Code/Tools/ProjectManager/Resources/iOS.svg b/Code/Tools/ProjectManager/Resources/iOS.svg
new file mode 100644
index 0000000000..871d36f657
--- /dev/null
+++ b/Code/Tools/ProjectManager/Resources/iOS.svg
@@ -0,0 +1,3 @@
+
diff --git a/Code/Tools/ProjectManager/Resources/macOS.svg b/Code/Tools/ProjectManager/Resources/macOS.svg
new file mode 100644
index 0000000000..4d433be6a3
--- /dev/null
+++ b/Code/Tools/ProjectManager/Resources/macOS.svg
@@ -0,0 +1,3 @@
+
diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp
index 6ceb443df8..6bb1e4959f 100644
--- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp
+++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp
@@ -21,8 +21,6 @@ namespace O3DE::ProjectManager
GemCatalog::GemCatalog(ProjectManagerWindow* window)
: ScreenWidget(window)
{
- ConnectSlotsAndSignals();
-
m_gemModel = new GemModel(this);
QVBoxLayout* vLayout = new QVBoxLayout();
@@ -56,36 +54,36 @@ namespace O3DE::ProjectManager
m_gemModel->AddGem(GemInfo("EMotion FX",
"O3DE Foundation",
"EMFX is a real-time character animation system. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
- (GemInfo::Android | GemInfo::iOS | GemInfo::Windows | GemInfo::Linux),
+ (GemInfo::Android | GemInfo::iOS | GemInfo::macOS | GemInfo::Windows | GemInfo::Linux),
true));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Atom",
"O3DE Foundation",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
- GemInfo::Android | GemInfo::Windows | GemInfo::Linux,
+ GemInfo::Android | GemInfo::Windows | GemInfo::Linux | GemInfo::macOS,
true));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("PhysX",
- "O3DE Foundation",
+ "O3DE London",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
- GemInfo::Android | GemInfo::Linux,
+ GemInfo::Android | GemInfo::Linux | GemInfo::macOS,
false));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Certificate Manager",
- "O3DE Foundation",
+ "O3DE Irvine",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
GemInfo::Windows,
false));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Cloud Gem Framework",
- "O3DE Foundation",
- "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
+ "O3DE Seattle",
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
GemInfo::iOS | GemInfo::Linux,
false));
m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Achievements",
"O3DE Foundation",
- "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
GemInfo::Android | GemInfo::Windows | GemInfo::Linux,
false));
}
diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h
index e5aa9c41f7..8c5040eb84 100644
--- a/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h
+++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemInfo.h
@@ -26,11 +26,12 @@ namespace O3DE::ProjectManager
public:
enum Platform
{
- Android = 0x0,
- iOS = 0x1,
- Linux = 0x2,
- macOS = 0x3,
- Windows = 0x4
+ Android = 1 << 0,
+ iOS = 1 << 1,
+ Linux = 1 << 2,
+ macOS = 1 << 3,
+ Windows = 1 << 4,
+ NumPlatforms = 5
};
Q_DECLARE_FLAGS(Platforms, Platform)
diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp
index 22e77ed40e..434a4aeef2 100644
--- a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp
+++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp
@@ -22,6 +22,18 @@ namespace O3DE::ProjectManager
: QStyledItemDelegate(parent)
, m_gemModel(gemModel)
{
+ AddPlatformIcon(GemInfo::Android, ":/Resources/Android.svg");
+ AddPlatformIcon(GemInfo::iOS, ":/Resources/iOS.svg");
+ AddPlatformIcon(GemInfo::Linux, ":/Resources/Linux.svg");
+ AddPlatformIcon(GemInfo::macOS, ":/Resources/macOS.svg");
+ AddPlatformIcon(GemInfo::Windows, ":/Resources/Windows.svg");
+ }
+
+ void GemItemDelegate::AddPlatformIcon(GemInfo::Platform platform, const QString& iconPath)
+ {
+ QPixmap pixmap(iconPath);
+ qreal aspectRatio = static_cast(pixmap.width()) / pixmap.height();
+ m_platformIcons.insert(platform, QIcon(iconPath).pixmap(s_platformIconSize * aspectRatio, s_platformIconSize));
}
void GemItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const
@@ -87,7 +99,7 @@ namespace O3DE::ProjectManager
painter->drawText(gemCreatorRect, Qt::TextSingleLine, gemCreator);
// Gem summary
- const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_itemMargins.right() * 4, contentRect.height());
+ const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_buttonWidth - s_itemMargins.right() * 4, contentRect.height());
const QRect summaryRect = QRect(/*topLeft=*/QPoint(contentRect.left() + s_summaryStartX, contentRect.top()), summarySize);
painter->setFont(standardFont);
@@ -96,6 +108,10 @@ namespace O3DE::ProjectManager
const QString summary = m_gemModel->GetSummary(modelIndex);
painter->drawText(summaryRect, Qt::AlignLeft | Qt::TextWordWrap, summary);
+
+ DrawButton(painter, contentRect, modelIndex);
+ DrawPlatformIcons(painter, contentRect, modelIndex);
+
painter->restore();
}
@@ -105,7 +121,7 @@ namespace O3DE::ProjectManager
initStyleOption(&options, modelIndex);
int marginsHorizontal = s_itemMargins.left() + s_itemMargins.right() + s_contentMargins.left() + s_contentMargins.right();
- return QSize(marginsHorizontal + s_summaryStartX, s_height);
+ return QSize(marginsHorizontal + s_buttonWidth + s_summaryStartX, s_height);
}
bool GemItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& modelIndex)
@@ -132,4 +148,85 @@ namespace O3DE::ProjectManager
font.setPixelSize(fontSize);
return QFontMetrics(font).boundingRect(text);
}
+
+ QRect GemItemDelegate::CalcButtonRect(const QRect& contentRect) const
+ {
+ const QPoint topLeft = QPoint(contentRect.right() - s_buttonWidth - s_itemMargins.right(), contentRect.top() + contentRect.height() / 2 - s_buttonHeight / 2);
+ const QSize size = QSize(s_buttonWidth, s_buttonHeight);
+ return QRect(topLeft, size);
+ }
+
+ void GemItemDelegate::DrawPlatformIcons(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const
+ {
+ const GemInfo::Platforms platforms = m_gemModel->GetPlatforms(modelIndex);
+ int startX = 0;
+
+ // Iterate and draw the platforms in the order they are defined in the enum.
+ for (int i = 0; i < GemInfo::NumPlatforms; ++i)
+ {
+ // Check if the platform is supported by the given gem.
+ const GemInfo::Platform platform = static_cast(1 << i);
+ if (platforms & platform)
+ {
+ // Get the icon for the platform and draw it.
+ const auto iterator = m_platformIcons.find(platform);
+ if (iterator != m_platformIcons.end())
+ {
+ const QPixmap& pixmap = iterator.value();
+ painter->drawPixmap(contentRect.left() + startX, contentRect.bottom() - s_platformIconSize, pixmap);
+ qreal aspectRatio = static_cast(pixmap.width()) / pixmap.height();
+ startX += s_platformIconSize * aspectRatio + s_platformIconSize / 2.5;
+ }
+ }
+ }
+ }
+
+ void GemItemDelegate::DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const
+ {
+ painter->save();
+ const QRect buttonRect = CalcButtonRect(contentRect);
+ QPoint circleCenter;
+ QString buttonText;
+
+ const bool isAdded = m_gemModel->IsAdded(modelIndex);
+ if (isAdded)
+ {
+ painter->setBrush(m_buttonEnabledColor);
+ painter->setPen(m_buttonEnabledColor);
+
+ circleCenter = buttonRect.center() + QPoint(buttonRect.width() / 2 - s_buttonBorderRadius, 1);
+ buttonText = "Added";
+ }
+ else
+ {
+ circleCenter = buttonRect.center() + QPoint(-buttonRect.width() / 2 + s_buttonBorderRadius + 1, 1);
+ buttonText = "Get";
+ }
+
+ // Rounded rect
+ painter->drawRoundedRect(buttonRect, s_buttonBorderRadius, s_buttonBorderRadius);
+
+ // Text
+ QFont font;
+ QRect textRect = GetTextRect(font, buttonText, s_buttonFontSize);
+ if (isAdded)
+ {
+ textRect = QRect(buttonRect.left(), buttonRect.top(), buttonRect.width() - s_buttonCircleRadius * 2.0, buttonRect.height());
+ }
+ else
+ {
+ textRect = QRect(buttonRect.left() + s_buttonCircleRadius * 2.0, buttonRect.top(), buttonRect.width() - s_buttonCircleRadius * 2.0, buttonRect.height());
+ }
+
+ font.setPixelSize(s_buttonFontSize);
+ painter->setFont(font);
+ painter->setPen(m_textColor);
+ painter->drawText(textRect, Qt::AlignCenter, buttonText);
+
+ // Circle
+ painter->setBrush(m_textColor);
+ painter->drawEllipse(circleCenter, s_buttonCircleRadius, s_buttonCircleRadius);
+
+ painter->restore();
+ }
} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h
index 3528d07d78..ee0392e188 100644
--- a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h
+++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h
@@ -16,6 +16,7 @@
#include
#include "GemInfo.h"
#include "GemModel.h"
+#include
#endif
QT_FORWARD_DECLARE_CLASS(QEvent)
@@ -38,6 +39,9 @@ namespace O3DE::ProjectManager
private:
void CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const;
QRect GetTextRect(QFont& font, const QString& text, qreal fontSize) const;
+ QRect CalcButtonRect(const QRect& contentRect) const;
+ void DrawPlatformIcons(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const;
+ void DrawButton(QPainter* painter, const QRect& contentRect, const QModelIndex& modelIndex) const;
GemModel* m_gemModel = nullptr;
@@ -47,9 +51,10 @@ namespace O3DE::ProjectManager
const QColor m_backgroundColor = QColor("#333333"); // Outside of the actual gem item
const QColor m_itemBackgroundColor = QColor("#404040"); // Background color of the gem item
const QColor m_borderColor = QColor("#1E70EB");
+ const QColor m_buttonEnabledColor = QColor("#00B931");
// Item
- inline constexpr static int s_height = 140; // Gem item total height
+ inline constexpr static int s_height = 135; // Gem item total height
inline constexpr static qreal s_gemNameFontSize = 16.0;
inline constexpr static qreal s_fontSize = 15.0;
inline constexpr static int s_summaryStartX = 200;
@@ -58,5 +63,17 @@ namespace O3DE::ProjectManager
inline constexpr static QMargins s_itemMargins = QMargins(/*left=*/20, /*top=*/10, /*right=*/20, /*bottom=*/10); // Item border distances
inline constexpr static QMargins s_contentMargins = QMargins(/*left=*/15, /*top=*/12, /*right=*/12, /*bottom=*/12); // Distances of the elements within an item to the item borders
inline constexpr static int s_borderWidth = 4;
+
+ // Button
+ inline constexpr static int s_buttonWidth = 70;
+ inline constexpr static int s_buttonHeight = 24;
+ inline constexpr static int s_buttonBorderRadius = 12;
+ inline constexpr static int s_buttonCircleRadius = s_buttonBorderRadius - 3;
+ inline constexpr static qreal s_buttonFontSize = 12.0;
+
+ // Platform icons
+ void AddPlatformIcon(GemInfo::Platform platform, const QString& iconPath);
+ inline constexpr static int s_platformIconSize = 16;
+ QHash m_platformIcons;
};
} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp
index 89e629cf5f..27905fd4d2 100644
--- a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp
+++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp
@@ -55,7 +55,7 @@ namespace O3DE::ProjectManager
return modelIndex.data(RoleCreator).toString();
}
- int GemModel::GetPlatforms(const QModelIndex& modelIndex) const
+ GemInfo::Platforms GemModel::GetPlatforms(const QModelIndex& modelIndex) const
{
return static_cast(modelIndex.data(RolePlatforms).toInt());
}
diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h
index 33ae02dc8a..4ce9de32fc 100644
--- a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h
+++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h
@@ -34,7 +34,7 @@ namespace O3DE::ProjectManager
QString GetName(const QModelIndex& modelIndex) const;
QString GetCreator(const QModelIndex& modelIndex) const;
- int GetPlatforms(const QModelIndex& modelIndex) const;
+ GemInfo::Platforms GetPlatforms(const QModelIndex& modelIndex) const;
QString GetSummary(const QModelIndex& modelIndex) const;
bool IsAdded(const QModelIndex& modelIndex) const;
diff --git a/Code/Tools/ProjectManager/project_manager.qrc b/Code/Tools/ProjectManager/project_manager.qrc
index 408398584b..6509a9f940 100644
--- a/Code/Tools/ProjectManager/project_manager.qrc
+++ b/Code/Tools/ProjectManager/project_manager.qrc
@@ -1,8 +1,13 @@
-
-
+
+
Resources/ProjectManager.qss
Resources/Add.svg
Resources/Select_Folder.svg
Resources/o3de_editor.ico
+ Resources/Windows.svg
+ Resources/Android.svg
+ Resources/iOS.svg
+ Resources/Linux.svg
+ Resources/macOS.svg
-
\ No newline at end of file
+
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp
index dd92e6bb8b..0ee25195bc 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp
@@ -151,7 +151,7 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast(context);
if (serializeContext)
{
- serializeContext->Class()->Version(2); // [LYN-2281] Skinned mesh loading fixes
+ serializeContext->Class()->Version(3); // [LYN-3349] Rolling back rotation change
}
}
diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp
index 60bf487de3..27bac09a63 100644
--- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp
@@ -306,7 +306,7 @@ namespace AZ
for (const RPI::ViewPtr& view : packet.m_views)
{
if (m_renderPipelineIdsForPersistentView.find(view.get()) != m_renderPipelineIdsForPersistentView.end() &&
- (view->GetUsageFlags() & RPI::View::UsageCamera))
+ (RHI::CheckBitsAny(view->GetUsageFlags(), RPI::View::UsageCamera | RPI::View::UsageReflectiveCubeMap)))
{
RPI::ShaderResourceGroup* viewSrg = view->GetShaderResourceGroup().get();
diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.cpp b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.cpp
index f56a753fb6..b22f4b5861 100644
--- a/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.cpp
@@ -69,9 +69,8 @@ namespace AZ
if (m_shouldUpdatePassParameters)
{
- auto* passSystem = AZ::RPI::PassSystemInterface::Get();
- UpdateEyeAdaptationPass(passSystem);
- UpdateLuminanceHeatmap(passSystem);
+ UpdateEyeAdaptationPass();
+ UpdateLuminanceHeatmap();
m_shouldUpdatePassParameters = false;
}
@@ -140,7 +139,8 @@ namespace AZ
if (m_heatmapEnabled != value)
{
m_heatmapEnabled = value;
- m_shouldUpdatePassParameters = true;
+ // Update immediately so that the ExposureControlSettings can just be turned off and killed without having to wait for another Simulate() call
+ UpdateLuminanceHeatmap();
}
}
@@ -198,8 +198,10 @@ namespace AZ
}
}
- void ExposureControlSettings::UpdateEyeAdaptationPass(RPI::PassSystemInterface* passSystem)
+ void ExposureControlSettings::UpdateEyeAdaptationPass()
{
+ auto* passSystem = AZ::RPI::PassSystemInterface::Get();
+
// [GFX-TODO][ATOM-13224] Remove UpdateLuminanceHeatmap and UpdateEyeAdaptationPass
auto passTemplateName = m_eyeAdaptationPassTemplateNameId;
@@ -220,8 +222,10 @@ namespace AZ
}
}
- void ExposureControlSettings::UpdateLuminanceHeatmap(RPI::PassSystemInterface* passSystem)
+ void ExposureControlSettings::UpdateLuminanceHeatmap()
{
+ auto* passSystem = AZ::RPI::PassSystemInterface::Get();
+
// [GFX-TODO][ATOM-13194] Support multiple views for the luminance heatmap
// [GFX-TODO][ATOM-13224] Remove UpdateLuminanceHeatmap and UpdateEyeAdaptationPass
const RPI::Ptr luminanceHeatmap = passSystem->GetRootPass()->FindPassByNameRecursive(m_luminanceHeatmapNameId);
diff --git a/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.h b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.h
index ebf5a1fe01..566f60dd28 100644
--- a/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.h
+++ b/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.h
@@ -84,8 +84,8 @@ namespace AZ
void UpdateExposureControlRelatedPassParameters();
- void UpdateLuminanceHeatmap(RPI::PassSystemInterface* passSystem);
- void UpdateEyeAdaptationPass(RPI::PassSystemInterface* passSystem);
+ void UpdateLuminanceHeatmap();
+ void UpdateEyeAdaptationPass();
PostProcessSettings* m_parentSettings = nullptr;
bool m_shouldUpdatePassParameters = true;
diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
index f31d130ee6..ff2a9cdf98 100644
--- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
+++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
@@ -99,6 +99,9 @@ namespace AtomToolsFramework
AZStd::optional ViewportScreenToWorldRay(
const AzFramework::ScreenPoint& screenPosition) override;
+ //! Set interface for providing viewport specific settings (e.g. snapping properties).
+ void SetViewportSettings(AzToolsFramework::ViewportInteraction::ViewportSettings* viewportSettings);
+
// AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Handler ...
void BeginCursorCapture() override;
void EndCursorCapture() override;
@@ -156,5 +159,7 @@ namespace AtomToolsFramework
bool m_capturingCursor = false;
// The last known position of the mouse cursor, if one is available.
AZStd::optional m_lastCursorPosition;
+ // The viewport settings (e.g. grid snapping, grid size) for this viewport.
+ const AzToolsFramework::ViewportInteraction::ViewportSettings* m_viewportSettings = nullptr;
};
} //namespace AtomToolsFramework
diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
index 94038d1977..961de670e8 100644
--- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
+++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
@@ -384,27 +384,32 @@ namespace AtomToolsFramework
bool RenderViewportWidget::GridSnappingEnabled()
{
- return false;
+ return m_viewportSettings ? m_viewportSettings->GridSnappingEnabled() : false;
}
float RenderViewportWidget::GridSize()
{
- return 0.0f;
+ return m_viewportSettings ? m_viewportSettings->GridSize() : 0.0f;
}
bool RenderViewportWidget::ShowGrid()
{
- return false;
+ return m_viewportSettings ? m_viewportSettings->ShowGrid() : false;
}
bool RenderViewportWidget::AngleSnappingEnabled()
{
- return false;
+ return m_viewportSettings ? m_viewportSettings->AngleSnappingEnabled() : false;
}
float RenderViewportWidget::AngleStep()
{
- return 0.0f;
+ return m_viewportSettings ? m_viewportSettings->AngleStep() : 0.0f;
+ }
+
+ void RenderViewportWidget::SetViewportSettings(AzToolsFramework::ViewportInteraction::ViewportSettings* viewportSettings)
+ {
+ m_viewportSettings = viewportSettings;
}
AzFramework::ScreenPoint RenderViewportWidget::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorBrowserInteractions.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorBrowserInteractions.cpp
index 92e02d5b42..9b79bcb6d9 100644
--- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorBrowserInteractions.cpp
+++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorBrowserInteractions.cpp
@@ -31,6 +31,7 @@
#include
#include
+#include
#include
#include
@@ -248,6 +249,24 @@ namespace MaterialEditor
}
}
});
+
+ menu->addSeparator();
+
+ QAction* createMaterialAction = menu->addAction(QObject::tr("Create Material..."));
+ QObject::connect(createMaterialAction, &QAction::triggered, caller, [caller, entry]()
+ {
+ CreateMaterialDialog createDialog(entry->GetFullPath().c_str(), caller);
+ createDialog.adjustSize();
+
+ if (createDialog.exec() == QDialog::Accepted &&
+ !createDialog.m_materialFileInfo.absoluteFilePath().isEmpty() &&
+ !createDialog.m_materialTypeFileInfo.absoluteFilePath().isEmpty())
+ {
+ MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::CreateDocumentFromFile,
+ createDialog.m_materialTypeFileInfo.absoluteFilePath().toUtf8().constData(),
+ createDialog.m_materialFileInfo.absoluteFilePath().toUtf8().constData());
+ }
+ });
}
void MaterialEditorBrowserInteractions::AddPerforceMenuActions([[maybe_unused]] QWidget* caller, QMenu* menu, const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ExposureControl/ExposureControlComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ExposureControl/ExposureControlComponentController.cpp
index 3b73c65f96..967db514c6 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ExposureControl/ExposureControlComponentController.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/ExposureControl/ExposureControlComponentController.cpp
@@ -88,6 +88,9 @@ namespace AZ
{
ExposureControlRequestBus::Handler::BusDisconnect(m_entityId);
+ m_configuration.SetHeatmapEnabled(false);
+ OnConfigChanged();
+
if (m_postProcessInterface)
{
m_postProcessInterface->RemoveExposureControlSettingsInterface();
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp
index 4e1a3dc06e..38660fce02 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp
+++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp
@@ -543,7 +543,7 @@ namespace EditorPythonBindings
{
if (!oldPathSet.contains(thisStr))
{
- pathAppend.append(AZStd::string::format("sys.path.append('%s')\n", thisStr.c_str()));
+ pathAppend.append(AZStd::string::format("sys.path.append(r'%s')\n", thisStr.c_str()));
appended = true;
}
}
diff --git a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake
index 4056242a47..620995a85b 100644
--- a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake
+++ b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake
@@ -14,7 +14,7 @@ ly_associate_package(PACKAGE_NAME zlib-1.2.8-rev2-multiplatform TARG
ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform TARGETS ilmbase PACKAGE_HASH 97547fdf1fbc4d81b8ccf382261f8c25514ed3b3c4f8fd493f0a4fa873bba348)
ly_associate_package(PACKAGE_NAME hdf5-1.0.11-rev2-multiplatform TARGETS hdf5 PACKAGE_HASH 11d5e04df8a93f8c52a5684a4cacbf0d9003056360983ce34f8d7b601082c6bd)
ly_associate_package(PACKAGE_NAME alembic-1.7.11-rev3-multiplatform TARGETS alembic PACKAGE_HASH ba7a7d4943dd752f5a662374f6c48b93493df1d8e2c5f6a8d101f3b50700dd25)
-ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev8-multiplatform TARGETS assimplib PACKAGE_HASH 21dce424eccf5a2626ff0841e72092fa4ff9407a64b851e5eed9895926ce309d)
+ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev7-multiplatform TARGETS assimplib PACKAGE_HASH def855c89d8210db3040f1cb6ec837141ab9b8e74c158eae7c03d50160fcf30b)
ly_associate_package(PACKAGE_NAME squish-ccr-20150601-rev3-multiplatform TARGETS squish-ccr PACKAGE_HASH c878c6c0c705e78403c397d03f5aa7bc87e5978298710e14d09c9daf951a83b3)
ly_associate_package(PACKAGE_NAME ASTCEncoder-2017_11_14-rev2-multiplatform TARGETS ASTCEncoder PACKAGE_HASH c240ffc12083ee39a5ce9dc241de44d116e513e1e3e4cc1d05305e7aa3bdc326)
ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf)
diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake
index e564d64fc3..8636715c39 100644
--- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake
+++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake
@@ -14,7 +14,7 @@ ly_associate_package(PACKAGE_NAME zlib-1.2.8-rev2-multiplatform
ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform TARGETS ilmbase PACKAGE_HASH 97547fdf1fbc4d81b8ccf382261f8c25514ed3b3c4f8fd493f0a4fa873bba348)
ly_associate_package(PACKAGE_NAME hdf5-1.0.11-rev2-multiplatform TARGETS hdf5 PACKAGE_HASH 11d5e04df8a93f8c52a5684a4cacbf0d9003056360983ce34f8d7b601082c6bd)
ly_associate_package(PACKAGE_NAME alembic-1.7.11-rev3-multiplatform TARGETS alembic PACKAGE_HASH ba7a7d4943dd752f5a662374f6c48b93493df1d8e2c5f6a8d101f3b50700dd25)
-ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev8-multiplatform TARGETS assimplib PACKAGE_HASH 21dce424eccf5a2626ff0841e72092fa4ff9407a64b851e5eed9895926ce309d)
+ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev7-multiplatform TARGETS assimplib PACKAGE_HASH def855c89d8210db3040f1cb6ec837141ab9b8e74c158eae7c03d50160fcf30b)
ly_associate_package(PACKAGE_NAME squish-ccr-20150601-rev3-multiplatform TARGETS squish-ccr PACKAGE_HASH c878c6c0c705e78403c397d03f5aa7bc87e5978298710e14d09c9daf951a83b3)
ly_associate_package(PACKAGE_NAME ASTCEncoder-2017_11_14-rev2-multiplatform TARGETS ASTCEncoder PACKAGE_HASH c240ffc12083ee39a5ce9dc241de44d116e513e1e3e4cc1d05305e7aa3bdc326)
ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf)
diff --git a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake
index 939948d501..bdc93d9a0e 100644
--- a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake
+++ b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake
@@ -14,7 +14,7 @@ ly_associate_package(PACKAGE_NAME zlib-1.2.8-rev2-multiplatform
ly_associate_package(PACKAGE_NAME ilmbase-2.3.0-rev4-multiplatform TARGETS ilmbase PACKAGE_HASH 97547fdf1fbc4d81b8ccf382261f8c25514ed3b3c4f8fd493f0a4fa873bba348)
ly_associate_package(PACKAGE_NAME hdf5-1.0.11-rev2-multiplatform TARGETS hdf5 PACKAGE_HASH 11d5e04df8a93f8c52a5684a4cacbf0d9003056360983ce34f8d7b601082c6bd)
ly_associate_package(PACKAGE_NAME alembic-1.7.11-rev3-multiplatform TARGETS alembic PACKAGE_HASH ba7a7d4943dd752f5a662374f6c48b93493df1d8e2c5f6a8d101f3b50700dd25)
-ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev8-multiplatform TARGETS assimplib PACKAGE_HASH 21dce424eccf5a2626ff0841e72092fa4ff9407a64b851e5eed9895926ce309d)
+ly_associate_package(PACKAGE_NAME assimp-5.0.1-rev7-multiplatform TARGETS assimplib PACKAGE_HASH def855c89d8210db3040f1cb6ec837141ab9b8e74c158eae7c03d50160fcf30b)
ly_associate_package(PACKAGE_NAME squish-ccr-20150601-rev3-multiplatform TARGETS squish-ccr PACKAGE_HASH c878c6c0c705e78403c397d03f5aa7bc87e5978298710e14d09c9daf951a83b3)
ly_associate_package(PACKAGE_NAME ASTCEncoder-2017_11_14-rev2-multiplatform TARGETS ASTCEncoder PACKAGE_HASH c240ffc12083ee39a5ce9dc241de44d116e513e1e3e4cc1d05305e7aa3bdc326)
ly_associate_package(PACKAGE_NAME md5-2.0-multiplatform TARGETS md5 PACKAGE_HASH 29e52ad22c78051551f78a40c2709594f0378762ae03b417adca3f4b700affdf)
diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake
index 25fddb90d0..4f6565edc7 100644
--- a/cmake/Packaging.cmake
+++ b/cmake/Packaging.cmake
@@ -13,7 +13,13 @@ if(NOT PAL_TRAIT_BUILD_CPACK_SUPPORTED)
return()
endif()
-set(CPACK_GENERATOR "ZIP")
+ly_get_absolute_pal_filename(pal_dir ${CMAKE_SOURCE_DIR}/cmake/Platform/${PAL_HOST_PLATFORM_NAME})
+include(${pal_dir}/Packaging_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake)
+
+# if we get here and the generator hasn't been set, then a non fatal error occurred disabling packaging support
+if(NOT CPACK_GENERATOR)
+ return()
+endif()
set(CPACK_PACKAGE_VENDOR "${PROJECT_NAME}")
set(CPACK_PACKAGE_VERSION "${LY_VERSION_STRING}")
@@ -27,6 +33,8 @@ set(DEFAULT_LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_LICENSE ${DEFAULT_LICENSE_FILE})
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}/${CPACK_PACKAGE_VERSION}")
+
# IMPORTANT: required to be included AFTER setting all property overrides
include(CPack REQUIRED)
diff --git a/cmake/Platform/Windows/PackagingTemplate.wxs.in b/cmake/Platform/Windows/PackagingTemplate.wxs.in
new file mode 100644
index 0000000000..3e5db03ec2
--- /dev/null
+++ b/cmake/Platform/Windows/PackagingTemplate.wxs.in
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ProductIcon.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cmake/Platform/Windows/Packaging_windows.cmake b/cmake/Platform/Windows/Packaging_windows.cmake
new file mode 100644
index 0000000000..8aa6f2386d
--- /dev/null
+++ b/cmake/Platform/Windows/Packaging_windows.cmake
@@ -0,0 +1,92 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+set(LY_WIX_PATH "" CACHE PATH "Path to the WiX install path")
+
+if(LY_WIX_PATH)
+ file(TO_CMAKE_PATH ${LY_QTIFW_PATH} CPACK_WIX_ROOT)
+elseif(DEFINED ENV{WIX})
+ file(TO_CMAKE_PATH $ENV{WIX} CPACK_WIX_ROOT)
+endif()
+
+if(CPACK_WIX_ROOT)
+ if(NOT EXISTS ${CPACK_WIX_ROOT})
+ message(FATAL_ERROR "Invalid path supplied for LY_WIX_PATH argument or WIX environment variable")
+ endif()
+else()
+ # early out as no path to WiX has been supplied effectively disabling support
+ return()
+endif()
+
+set(CPACK_GENERATOR "WIX")
+
+# CPack will generate the WiX product/upgrade GUIDs further down the chain if they weren't supplied
+# however, they are unique for each run. instead, let's do the auto generation here and add it to
+# the cache for run persistence. an additional cache file will be used to store the information on
+# the original generation so we still have the ability to detect if they are still being used.
+set(_guid_cache_file "${CMAKE_BINARY_DIR}/installer/wix_guid_cache.cmake")
+if(NOT EXISTS ${_guid_cache_file})
+ set(_wix_guid_namespace "6D43F57A-2917-4AD9-B758-1F13CDB08593")
+
+ # based the ISO-8601 standard (YYYY-MM-DDTHH-mm-ssTZD) e.g., 20210506145533
+ string(TIMESTAMP _guid_gen_timestamp "%Y%m%d%H%M%S")
+
+ file(WRITE ${_guid_cache_file} "set(_wix_guid_gen_timestamp ${_guid_gen_timestamp})\n")
+
+ string(UUID _default_product_guid
+ NAMESPACE ${_wix_guid_namespace}
+ NAME "ProductID_${_guid_gen_timestamp}"
+ TYPE SHA1
+ UPPER
+ )
+ file(APPEND ${_guid_cache_file} "set(_wix_default_product_guid ${_default_product_guid})\n")
+
+ string(UUID _default_upgrade_guid
+ NAMESPACE ${_wix_guid_namespace}
+ NAME "UpgradeCode_${_guid_gen_timestamp}"
+ TYPE SHA1
+ UPPER
+ )
+ file(APPEND ${_guid_cache_file} "set(_wix_default_upgrade_guid ${_default_upgrade_guid})\n")
+endif()
+include(${_guid_cache_file})
+
+set(LY_WIX_PRODUCT_GUID "${_wix_default_product_guid}" CACHE STRING "GUID for the Product ID field. Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
+set(LY_WIX_UPGRADE_GUID "${_wix_default_upgrade_guid}" CACHE STRING "GUID for the Upgrade Code field. Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
+
+set(_uses_default_product_guid FALSE)
+if(NOT LY_WIX_PRODUCT_GUID OR LY_WIX_PRODUCT_GUID STREQUAL ${_wix_default_product_guid})
+ set(_uses_default_product_guid TRUE)
+ set(LY_WIX_PRODUCT_GUID ${_wix_default_product_guid})
+endif()
+
+set(_uses_default_upgrade_guid FALSE)
+if(NOT LY_WIX_UPGRADE_GUID OR LY_WIX_UPGRADE_GUID STREQUAL ${_wix_default_upgrade_guid})
+ set(_uses_default_upgrade_guid TRUE)
+ set(LY_WIX_UPGRADE_GUID ${_wix_default_upgrade_guid})
+endif()
+
+if(_uses_default_product_guid OR _uses_default_upgrade_guid)
+ message(STATUS "One or both WiX GUIDs were auto generated. It is recommended you supply your own GUIDs through LY_WIX_PRODUCT_GUID and LY_WIX_UPGRADE_GUID.")
+
+ if(_uses_default_product_guid)
+ message(STATUS "-> Default LY_WIX_PRODUCT_GUID = ${LY_WIX_PRODUCT_GUID}")
+ endif()
+
+ if(_uses_default_upgrade_guid)
+ message(STATUS "-> Default LY_WIX_UPGRADE_GUID = ${LY_WIX_UPGRADE_GUID}")
+ endif()
+endif()
+
+set(CPACK_WIX_PRODUCT_GUID ${LY_WIX_PRODUCT_GUID})
+set(CPACK_WIX_UPGRADE_GUID ${LY_WIX_UPGRADE_GUID})
+
+set(CPACK_WIX_TEMPLATE "${CMAKE_SOURCE_DIR}/cmake/Platform/Windows/PackagingTemplate.wxs.in")
diff --git a/cmake/Platform/Windows/platform_windows_files.cmake b/cmake/Platform/Windows/platform_windows_files.cmake
index bf9cb05d17..2fc869b43e 100644
--- a/cmake/Platform/Windows/platform_windows_files.cmake
+++ b/cmake/Platform/Windows/platform_windows_files.cmake
@@ -23,4 +23,6 @@ set(FILES
PAL_windows.cmake
PALDetection_windows.cmake
Install_windows.cmake
+ Packaging_windows.cmake
+ PackagingTemplate.wxs.in
)
diff --git a/scripts/build/Platform/Android/build_config.json b/scripts/build/Platform/Android/build_config.json
index 07dc363296..699ccdf20a 100644
--- a/scripts/build/Platform/Android/build_config.json
+++ b/scripts/build/Platform/Android/build_config.json
@@ -27,7 +27,8 @@
},
"debug": {
"TAGS":[
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
@@ -67,7 +68,8 @@
},
"profile_nounity": {
"TAGS":[
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
@@ -83,7 +85,9 @@
"asset_profile": {
"TAGS":[
"default",
- "weekly-build-metrics"
+ "weekly-build-metrics",
+ "nightly-incremental",
+ "nightly-clean"
],
"COMMAND":"../Windows/build_asset_windows.cmd",
"PARAMETERS": {
@@ -98,21 +102,10 @@
"ASSET_PROCESSOR_PLATFORMS":"es3"
}
},
- "asset_clean_profile": {
- "TAGS":[
- "nightly"
- ],
- "PIPELINE_ENV": {
- "CLEAN_ASSETS": "1"
- },
- "steps": [
- "clean",
- "asset_profile"
- ]
- },
"release": {
"TAGS":[
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
@@ -127,7 +120,8 @@
},
"monolithic_release": {
"TAGS":[
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
diff --git a/scripts/build/Platform/Android/pipeline.json b/scripts/build/Platform/Android/pipeline.json
index a4a2700af0..ed10e7022d 100644
--- a/scripts/build/Platform/Android/pipeline.json
+++ b/scripts/build/Platform/Android/pipeline.json
@@ -13,6 +13,9 @@
},
"packaging": {
"CLEAN_WORKSPACE": true
+ },
+ "nightly-clean": {
+ "CLEAN_WORKSPACE": true
}
}
}
\ No newline at end of file
diff --git a/scripts/build/Platform/Linux/build_config.json b/scripts/build/Platform/Linux/build_config.json
index 426bf1d7ce..4ae4c4ec0b 100644
--- a/scripts/build/Platform/Linux/build_config.json
+++ b/scripts/build/Platform/Linux/build_config.json
@@ -29,7 +29,8 @@
},
"debug": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
@@ -43,9 +44,10 @@
},
"profile": {
"TAGS": [
- "nightly",
- "daily-pipeline-metrics",
- "weekly-build-metrics"
+ "nightly-incremental",
+ "nightly-clean",
+ "daily-pipeline-metrics",
+ "weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
"PARAMETERS": {
@@ -98,7 +100,9 @@
},
"asset_profile": {
"TAGS": [
- "weekly-build-metrics"
+ "weekly-build-metrics",
+ "nightly-incremental",
+ "nightly-clean"
],
"COMMAND": "build_asset_linux.sh",
"PARAMETERS": {
@@ -126,21 +130,10 @@
"ASSET_PROCESSOR_PLATFORMS": "pc,server"
}
},
- "asset_clean_profile": {
- "TAGS": [
- "nightly"
- ],
- "PIPELINE_ENV": {
- "CLEAN_ASSETS": "1"
- },
- "steps": [
- "clean",
- "asset_profile"
- ]
- },
"periodic_test_profile": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_test_linux.sh",
@@ -155,7 +148,8 @@
},
"benchmark_test_profile": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_test_linux.sh",
@@ -170,7 +164,8 @@
},
"release": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
@@ -184,7 +179,8 @@
},
"monolithic_release": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
diff --git a/scripts/build/Platform/Linux/pipeline.json b/scripts/build/Platform/Linux/pipeline.json
index ec06dff5bf..d964a693ce 100644
--- a/scripts/build/Platform/Linux/pipeline.json
+++ b/scripts/build/Platform/Linux/pipeline.json
@@ -12,6 +12,9 @@
},
"packaging": {
"CLEAN_WORKSPACE": true
+ },
+ "nightly-clean": {
+ "CLEAN_WORKSPACE": true
}
}
}
\ No newline at end of file
diff --git a/scripts/build/Platform/Mac/build_config.json b/scripts/build/Platform/Mac/build_config.json
index f816117331..1e6ca79d8e 100644
--- a/scripts/build/Platform/Mac/build_config.json
+++ b/scripts/build/Platform/Mac/build_config.json
@@ -9,7 +9,8 @@
},
"profile_pipe": {
"TAGS": [
- "nightly"
+ "nightly-incremental",
+ "nightly-clean"
],
"steps": [
"profile",
@@ -28,7 +29,8 @@
},
"debug": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
@@ -56,7 +58,8 @@
},
"profile_nounity": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
@@ -70,7 +73,9 @@
},
"asset_profile": {
"TAGS": [
- "weekly-build-metrics"
+ "weekly-build-metrics",
+ "nightly-incremental",
+ "nightly-clean"
],
"COMMAND": "build_asset_mac.sh",
"PARAMETERS": {
@@ -84,21 +89,10 @@
"ASSET_PROCESSOR_PLATFORMS": "osx_gl"
}
},
- "asset_clean_profile": {
- "TAGS": [
- "nightly"
- ],
- "PIPELINE_ENV": {
- "CLEAN_ASSETS": "1"
- },
- "steps": [
- "clean",
- "asset_profile"
- ]
- },
"periodic_test_profile": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_test_mac.sh",
@@ -113,7 +107,8 @@
},
"benchmark_test_profile": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_test_mac.sh",
@@ -128,7 +123,8 @@
},
"release": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
@@ -142,7 +138,8 @@
},
"monolithic_release": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
diff --git a/scripts/build/Platform/Mac/pipeline.json b/scripts/build/Platform/Mac/pipeline.json
index bb94f33d70..58f62b421d 100644
--- a/scripts/build/Platform/Mac/pipeline.json
+++ b/scripts/build/Platform/Mac/pipeline.json
@@ -12,6 +12,9 @@
},
"packaging": {
"CLEAN_WORKSPACE": true
+ },
+ "nightly-clean": {
+ "CLEAN_WORKSPACE": true
}
}
}
\ No newline at end of file
diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json
index bd10c9e59a..263539cd4a 100644
--- a/scripts/build/Platform/Windows/build_config.json
+++ b/scripts/build/Platform/Windows/build_config.json
@@ -17,7 +17,8 @@
},
"debug_vs2019_pipe": {
"TAGS": [
- "nightly"
+ "nightly-incremental",
+ "nightly-clean"
],
"steps": [
"debug_vs2019",
@@ -125,7 +126,8 @@
},
"profile_vs2019_nounity": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
@@ -157,10 +159,11 @@
},
"test_gpu_profile_vs2019": {
"TAGS":[
- "nightly"
+ "nightly-incremental",
+ "nightly-clean"
],
"PIPELINE_ENV":{
- "NODE_LABEL":"windows-gpu"
+ "NODE_LABEL":"windows-gpu"
},
"COMMAND": "build_test_windows.cmd",
"PARAMETERS": {
@@ -176,7 +179,9 @@
},
"asset_profile_vs2019": {
"TAGS": [
- "weekly-build-metrics"
+ "weekly-build-metrics",
+ "nightly-incremental",
+ "nightly-clean"
],
"COMMAND": "build_asset_windows.cmd",
"PARAMETERS": {
@@ -191,21 +196,10 @@
"ASSET_PROCESSOR_PLATFORMS": "pc,server"
}
},
- "asset_clean_profile_vs2019": {
- "TAGS": [
- "nightly"
- ],
- "PIPELINE_ENV": {
- "CLEAN_ASSETS": "1"
- },
- "steps": [
- "clean",
- "asset_profile_vs2019"
- ]
- },
"periodic_test_profile_vs2019": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_test_windows.cmd",
@@ -222,7 +216,8 @@
},
"sandbox_test_profile_vs2019": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"PIPELINE_ENV": {
@@ -242,7 +237,8 @@
},
"benchmark_test_profile_vs2019": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_test_windows.cmd",
@@ -259,7 +255,8 @@
},
"release_vs2019": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
@@ -274,7 +271,8 @@
},
"monolithic_release_vs2019": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
@@ -289,7 +287,8 @@
},
"install_profile_vs2019": {
"TAGS": [
- "nightly"
+ "nightly-incremental",
+ "nightly-clean"
],
"COMMAND": "build_windows.cmd",
"PARAMETERS": {
diff --git a/scripts/build/Platform/Windows/pipeline.json b/scripts/build/Platform/Windows/pipeline.json
index 380b8c1a48..5f10ccc7ae 100644
--- a/scripts/build/Platform/Windows/pipeline.json
+++ b/scripts/build/Platform/Windows/pipeline.json
@@ -12,6 +12,9 @@
},
"packaging": {
"CLEAN_WORKSPACE": true
+ },
+ "nightly-clean": {
+ "CLEAN_WORKSPACE": true
}
}
}
\ No newline at end of file
diff --git a/scripts/build/Platform/iOS/build_config.json b/scripts/build/Platform/iOS/build_config.json
index 921262e267..75b5e7b10d 100644
--- a/scripts/build/Platform/iOS/build_config.json
+++ b/scripts/build/Platform/iOS/build_config.json
@@ -19,7 +19,8 @@
},
"debug": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_mac.sh",
@@ -34,7 +35,8 @@
},
"profile": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"daily-pipeline-metrics",
"weekly-build-metrics"
],
@@ -50,7 +52,8 @@
},
"profile_nounity": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_mac.sh",
@@ -65,7 +68,8 @@
},
"asset_profile": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_asset_mac.sh",
@@ -80,21 +84,10 @@
"ASSET_PROCESSOR_PLATFORMS": "ios"
}
},
- "asset_clean_profile": {
- "TAGS": [
- "nightly"
- ],
- "PIPELINE_ENV": {
- "CLEAN_ASSETS": "true"
- },
- "steps": [
- "clean",
- "asset_profile"
- ]
- },
"release": {
"TAGS": [
- "nightly",
+ "nightly-incremental",
+ "nightly-clean",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_mac.sh",
diff --git a/scripts/build/Platform/iOS/pipeline.json b/scripts/build/Platform/iOS/pipeline.json
index bb94f33d70..58f62b421d 100644
--- a/scripts/build/Platform/iOS/pipeline.json
+++ b/scripts/build/Platform/iOS/pipeline.json
@@ -12,6 +12,9 @@
},
"packaging": {
"CLEAN_WORKSPACE": true
+ },
+ "nightly-clean": {
+ "CLEAN_WORKSPACE": true
}
}
}
\ No newline at end of file