diff --git a/.github/ISSUE_TEMPLATE/ar_bug_report-md.md b/.github/ISSUE_TEMPLATE/ar_bug_report.md
similarity index 72%
rename from .github/ISSUE_TEMPLATE/ar_bug_report-md.md
rename to .github/ISSUE_TEMPLATE/ar_bug_report.md
index e2f64b88b8..0d4aee9397 100644
--- a/.github/ISSUE_TEMPLATE/ar_bug_report-md.md
+++ b/.github/ISSUE_TEMPLATE/ar_bug_report.md
@@ -1,17 +1,8 @@
---
name: ar_bug_report.md
about: Create a bug for a an issue found in the Automated Review
-title: ''
-labels: ''
-assignees: ''
-
----
-
----
-name: Automated Review Bug report
-about: Create a report when a failure occurs in main branch
-title: ''
-labels: 'Automated_Review'
+title: 'AR Bug Report'
+labels: 'needs-triage,kind/bug,kind/automation'
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/rfc-feature.md b/.github/ISSUE_TEMPLATE/rfc-feature.md
deleted file mode 100644
index 31a195f803..0000000000
--- a/.github/ISSUE_TEMPLATE/rfc-feature.md
+++ /dev/null
@@ -1,73 +0,0 @@
----
-name: RFC Feature request
-about: Create Feature RFC for this project
-title: Proposed RFC Feature =description=
-labels: 'rfc-feature'
-assignees: ''
-
----
-
-# O3DE RFC Feature Template
-
-### When using this template, you do not have to fill out every question below. The questions are there for guidance.
-
-This RFC feature template should be used for any feature that is not a bug or a substantial reorganization of the O3DE product.
-
-If you submit a pull request to implement a new feature without going through the RFC process, it may be closed with a polite request to submit an RFC first.
-
-A hastily proposed RFC can hurt its chances of acceptance. Low-quality proposals, proposals for previously-rejected features, or those that don't fit into the near-term roadmap may be quickly rejected, demotivating the unprepared contributor. Laying some groundwork ahead of the RFC can make the process smoother.
-
-Although there is no single way to prepare for submitting an RFC, it is generally a good idea to pursue feedback from other project developers beforehand to ascertain that the RFC may be desirable; having a consistent impact on the project requires concerted effort toward consensus-building.
-
-The most common preparations for writing and submitting an RFC include:
-- Talking the idea over on our Discord server.
-- Discussing the topic on our GitHub RFCs discussions page.
-- Occasionally posting "pre-RFCs" on the GitHub RFCs discussion page.
-You may file issues in the RFCs repo for discussion, but these are not actively looked at by the teams.
-
-As a rule of thumb, receiving encouraging feedback from long-standing project developers, and particularly members of the relevant sub-team, is a good indication that the RFC is worth pursuing.
-
-# ----- DELETE EVERYTHING FROM THE TOP TO THE SUMMARY LINE BELOW WHEN USING TEMPLATE ----- #
-
-### Summary:
-Single paragraph explanation of the feature
-
-### What is the relevance of this feature?
-Why is this important? What are the use cases? What will it do once completed?
-
-### Feature design description:
-- Explain the design of the feature with enough detail that someone familiar with the environment and framework can understand the concept and explain it to others.
-- It should include at least one end-to-end example of how a developer will use it along with specific details, including outlying use cases.
-
-- If there is any new terminology, it should be defined here.
-
-### Technical design description:
-- Explain the technical portion of the work in enough detail that members can implement the feature.
-
-- Explain any API or process changes required to implement this feature
-
-- This section should relate to the feature design description by reference and explain in greater detail how it makes the feature design examples work.
-
-- This should also provide detailed information on compatibility with different hardware platforms.
-
-
-### What are the advantages of the feature?
-- Explain the advantages for someone to use this feature
-
-### What are the disadvantages of the feature?
-- Explain any disadvantages for someone to use this feature
-
-### How will this be implemented or integrated into the O3DE environment?
-- Explain how a developer will integrate this into the codebase of O3DE and provide any specific library or technical stack requirements.
-
-### Are there any alternatives to this feature?
-- Provide any other designs that have been considered. Explain what the impact might be of not doing this.
-- If there is any prior art or approaches with other frameworks in the same domain, explain how they may have solved this problem or implemented this feature.
-
-### How will users learn this feature?
-- Detail how it can be best presented and how it is used as an extension or a standalone tool used with O3DE.
-- Explain if and how it may change how individuals would use the platform and if any documentation must be changed or reorganized.
-- Explain how it would be taught to new and existing O3DE users.
-
-### Are there any open questions?
-- What are some of the open questions and potential scenarios that should be considered?
diff --git a/.github/ISSUE_TEMPLATE/rfc-suggestion.md b/.github/ISSUE_TEMPLATE/rfc-suggestion.md
deleted file mode 100644
index 7c51bbc918..0000000000
--- a/.github/ISSUE_TEMPLATE/rfc-suggestion.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-name: RFC Suggestion request
-about: Create Suggestion RFC for this project
-title: Proposed RFC Suggestion =description=
-labels: 'rfc-suggestion'
-assignees: ''
-
----
-
-# O3DE Suggestion RFC Template
-
-### When using this template, you do not have to fill out every question below. The questions are there for guidance.
-
-This RFC template should be used for any suggestion that is not based upon code or content related to the O3DE product itself. This template is for proposing new process models, approaches, or ideas to improve the O3DE community.
-
-A hastily proposed RFC can hurt its chances of acceptance. Low-quality proposals, proposals for previously rejected features, or those that do not have any substantive value to the project may be quickly rejected, demotivating the unprepared contributor. Laying some groundwork with others in the community ahead of the RFC can make the process much smoother.
-
-Although there is no single way to prepare for submitting an RFC, it is generally a good idea to pursue feedback from other project members beforehand. Keep in mind that you want other members to contribute and back your suggestion, which can drastically improve the chances of implementation.
-
-The most common preparations for writing and submitting an RFC include:
-- Talking the idea over on our Discord server.
-- Creating a discussion on our GitHub RFCs discussions page.
-- Occasionally posting "pre-RFCs" on the GitHub RFCs discussion page.
-You may file issues in the RFCs repo for discussion, but these are not actively looked at by the teams.
-
-As a rule of thumb, receiving encouraging feedback from long-standing community members is a good indication that the RFC is worth pursuing.
-
-# ----- DELETE EVERYTHING FROM THE TOP TO THE SUMMARY LINE BELOW WHEN USING TEMPLATE ----- #
-
-### Summary:
-Single paragraph explanation of the suggestion
-
-### What is the motivation for this suggestion?
-Why is this important?
-What are the use cases for this suggestion?
-What should the outcome be if this suggestion is implemented?
-
-### Suggestion design description:
-- Explain the suggestion with enough detail that someone familiar with the process and environment of the project can understand the suggestion and explain it to others.
-- It should include at least one end-to-end example of how the community will use it along with the specific details with outlying use cases.
-
-- If there is any new terminology, it should be defined here.
-
-### What are the advantages of the suggestion?
-- Explain the advantages of using this suggestion
-
-### What are the disadvantages of the suggestion?
-- Explain any disadvantages or trade-offs to using this suggestion
-
-### How will this be work within the O3DE project?
-- Explain how this suggestion will be work within the O3DE project.
-
-### Are there any alternatives to this suggestion?
-- Provide any other alternative ways that have been considered.
-- Explain what the impact might be of not implementing this suggestion.
-- If there are other similar suggestions previously used, list them and explain which parts may have solved some or all of this problem.
-
-### What is the strategy for adoption?
-- Explain how new and existing users will adopt this suggestion.
-- Point out any efforts needed if it requires coordination with multiple SIGs or other projects.
-- Explain how it would be taught to new and existing O3DE users.
diff --git a/AutomatedTesting/Gem/Code/enabled_gems.cmake b/AutomatedTesting/Gem/Code/enabled_gems.cmake
index b712fec7ab..dd68e379dd 100644
--- a/AutomatedTesting/Gem/Code/enabled_gems.cmake
+++ b/AutomatedTesting/Gem/Code/enabled_gems.cmake
@@ -47,8 +47,7 @@ set(ENABLED_GEMS
LmbrCentral
LyShine
HttpRequestor
- Atom_AtomBridge
- PythonCoverage
+ Atom
AWSCore
AWSClientAuth
AWSMetrics
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py
index 902666ba10..e7c115d4dd 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py
@@ -15,10 +15,7 @@ import ly_test_tools.log.log_monitor
# fixture imports
from AWS.Windows.resource_mappings.resource_mappings import resource_mappings
-from AWS.Windows.cdk.cdk_utils import Cdk
-from AWS.common.aws_utils import AwsUtils
-from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
-from AWS.common.aws_credentials import aws_credentials
+from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
from .aws_metrics_utils import aws_metrics_utils
AWS_METRICS_FEATURE_NAME = 'AWSMetrics'
@@ -28,7 +25,7 @@ logger = logging.getLogger(__name__)
def setup(launcher: ly_test_tools.launchers.Launcher,
- cdk: Cdk,
+ cdk: pytest.fixture,
asset_processor: asset_processor,
resource_mappings: resource_mappings,
context_variable: str = '') -> typing.Tuple[ly_test_tools.log.log_monitor.LogMonitor, str, str]:
@@ -119,7 +116,7 @@ class TestAWSMetricsWindows(object):
asset_processor: pytest.fixture,
workspace: pytest.fixture,
aws_utils: pytest.fixture,
- aws_credentials: aws_credentials,
+ aws_credentials: pytest.fixture,
resource_mappings: pytest.fixture,
cdk: pytest.fixture,
aws_metrics_utils: aws_metrics_utils,
@@ -162,7 +159,7 @@ class TestAWSMetricsWindows(object):
level: str,
launcher: ly_test_tools.launchers.Launcher,
cdk: pytest.fixture,
- aws_credentials: aws_credentials,
+ aws_credentials: pytest.fixture,
asset_processor: pytest.fixture,
resource_mappings: pytest.fixture,
workspace: pytest.fixture):
@@ -187,7 +184,7 @@ class TestAWSMetricsWindows(object):
level: str,
launcher: ly_test_tools.launchers.Launcher,
cdk: pytest.fixture,
- aws_credentials: aws_credentials,
+ aws_credentials: pytest.fixture,
asset_processor: pytest.fixture,
resource_mappings: pytest.fixture,
aws_utils: pytest.fixture,
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/core/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/core/__init__.py
new file mode 100644
index 0000000000..e200fa77d0
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/core/__init__.py
@@ -0,0 +1,5 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/core/test_aws_resource_interaction.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/core/test_aws_resource_interaction.py
new file mode 100644
index 0000000000..935d8aa283
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/core/test_aws_resource_interaction.py
@@ -0,0 +1,186 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+import os
+import logging
+import time
+
+import pytest
+import ly_test_tools
+import ly_test_tools.log.log_monitor
+import ly_test_tools.environment.process_utils as process_utils
+import ly_test_tools.o3de.asset_processor_utils as asset_processor_utils
+
+from botocore.exceptions import ClientError
+from AWS.Windows.resource_mappings.resource_mappings import resource_mappings
+from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
+
+AWS_CORE_FEATURE_NAME = 'AWSCore'
+AWS_RESOURCE_MAPPING_FILE_NAME = 'default_aws_resource_mappings.json'
+
+process_utils.kill_processes_named("o3de", ignore_extensions=True) # Kill ProjectManager windows
+
+GAME_LOG_NAME = 'Game.log'
+
+logger = logging.getLogger(__name__)
+
+
+def setup(launcher: pytest.fixture, cdk: pytest.fixture, resource_mappings: pytest.fixture, asset_processor: pytest.fixture):
+ asset_processor_utils.kill_asset_processor()
+ logger.info(f'Cdk stack names:\n{cdk.list()}')
+ stacks = cdk.deploy(additonal_params=['--all'])
+ resource_mappings.populate_output_keys(stacks)
+ asset_processor.start()
+ asset_processor.wait_for_idle()
+
+ file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME)
+ log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
+
+ return log_monitor
+
+
+@pytest.mark.SUITE_periodic
+@pytest.mark.usefixtures('automatic_process_killer')
+@pytest.mark.usefixtures('asset_processor')
+@pytest.mark.usefixtures('cdk')
+@pytest.mark.parametrize('feature_name', [AWS_CORE_FEATURE_NAME])
+@pytest.mark.parametrize('region_name', ['us-west-2'])
+@pytest.mark.parametrize('assume_role_arn', ['arn:aws:iam::645075835648:role/o3de-automation-tests'])
+@pytest.mark.parametrize('session_name', ['o3de-Automation-session'])
+@pytest.mark.usefixtures('workspace')
+@pytest.mark.parametrize('project', ['AutomatedTesting'])
+@pytest.mark.parametrize('level', ['AWS/Core'])
+@pytest.mark.usefixtures('resource_mappings')
+@pytest.mark.parametrize('resource_mappings_filename', [AWS_RESOURCE_MAPPING_FILE_NAME])
+@pytest.mark.usefixtures('aws_credentials')
+@pytest.mark.parametrize('profile_name', ['AWSAutomationTest'])
+class TestAWSCoreAWSResourceInteraction(object):
+ """
+ Test class to verify AWSCore can downloading a file from S3.
+ """
+ def test_download_from_s3(self,
+ level: str,
+ launcher: pytest.fixture,
+ cdk: pytest.fixture,
+ workspace: pytest.fixture,
+ asset_processor: pytest.fixture,
+ resource_mappings: pytest.fixture
+ ):
+ """
+ Setup: Deploys cdk and updates resource mapping file.
+ Tests: Getting AWS credentials for no signed in user.
+ Verification: Log monitor looks for success download. The existence and contents of the file are also verified.
+ """
+
+ log_monitor = setup(launcher, cdk, resource_mappings, asset_processor)
+
+ launcher.args = ['+LoadLevel', level]
+ launcher.args.extend(['-rhi=null'])
+
+ user_dir = os.path.join(workspace.paths.project(), 'user')
+ download_dir = os.path.join(user_dir, 's3_download')
+ if not os.path.exists(download_dir):
+ os.makedirs(download_dir)
+
+ with launcher.start(launch_ap=False):
+ result = log_monitor.monitor_log_for_lines(
+ expected_lines=['(Script) - [S3] Head object request is done',
+ '(Script) - [S3] Head object success: Object example.txt is found.',
+ '(Script) - [S3] Get object success: Object example.txt is downloaded.'],
+ unexpected_lines=['(Script) - [S3] Head object error: No response body.',
+ '(Script) - [S3] Get object error: Request validation failed, output file directory doesn\'t exist.'],
+ halt_on_unexpected=True
+ )
+
+ assert result, "Expected lines weren't found."
+
+ download_path = os.path.join(download_dir, 'output.txt')
+
+ file_was_downloaded = os.path.exists(download_path)
+ # clean up the file directories.
+ if file_was_downloaded:
+ os.remove(download_path)
+ os.rmdir(download_dir)
+
+ assert file_was_downloaded, 'The expected file wasn\'t successfully downloaded'
+
+ def test_invoke_lambda(self,
+ level: str,
+ launcher: pytest.fixture,
+ cdk: pytest.fixture,
+ resource_mappings: pytest.fixture,
+ workspace: pytest.fixture,
+ asset_processor: pytest.fixture
+ ):
+ """
+ Setup: Deploys the CDK.
+ Tests: Runs the test level.
+ Verification: Searches the logs for the expected output from the example lambda.
+ """
+
+ log_monitor = setup(launcher, cdk, resource_mappings, asset_processor)
+
+ launcher.args = ['+LoadLevel', level]
+ launcher.args.extend(['-rhi=null'])
+
+ with launcher.start(launch_ap=False):
+ result = log_monitor.monitor_log_for_lines(
+ expected_lines=['(Script) - [Lambda] Completed Invoke',
+ '(Script) - [Lambda] Invoke success: {"statusCode": 200, "body": {}}'],
+ unexpected_lines=['(Script) - Request validation failed, output file miss full path.',
+ '(Script) - '],
+ halt_on_unexpected=True
+ )
+
+ assert result
+
+ def test_get_dynamodb_value(self,
+ level: str,
+ launcher: pytest.fixture,
+ cdk: pytest.fixture,
+ resource_mappings: pytest.fixture,
+ workspace: pytest.fixture,
+ asset_processor: pytest.fixture,
+ aws_utils: pytest.fixture,
+ ):
+ """
+ Setup: Deploys the CDK application
+ Test: Runs a launcher with a level that loads a scriptcanvas that pulls a DynamoDB table value.
+ Verification: The value is output in the logs and verified by the test.
+ """
+
+ def write_test_table_data():
+ client = aws_utils.client('dynamodb')
+ table_name = resource_mappings.get_resource_name_id("AWSCore.ExampleDynamoTableOutput")
+ try:
+ client.put_item(
+ TableName=table_name,
+ Item={
+ 'id': {
+ 'S': 'Item1'
+ }
+ }
+ )
+ logger.info(f'Loaded data into table {table_name}')
+ except ClientError:
+ logger.exception(f'Failed to load data into table {table_name}')
+ raise
+
+ log_monitor = setup(launcher, cdk, resource_mappings, asset_processor)
+ write_test_table_data()
+
+ launcher.args = ['+LoadLevel', level]
+ launcher.args.extend(['-rhi=null'])
+
+ with launcher.start(launch_ap=False):
+ result = log_monitor.monitor_log_for_lines(
+ expected_lines=['(Script) - [DynamoDB] Results finished'],
+ unexpected_lines=['(Script) - Request validation failed, output file miss full path.',
+ '(Script) - '],
+ halt_on_unexpected=True
+ )
+
+ assert result
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py
index 61523599a8..f74ae888d5 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py
@@ -107,24 +107,3 @@ class AwsCredentials:
else:
self._credentials[self._profile_name][attribute_name] = attribute_value
-
-@pytest.fixture(scope='function')
-def aws_credentials(request: pytest.fixture, aws_utils: pytest.fixture, profile_name: str):
- """
- Fixture for setting up temporary AWS credentials from assume role.
-
- :param request: _pytest.fixtures.SubRequest class that handles getting
- a pytest fixture from a pytest function/fixture.
- :param aws_utils: aws_utils fixture.
- :param profile_name: Named AWS profile to store temporary credentials.
- """
- aws_credentials_obj = AwsCredentials(profile_name)
- original_access_key, original_secret_access_key, original_token = aws_credentials_obj.get_aws_credentials()
- aws_credentials_obj.set_aws_credentials_by_session(aws_utils.assume_session())
-
- def teardown():
- # Reset to the named profile using the original AWS credentials
- aws_credentials_obj.set_aws_credentials(original_access_key, original_secret_access_key, original_token)
- request.addfinalizer(teardown)
-
- return aws_credentials_obj
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/conftest.py b/AutomatedTesting/Gem/PythonTests/AWS/conftest.py
index 15217d4620..f6425dbab4 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/conftest.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/conftest.py
@@ -6,6 +6,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import pytest
import logging
from AWS.common.aws_utils import AwsUtils
+from AWS.common.aws_credentials import AwsCredentials
from AWS.Windows.cdk.cdk_utils import Cdk
logger = logging.getLogger(__name__)
@@ -81,3 +82,26 @@ def cdk(
request.addfinalizer(teardown)
return pytest.cdk_obj
+
+
+
+@pytest.fixture(scope='function')
+def aws_credentials(request: pytest.fixture, aws_utils: pytest.fixture, profile_name: str):
+ """
+ Fixture for setting up temporary AWS credentials from assume role.
+
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param aws_utils: aws_utils fixture.
+ :param profile_name: Named AWS profile to store temporary credentials.
+ """
+ aws_credentials_obj = AwsCredentials(profile_name)
+ original_access_key, original_secret_access_key, original_token = aws_credentials_obj.get_aws_credentials()
+ aws_credentials_obj.set_aws_credentials_by_session(aws_utils.assume_session())
+
+ def teardown():
+ # Reset to the named profile using the original AWS credentials
+ aws_credentials_obj.set_aws_credentials(original_access_key, original_secret_access_key, original_token)
+ request.addfinalizer(teardown)
+
+ return aws_credentials_obj
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
index f05aff6db3..baf8e9733e 100644
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
@@ -103,6 +103,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
AZ::AssetBundlerBatch
)
+ ly_add_pytest(
+ NAME AssetPipelineTests.AssetBundler_SandBox
+ TEST_SUITE sandbox
+ PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
+ PYTEST_MARKS "SUITE_sandbox" # run only sandbox tests in this file
+ EXCLUDE_TEST_RUN_TARGET_FROM_IDE
+ TEST_SERIAL
+ TIMEOUT 1500
+ RUNTIME_DEPENDENCIES
+ AZ::AssetProcessor
+ AZ::AssetBundlerBatch
+ )
+
ly_add_pytest(
NAME AssetPipelineTests.AssetBuilder
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_builder_tests.py
diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py
index 926f1cc602..1a5ece92e1 100755
--- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py
+++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py
@@ -730,6 +730,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object):
@pytest.mark.BAT
@pytest.mark.assetpipeline
+ @pytest.mark.SUITE_sandbox
@pytest.mark.test_case_id("C16877174")
@pytest.mark.test_case_id("C16877175")
@pytest.mark.test_case_id("C16877178")
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt
index ec150bd186..b851260639 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt
@@ -38,7 +38,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
TEST_SUITE main
TEST_REQUIRES gpu
TEST_SERIAL
- TIMEOUT 400
+ TIMEOUT 800
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_GPUTests.py
RUNTIME_DEPENDENCIES
AssetProcessor
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py
index cb5ae709d1..05eff871c1 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py
@@ -17,7 +17,7 @@ import editor_python_test_tools.hydra_test_utils as hydra
logger = logging.getLogger(__name__)
DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots'
-EDITOR_TIMEOUT = 300
+EDITOR_TIMEOUT = 600
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
@@ -77,7 +77,6 @@ class TestAllComponentsIndepthTests(object):
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
cfg_args=[level],
- auto_test_mode=False,
null_renderer=False,
)
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py
index 26110cd954..c157c995c4 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py
@@ -60,24 +60,7 @@ class TestEditMenuOptions(EditorTestHelper):
("Modify", "Transform Mode", "Rotate"),
("Modify", "Transform Mode", "Scale"),
("Editor Settings", "Global Preferences"),
- ("Editor Settings", "Graphics Settings"),
("Editor Settings", "Editor Settings Manager"),
- ("Editor Settings", "Graphics Performance", "PC", "Very High"),
- ("Editor Settings", "Graphics Performance", "PC", "High"),
- ("Editor Settings", "Graphics Performance", "PC", "Medium"),
- ("Editor Settings", "Graphics Performance", "PC", "Low"),
- ("Editor Settings", "Graphics Performance", "OSX Metal", "Very High"),
- ("Editor Settings", "Graphics Performance", "OSX Metal", "High"),
- ("Editor Settings", "Graphics Performance", "OSX Metal", "Medium"),
- ("Editor Settings", "Graphics Performance", "OSX Metal", "Low"),
- ("Editor Settings", "Graphics Performance", "Android", "Very High"),
- ("Editor Settings", "Graphics Performance", "Android", "High"),
- ("Editor Settings", "Graphics Performance", "Android", "Medium"),
- ("Editor Settings", "Graphics Performance", "Android", "Low"),
- ("Editor Settings", "Graphics Performance", "iOS", "Very High"),
- ("Editor Settings", "Graphics Performance", "iOS", "High"),
- ("Editor Settings", "Graphics Performance", "iOS", "Medium"),
- ("Editor Settings", "Graphics Performance", "iOS", "Low"),
("Editor Settings", "Keyboard Customization", "Customize Keyboard"),
("Editor Settings", "Keyboard Customization", "Export Keyboard Settings"),
("Editor Settings", "Keyboard Customization", "Import Keyboard Settings"),
diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py
index 7ed08867a9..3f3885a028 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py
@@ -49,7 +49,6 @@ class TestViewMenuOptions(EditorTestHelper):
("Viewport", "Center on Selection"),
("Viewport", "Go to Location"),
("Viewport", "Remember Location"),
- ("Viewport", "Change Move Speed"),
("Viewport", "Switch Camera"),
("Viewport", "Show/Hide Helpers"),
("Refresh Style",),
diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py b/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py
index b45a087c79..cc5385f4ba 100644
--- a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py
+++ b/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py
@@ -55,12 +55,7 @@ class TestMenus(object):
"Rotate Action triggered",
"Scale Action triggered",
"Global Preferences Action triggered",
- "Graphics Settings Action triggered",
"Editor Settings Manager Action triggered",
- "Very High Action triggered",
- "High Action triggered",
- "Medium Action triggered",
- "Low Action triggered",
"Customize Keyboard Action triggered",
"Export Keyboard Settings Action triggered",
"Import Keyboard Settings Action triggered",
@@ -89,7 +84,6 @@ class TestMenus(object):
"Center on Selection Action triggered",
"Go to Location Action triggered",
"Remember Location Action triggered",
- "Change Move Speed Action triggered",
"Switch Camera Action triggered",
"Show/Hide Helpers Action triggered",
"Refresh Style Action triggered",
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt
index af9fc142e2..73af69b93a 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt
@@ -51,4 +51,18 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
)
+
+ ly_add_pytest(
+ NAME AutomatedTesting::GameLauncherWithGPU
+ TEST_SUITE sandbox
+ TEST_REQUIRES gpu
+ PATH ${CMAKE_CURRENT_LIST_DIR}/test_GameLauncher_EnterExitGameMode_Works.py
+ TIMEOUT 100
+ RUNTIME_DEPENDENCIES
+ AZ::AssetProcessor
+ AZ::PythonBindingsExample
+ Legacy::Editor
+ AutomatedTesting.GameLauncher
+ AutomatedTesting.Assets
+ )
endif()
diff --git a/AutomatedTesting/Gem/Resources/CryEngineLogoLauncher.bmp b/AutomatedTesting/Gem/Resources/CryEngineLogoLauncher.bmp
deleted file mode 100644
index fe0adc54a4..0000000000
--- a/AutomatedTesting/Gem/Resources/CryEngineLogoLauncher.bmp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:cf6d56fe4c367d39bd78500dd34332fcad57ad41241768b52781dbdb60ddd972
-size 347568
diff --git a/AutomatedTesting/Gem/Resources/GameSDK.ico b/AutomatedTesting/Gem/Resources/GameSDK.ico
index cb935cd926..0be1f28b6c 100644
--- a/AutomatedTesting/Gem/Resources/GameSDK.ico
+++ b/AutomatedTesting/Gem/Resources/GameSDK.ico
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:61efd8df621780af995fc1250918df5e00364ff00f849bef67702cd4b0a152e1
-size 65537
+oid sha256:41239f8345fa91fe546442208461ad3cd17c7a7a7047af45018b97363bfea204
+size 109783
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon152x152.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon152x152.png
index b0dd493c11..ad18894411 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon152x152.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon152x152.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e4901093fa6190bf37291b0fb6de23fba1be8ebbd742775a8565a4106722fbb6
-size 31942
+oid sha256:ebfc95bd4c0cbcc53d0ef9d314d26e09a347a22dabbf210597f405d9ed8646bf
+size 7729
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon76x76.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon76x76.png
index 21aa62e96b..888d8cf785 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon76x76.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadAppIcon76x76.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e4ae97c4f44910121a61686862c8342ce598db4cdf9d46b29e96d3cb9e43bd06
-size 22158
+oid sha256:99cb7da9282cfcfa64598455827f27ca6791d45ca0d2c3c2dc090d82468dac03
+size 4447
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadProAppIcon167x167.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadProAppIcon167x167.png
index 6b696a84b2..86aa72016a 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadProAppIcon167x167.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadProAppIcon167x167.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:061e2d0ce8dc852dd298c80f2aed5fee8ea4b87511c00662aa2d00922c0ba3c2
-size 30162
+oid sha256:101568e946f1d4cea86d666187bbf71116bbf62e6eaf6d80bc3c5e2e184bdb15
+size 7938
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon29x29.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon29x29.png
index f3dfa05839..79331c29b1 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon29x29.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon29x29.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0fb4b4b77620d99dae7473b7bd8affe14630419835bd5719167ed200e657fa4f
-size 17504
+oid sha256:cf930ffd4efb0b7b627e05aac6e0f56252ea206623e8b5d097d803aa315cdfb8
+size 1812
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon58x58.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon58x58.png
index 5325b805fd..27c4aaef2e 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon58x58.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSettingsIcon58x58.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8aa9b1194f3244025578225a6a87cbc2dd12c70955ff615c8af640ea7f1334f1
-size 19619
+oid sha256:ba5fea53b349e254b4625035a308d5731cb06f6d0adc278874d14db2627962cb
+size 3424
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon40x40.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon40x40.png
index 98d8455838..df1630a95a 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon40x40.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon40x40.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0c25ffb1af8160b3202977de8c32aaa235e22c643ffd8004e4546c96868ef3b9
-size 18317
+oid sha256:cf087f357cd439d14651073ac079542c60f0648a30dced2a8d19912124b3f8b6
+size 2310
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon80x80.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon80x80.png
index 7482f6c892..4b7f5d6318 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon80x80.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPadSpotlightIcon80x80.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2db961b8f922a552d8ad374fdb56029efd4049a6cde10399b3d961242c82ce53
-size 22571
+oid sha256:421ad4db14c28ed18666158f9ec30747c5b8c757405c1efb32442978911b0c06
+size 4437
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon120x120.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon120x120.png
index da987b86f9..674c6da124 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon120x120.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon120x120.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f39d897a57d4da0a70ede7c91339660b28e9d8c57b3e7d749807b13baa4b85f3
-size 28559
+oid sha256:0d0044ebf7e0a5dd23ed64a1289c705d8f6c3c41a62d65e5a1371058855b8cec
+size 6546
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon180x180.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon180x180.png
index 205e025c36..c0c10c2390 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon180x180.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneAppIcon180x180.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:263b75d58328499eef1f8fa2e64c30706f546badcc0c4464a043b231da93cd0d
-size 34969
+oid sha256:3b8717c5f2109dfce1bf7b017278059d4915b524a6eb7e83cfb1926e54ed6869
+size 7383
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon58x58.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon58x58.png
index 0deb4f4f35..27c4aaef2e 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon58x58.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon58x58.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:33522ad8a8e826b22dd9ad214f56e63e24bf55c00bd8c845925d848b855dfb48
-size 19619
+oid sha256:ba5fea53b349e254b4625035a308d5731cb06f6d0adc278874d14db2627962cb
+size 3424
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon87x87.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon87x87.png
index 78591751d7..9093e13867 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon87x87.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSettingsIcon87x87.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f405c9f3d908d038aea26049e533b0d10955adfac370c7b3b80209997ea706d0
-size 24407
+oid sha256:a32908a839a6cb0ca2a76d6aa60376ba8a14b4428f06c13149ec277514eb5676
+size 4533
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon120x120.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon120x120.png
index 034dcb9fed..674c6da124 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon120x120.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon120x120.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d110f6e151799a2327bcdf5ef94d6fc82b114783a8cc973a8915896679ba4a80
-size 28559
+oid sha256:0d0044ebf7e0a5dd23ed64a1289c705d8f6c3c41a62d65e5a1371058855b8cec
+size 6546
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon80x80.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon80x80.png
index f0fa89149c..4b7f5d6318 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon80x80.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AppIcon.appiconset/iPhoneSpotlightIcon80x80.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:db8f00568fad4e49b05249aaa7a48c9fbf85c8b7a78489c83dc9b8161778bcef
-size 22571
+oid sha256:421ad4db14c28ed18666158f9ec30747c5b8c757405c1efb32442978911b0c06
+size 4437
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon152x152.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon152x152.png
index b0dd493c11..ad18894411 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon152x152.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon152x152.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e4901093fa6190bf37291b0fb6de23fba1be8ebbd742775a8565a4106722fbb6
-size 31942
+oid sha256:ebfc95bd4c0cbcc53d0ef9d314d26e09a347a22dabbf210597f405d9ed8646bf
+size 7729
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon76x76.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon76x76.png
index 21aa62e96b..888d8cf785 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon76x76.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadAppIcon76x76.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e4ae97c4f44910121a61686862c8342ce598db4cdf9d46b29e96d3cb9e43bd06
-size 22158
+oid sha256:99cb7da9282cfcfa64598455827f27ca6791d45ca0d2c3c2dc090d82468dac03
+size 4447
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadProAppIcon167x167.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadProAppIcon167x167.png
index 6b696a84b2..86aa72016a 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadProAppIcon167x167.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadProAppIcon167x167.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:061e2d0ce8dc852dd298c80f2aed5fee8ea4b87511c00662aa2d00922c0ba3c2
-size 30162
+oid sha256:101568e946f1d4cea86d666187bbf71116bbf62e6eaf6d80bc3c5e2e184bdb15
+size 7938
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon29x29.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon29x29.png
index f3dfa05839..79331c29b1 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon29x29.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon29x29.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0fb4b4b77620d99dae7473b7bd8affe14630419835bd5719167ed200e657fa4f
-size 17504
+oid sha256:cf930ffd4efb0b7b627e05aac6e0f56252ea206623e8b5d097d803aa315cdfb8
+size 1812
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon58x58.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon58x58.png
index 5325b805fd..27c4aaef2e 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon58x58.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSettingsIcon58x58.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8aa9b1194f3244025578225a6a87cbc2dd12c70955ff615c8af640ea7f1334f1
-size 19619
+oid sha256:ba5fea53b349e254b4625035a308d5731cb06f6d0adc278874d14db2627962cb
+size 3424
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon40x40.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon40x40.png
index 98d8455838..df1630a95a 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon40x40.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon40x40.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0c25ffb1af8160b3202977de8c32aaa235e22c643ffd8004e4546c96868ef3b9
-size 18317
+oid sha256:cf087f357cd439d14651073ac079542c60f0648a30dced2a8d19912124b3f8b6
+size 2310
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon80x80.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon80x80.png
index 7482f6c892..4b7f5d6318 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon80x80.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPadSpotlightIcon80x80.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2db961b8f922a552d8ad374fdb56029efd4049a6cde10399b3d961242c82ce53
-size 22571
+oid sha256:421ad4db14c28ed18666158f9ec30747c5b8c757405c1efb32442978911b0c06
+size 4437
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon120x120.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon120x120.png
index da987b86f9..674c6da124 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon120x120.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon120x120.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f39d897a57d4da0a70ede7c91339660b28e9d8c57b3e7d749807b13baa4b85f3
-size 28559
+oid sha256:0d0044ebf7e0a5dd23ed64a1289c705d8f6c3c41a62d65e5a1371058855b8cec
+size 6546
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon180x180.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon180x180.png
index 205e025c36..c0c10c2390 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon180x180.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneAppIcon180x180.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:263b75d58328499eef1f8fa2e64c30706f546badcc0c4464a043b231da93cd0d
-size 34969
+oid sha256:3b8717c5f2109dfce1bf7b017278059d4915b524a6eb7e83cfb1926e54ed6869
+size 7383
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon58x58.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon58x58.png
index 0deb4f4f35..27c4aaef2e 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon58x58.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon58x58.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:33522ad8a8e826b22dd9ad214f56e63e24bf55c00bd8c845925d848b855dfb48
-size 19619
+oid sha256:ba5fea53b349e254b4625035a308d5731cb06f6d0adc278874d14db2627962cb
+size 3424
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon87x87.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon87x87.png
index 78591751d7..9093e13867 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon87x87.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSettingsIcon87x87.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f405c9f3d908d038aea26049e533b0d10955adfac370c7b3b80209997ea706d0
-size 24407
+oid sha256:a32908a839a6cb0ca2a76d6aa60376ba8a14b4428f06c13149ec277514eb5676
+size 4533
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon120x120.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon120x120.png
index 034dcb9fed..674c6da124 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon120x120.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon120x120.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d110f6e151799a2327bcdf5ef94d6fc82b114783a8cc973a8915896679ba4a80
-size 28559
+oid sha256:0d0044ebf7e0a5dd23ed64a1289c705d8f6c3c41a62d65e5a1371058855b8cec
+size 6546
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon80x80.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon80x80.png
index f0fa89149c..4b7f5d6318 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon80x80.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/AutomatedTestingAppIcon.appiconset/iPhoneSpotlightIcon80x80.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:db8f00568fad4e49b05249aaa7a48c9fbf85c8b7a78489c83dc9b8161778bcef
-size 22571
+oid sha256:421ad4db14c28ed18666158f9ec30747c5b8c757405c1efb32442978911b0c06
+size 4437
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/Contents.json b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/Contents.json
index 5ea213954f..f836f07ee7 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/Contents.json
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/Contents.json
@@ -1,41 +1,5 @@
{
"images" : [
- {
- "extent" : "full-screen",
- "filename" : "iPhoneLaunchImage1242x2688.png",
- "idiom" : "iphone",
- "minimum-system-version" : "12.0",
- "orientation" : "portrait",
- "scale" : "3x",
- "subtype" : "2688h"
- },
- {
- "extent" : "full-screen",
- "filename" : "iPhoneLaunchImage2688x1242.png",
- "idiom" : "iphone",
- "minimum-system-version" : "12.0",
- "orientation" : "landscape",
- "scale" : "3x",
- "subtype" : "2688h"
- },
- {
- "extent" : "full-screen",
- "filename" : "iPhoneLaunchImage828x1792.png",
- "idiom" : "iphone",
- "minimum-system-version" : "12.0",
- "orientation" : "portrait",
- "scale" : "2x",
- "subtype" : "1792h"
- },
- {
- "extent" : "full-screen",
- "filename" : "iPhoneLaunchImage1792x828.png",
- "idiom" : "iphone",
- "minimum-system-version" : "12.0",
- "orientation" : "landscape",
- "scale" : "2x",
- "subtype" : "1792h"
- },
{
"extent" : "full-screen",
"idiom" : "iphone",
@@ -202,4 +166,4 @@
"version" : 1,
"author" : "xcode"
}
-}
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png
index 1249ef3703..9f586d6af3 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1024x768.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:31afa7ed44c5d9844c8d6ce08beccac482c3f43590869a3d190d06e2df377ccc
-size 137472
+oid sha256:a4018d9df45b4a04d4cf24a40fe01aa7e30e44a9fdd8ad9a41b0d87791786c12
+size 30442
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png
index cdb6d5a82a..c978631c22 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage1536x2048.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0aac8ef9899442820bec0df8bf6434a46cc787d57c5d6d38a04727b8dc310048
-size 338281
+oid sha256:2eea06cb8ad05acefe9664551af5645d52d9763b82473b1fd4a2b2b6f62e96d3
+size 53550
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png
index 954d3084c8..a52e832a42 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage2048x1536.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c07495891f15b138ba09f142777b0f43217bf8be05cbb74ba938319f3425980c
-size 321125
+oid sha256:90991aca91ab7222fdb85c03947cff38f549a6492551e7447e0c8f55022aae48
+size 52467
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png
index 021319fbc3..3e441fab3b 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPadLaunchImage768x1024.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d6bf6acb92421a453a36fc143ab6cefda14d631ea5e6dbf95c6e252a445fcbac
-size 144797
+oid sha256:6c8439a64d18dbff17dd67f6405bf49f99695e9b22fc2cc541dc72c6e3167307
+size 30564
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage1242x2688.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage1242x2688.png
deleted file mode 100644
index e190d2b585..0000000000
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage1242x2688.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:fc79117e25cc7533ccf6724453e3f44a01b4eaaecded6fa826abe897456f36ee
-size 405896
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage1792x828.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage1792x828.png
deleted file mode 100644
index 5601f081de..0000000000
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage1792x828.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6c7191be3bdae09dc621012a26b0c1b9c15de1d567cf65ff1079e00f8636a32a
-size 220720
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage2688x1242.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage2688x1242.png
deleted file mode 100644
index 844b23fdd9..0000000000
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage2688x1242.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:dfbd362f9cb5f285c23807a032af98150cf5409c514445122683736a3c65008c
-size 364976
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png
index a15fd777fa..e662e9675c 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x1136.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e9ad650fda925b1c076a67d1ef70315fe4f14db888c9fd36ee4eba1d18c1e7d1
-size 166749
+oid sha256:f752615184160d7a78f28d9eef354c86e544f11eb1dde9f651d7acd315b3f2e6
+size 35934
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png
index 2855f4069d..2753529fc2 100644
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png
+++ b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage640x960.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:16f6e9d7bd15fc528d934c252213de8792812e708b1810191c5f1767f7165852
-size 142331
+oid sha256:1a43f1d893e85aa99d335a657ec0f6c13a741db976c033451ab9a2328b8a5970
+size 35559
diff --git a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage828x1792.png b/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage828x1792.png
deleted file mode 100644
index 9ebb93e39c..0000000000
--- a/AutomatedTesting/Gem/Resources/IOSLauncher/Images.xcassets/LaunchImage.launchimage/iPhoneLaunchImage828x1792.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b0252b068b232f521ac6eca4a708fad6eaf257d0a66aa03f4f865f6a0b219cfc
-size 236433
diff --git a/AutomatedTesting/Gem/Resources/LegacyLogoLauncher.bmp b/AutomatedTesting/Gem/Resources/LegacyLogoLauncher.bmp
new file mode 100644
index 0000000000..7a35cddd49
--- /dev/null
+++ b/AutomatedTesting/Gem/Resources/LegacyLogoLauncher.bmp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7c8433178baebafe984ca23d9325d3c71b5a177fc3b3b869afbb01a583542fbe
+size 462842
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/Contents.json b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/Contents.json
index bfa8bcf478..2b63c0ee15 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/Contents.json
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -33,7 +33,7 @@
{
"size" : "128x128",
"idiom" : "mac",
- "filename" : "icon_128 _2x.png",
+ "filename" : "icon_128_2x.png",
"scale" : "2x"
},
{
@@ -45,7 +45,7 @@
{
"size" : "256x256",
"idiom" : "mac",
- "filename" : "icon_256 _2x.png",
+ "filename" : "icon_256_2x.png",
"scale" : "2x"
},
{
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128 _2x.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128 _2x.png
deleted file mode 100644
index 5970ea34ba..0000000000
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128 _2x.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e38257b6917cdf5d73e90e6009f10c8736d62b20c4e785085305075c7e6320e2
-size 32037
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128.png
index 9e30e09547..5a73a4a54d 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9f41a37d2347a617e93bd97adaf6d4c161c471ca3ef7e04b98c65ddda52396dc
-size 27833
+oid sha256:f3c651ca45a83d0f68bdaa466826a29b2ca6f674e225d90e68b7dbadc2ba582d
+size 6620
diff --git a/Templates/DefaultProject/Template/Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128 _2x.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128_2x.png
similarity index 100%
rename from Templates/DefaultProject/Template/Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_128 _2x.png
rename to AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_128_2x.png
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16.png
index aeb29abd0a..a7ec66841f 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b07984494059bf827bc485cbea06d12e0283811face1a18799495f9ba7ae8af1
-size 20779
+oid sha256:f7d5b15add5104d91a03df7d86898f4bc415d095d11c23555b24440497371948
+size 1061
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16_2x.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16_2x.png
index 445a389d61..474378c926 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16_2x.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_16_2x.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e645142d284de40aafb7a4a858f3df92b6a5ba9b03fa5f1a2d3cb25211597926
-size 21857
+oid sha256:148fdae6493d7b7e1bb6cc6aae1861e0469838f54dcb3c15cc157a548c707fec
+size 1910
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256 _2x.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256 _2x.png
deleted file mode 100644
index 0904cf7ce8..0000000000
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256 _2x.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:07631f41b8dea80713d2463f81a713a9a93798975b6fb50afbeeb13d26c57fa2
-size 48899
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256.png
index 5970ea34ba..d30f2d3686 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e38257b6917cdf5d73e90e6009f10c8736d62b20c4e785085305075c7e6320e2
-size 32037
+oid sha256:094620c172320b062f9a1f8cc758ef4bbee11bc0a6049f46ad6b42f9bf613c92
+size 9679
diff --git a/Templates/DefaultProject/Template/Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256 _2x.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256_2x.png
similarity index 100%
rename from Templates/DefaultProject/Template/Resources/Platform/Mac/Images.xcassets/TestDPAppIcon.appiconset/icon_256 _2x.png
rename to AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_256_2x.png
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32.png
index 445a389d61..474378c926 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e645142d284de40aafb7a4a858f3df92b6a5ba9b03fa5f1a2d3cb25211597926
-size 21857
+oid sha256:148fdae6493d7b7e1bb6cc6aae1861e0469838f54dcb3c15cc157a548c707fec
+size 1910
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32_2x.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32_2x.png
index 1fad9bda96..3359e99cd4 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32_2x.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_32_2x.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:ad83faf98b49f4e37112baedeae726f4f8d71bcdd1961d9cdad31f043f8ca666
-size 24003
+oid sha256:749bcd29d73e5ef2d1ef8b2d878626d0bca09c6b0d5f1c9dc6cefe7b9082c8cc
+size 3758
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512.png
index e1517dddb6..f9ff1c15e3 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:68529a6c11d5ffa7ecd9d5bbb11ceea28e6852bd45946b525af09602c9a1e1bf
-size 48899
+oid sha256:934502e242ff7a2e34e21eed1424b5e0953e701761d158520b3297944132328e
+size 18716
diff --git a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512_2x.png b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512_2x.png
index b425cb685f..a736c7f6b8 100644
--- a/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512_2x.png
+++ b/AutomatedTesting/Gem/Resources/MacLauncher/Images.xcassets/AppIcon.appiconset/icon_512_2x.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8a70003840b418848b2ce6c18ed7cbbfcd6fcf76598a6601dca8b98d9b6c1a2f
-size 114706
+oid sha256:5719043940db268dccd2e20bd9d6aa13131890d43edf002a173714ae33890422
+size 29510
diff --git a/AutomatedTesting/Levels/AWS/Core/Core.ly b/AutomatedTesting/Levels/AWS/Core/Core.ly
new file mode 100644
index 0000000000..8b01ee7abe
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Core/Core.ly
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5242a9b598bc329ef2af2b114092e4e50c7c398cdde4605a0717b0b3ce66d797
+size 10030
diff --git a/AutomatedTesting/Levels/AWS/Core/filelist.xml b/AutomatedTesting/Levels/AWS/Core/filelist.xml
new file mode 100644
index 0000000000..9d1fcd2e83
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Core/filelist.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/Core/level.pak b/AutomatedTesting/Levels/AWS/Core/level.pak
new file mode 100644
index 0000000000..01b79da84e
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Core/level.pak
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4ba2f409fc974c72b8ee8b660d200ed1d013ee8408419b0e91d6d487e71e4997
+size 3774
diff --git a/AutomatedTesting/Levels/AWS/Core/tags.txt b/AutomatedTesting/Levels/AWS/Core/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Core/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/ScriptCanvas/dynamodbdemo.scriptcanvas b/AutomatedTesting/ScriptCanvas/dynamodbdemo.scriptcanvas
new file mode 100644
index 0000000000..52654666f8
--- /dev/null
+++ b/AutomatedTesting/ScriptCanvas/dynamodbdemo.scriptcanvas
@@ -0,0 +1,3478 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/ScriptCanvas/lambdademo.scriptcanvas b/AutomatedTesting/ScriptCanvas/lambdademo.scriptcanvas
new file mode 100644
index 0000000000..d1ad940ccf
--- /dev/null
+++ b/AutomatedTesting/ScriptCanvas/lambdademo.scriptcanvas
@@ -0,0 +1,2484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/ScriptCanvas/s3demo.scriptcanvas b/AutomatedTesting/ScriptCanvas/s3demo.scriptcanvas
new file mode 100644
index 0000000000..c87c647d60
--- /dev/null
+++ b/AutomatedTesting/ScriptCanvas/s3demo.scriptcanvas
@@ -0,0 +1,5358 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..ba7f134922
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,14 @@
+# Contributing
+
+Welcome to the Open 3D Engine! To learn more about contributing to the [O3DE code repo](README.md), check out the [Contributor's Guide](https://github.com/o3de/community/blob/main/CONTRIBUTING.md).
+
+The [O3DE community repo](https://github.com/o3de/community) contains information about how to get started, how the community organizes, and more.
+
+To contribute, please review our [Code of Conduct](https://github.com/o3de/o3de/blob/development/CODE_OF_CONDUCT.md) first.
+
+## Making contributions with the Developer Certificate of Origin (DCO)
+
+When contributing, your pull requests will require that you have agreed to our DCO found here: [Devloper Certificate of Origin](https://developercertificate.org/)
+
+You can do this by using the -s option in git.
+Example: ```git commit -s -m 'my commit message'```
\ No newline at end of file
diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt
index 8a5f35fb92..13985cfb5e 100644
--- a/Code/Editor/CMakeLists.txt
+++ b/Code/Editor/CMakeLists.txt
@@ -111,7 +111,6 @@ ly_add_target(
AZ::AzCore
AZ::AzToolsFramework
Gem::LmbrCentral.Static
- Legacy::NewsShared
AZ::AWSNativeSDKInit
AZ::AtomCore
Gem::Atom_RPI.Edit
@@ -139,7 +138,6 @@ ly_add_source_properties(
ly_add_source_properties(
SOURCES
Core/LevelEditorMenuHandler.cpp
- GraphicsSettingsDialog.cpp
MainWindow.cpp
PROPERTY COMPILE_DEFINITIONS
VALUES ${LY_PAL_TOOLS_DEFINES}
diff --git a/Code/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Editor/Core/LevelEditorMenuHandler.cpp
index ab1229dc6b..600691bdd6 100644
--- a/Code/Editor/Core/LevelEditorMenuHandler.cpp
+++ b/Code/Editor/Core/LevelEditorMenuHandler.cpp
@@ -497,9 +497,15 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
// Hide Selection
editMenu.AddAction(AzToolsFramework::HideSelection);
- // Unhide All
+ // Show All
editMenu.AddAction(AzToolsFramework::ShowAll);
+ // Lock Selection
+ editMenu.AddAction(AzToolsFramework::LockSelection);
+
+ // UnLock All
+ editMenu.AddAction(AzToolsFramework::UnlockAll);
+
/*
* The following block of code is part of the feature "Isolation Mode" and is temporarily
* disabled for 1.10 release.
@@ -552,49 +558,9 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
// Global Preferences...
editorSettingsMenu.AddAction(ID_TOOLS_PREFERENCES);
- // Graphics Settings...
- editorSettingsMenu.AddAction(ID_GRAPHICS_SETTINGS);
-
// Editor Settings Manager
AddOpenViewPaneAction(editorSettingsMenu, LyViewPane::EditorSettingsManager);
- // Graphics Performance
- auto graphicPerformanceSubMenu = editorSettingsMenu.AddMenu(QObject::tr("Graphics Performance"));
-
- auto pcMenu = graphicPerformanceSubMenu.AddMenu(tr("PC"));
- pcMenu.AddAction(ID_GAME_PC_ENABLEVERYHIGHSPEC);
- pcMenu.AddAction(ID_GAME_PC_ENABLEHIGHSPEC);
- pcMenu.AddAction(ID_GAME_PC_ENABLEMEDIUMSPEC);
- pcMenu.AddAction(ID_GAME_PC_ENABLELOWSPEC);
-
- auto osxmetalMenu = graphicPerformanceSubMenu.AddMenu(tr("OSX Metal"));
- osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC);
- osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEHIGHSPEC);
- osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC);
- osxmetalMenu.AddAction(ID_GAME_OSXMETAL_ENABLELOWSPEC);
-
- auto androidMenu = graphicPerformanceSubMenu.AddMenu(tr("Android"));
- androidMenu.AddAction(ID_GAME_ANDROID_ENABLEVERYHIGHSPEC);
- androidMenu.AddAction(ID_GAME_ANDROID_ENABLEHIGHSPEC);
- androidMenu.AddAction(ID_GAME_ANDROID_ENABLEMEDIUMSPEC);
- androidMenu.AddAction(ID_GAME_ANDROID_ENABLELOWSPEC);
-
- auto iosMenu = graphicPerformanceSubMenu.AddMenu(tr("iOS"));
- iosMenu.AddAction(ID_GAME_IOS_ENABLEVERYHIGHSPEC);
- iosMenu.AddAction(ID_GAME_IOS_ENABLEHIGHSPEC);
- iosMenu.AddAction(ID_GAME_IOS_ENABLEMEDIUMSPEC);
- iosMenu.AddAction(ID_GAME_IOS_ENABLELOWSPEC);
-
-#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
-#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
- auto publicname##Menu = graphicPerformanceSubMenu.AddMenu(tr(PublicAuxName2));\
- publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLEHIGHSPEC);\
- publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC);\
- publicname##Menu.AddAction(ID_GAME_##CODENAME##_ENABLELOWSPEC);
- AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
-#undef AZ_RESTRICTED_PLATFORM_EXPANSION
-#endif
-
// Keyboard Customization
auto keyboardCustomizationMenu = editorSettingsMenu.AddMenu(tr("Keyboard Customization"));
keyboardCustomizationMenu.AddAction(ID_TOOLS_CUSTOMIZEKEYBOARD);
diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp
index 8efd4bc5b3..b0dddc94ae 100644
--- a/Code/Editor/CryEdit.cpp
+++ b/Code/Editor/CryEdit.cpp
@@ -111,7 +111,6 @@ AZ_POP_DISABLE_WARNING
#include "ToolBox.h"
#include "LevelInfo.h"
#include "EditorPreferencesDialog.h"
-#include "GraphicsSettingsDialog.h"
#include "AnimationContext.h"
#include "GotoPositionDlg.h"
@@ -440,7 +439,6 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_CLEAR_REGISTRY, OnClearRegistryData)
ON_COMMAND(ID_VALIDATELEVEL, OnValidatelevel)
ON_COMMAND(ID_TOOLS_PREFERENCES, OnToolsPreferences)
- ON_COMMAND(ID_GRAPHICS_SETTINGS, OnGraphicsSettings)
ON_COMMAND(ID_SWITCHCAMERA_DEFAULTCAMERA, OnSwitchToDefaultCamera)
ON_COMMAND(ID_SWITCHCAMERA_SEQUENCECAMERA, OnSwitchToSequenceCamera)
ON_COMMAND(ID_SWITCHCAMERA_SELECTEDCAMERA, OnSwitchToSelectedcamera)
@@ -453,14 +451,6 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_OPEN_TRACKVIEW, OnOpenTrackView)
ON_COMMAND(ID_OPEN_UICANVASEDITOR, OnOpenUICanvasEditor)
- ON_COMMAND_RANGE(ID_GAME_PC_ENABLELOWSPEC, ID_GAME_PC_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
-
- ON_COMMAND_RANGE(ID_GAME_OSXMETAL_ENABLELOWSPEC, ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
-
- ON_COMMAND_RANGE(ID_GAME_ANDROID_ENABLELOWSPEC, ID_GAME_ANDROID_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
-
- ON_COMMAND_RANGE(ID_GAME_IOS_ENABLELOWSPEC, ID_GAME_IOS_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
-
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
ON_COMMAND_RANGE(ID_GAME_##CODENAME##_ENABLELOWSPEC, ID_GAME_##CODENAME##_ENABLEHIGHSPEC, OnChangeGameSpec)
@@ -3674,13 +3664,6 @@ void CCryEditApp::OnToolsPreferences()
dlg.exec();
}
-//////////////////////////////////////////////////////////////////////////
-void CCryEditApp::OnGraphicsSettings()
-{
- GraphicsSettingsDialog dlg(MainWindow::instance());
- dlg.exec();
-}
-
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchToDefaultCamera()
{
@@ -3815,91 +3798,6 @@ void CCryEditApp::OnOpenUICanvasEditor()
QtViewPaneManager::instance()->OpenPane(LyViewPane::UiEditor);
}
-//////////////////////////////////////////////////////////////////////////
-void CCryEditApp::SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable)
-{
- if (GetIEditor()->GetEditorConfigSpec() == spec && GetIEditor()->GetEditorConfigPlatform() == platform)
- {
- nCheck = 1;
- }
- enable = spec <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
-}
-
-//////////////////////////////////////////////////////////////////////////
-void CCryEditApp::OnUpdateGameSpec(QAction* action)
-{
- Q_ASSERT(action->isCheckable());
- int nCheck = 0;
- bool enable = true;
- switch (action->data().toInt())
- {
- case ID_GAME_PC_ENABLELOWSPEC:
- SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_PC, nCheck, enable);
- break;
- case ID_GAME_PC_ENABLEMEDIUMSPEC:
- SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_PC, nCheck, enable);
- break;
- case ID_GAME_PC_ENABLEHIGHSPEC:
- SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_PC, nCheck, enable);
- break;
- case ID_GAME_PC_ENABLEVERYHIGHSPEC:
- SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_PC, nCheck, enable);
- break;
- case ID_GAME_OSXMETAL_ENABLELOWSPEC:
- SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_OSX_METAL, nCheck, enable);
- break;
- case ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC:
- SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_OSX_METAL, nCheck, enable);
- break;
- case ID_GAME_OSXMETAL_ENABLEHIGHSPEC:
- SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_OSX_METAL, nCheck, enable);
- break;
- case ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC:
- SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_OSX_METAL, nCheck, enable);
- break;
- case ID_GAME_ANDROID_ENABLELOWSPEC:
- SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_ANDROID, nCheck, enable);
- break;
- case ID_GAME_ANDROID_ENABLEMEDIUMSPEC:
- SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_ANDROID, nCheck, enable);
- break;
- case ID_GAME_ANDROID_ENABLEHIGHSPEC:
- SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_ANDROID, nCheck, enable);
- break;
- case ID_GAME_ANDROID_ENABLEVERYHIGHSPEC:
- SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_ANDROID, nCheck, enable);
- break;
- case ID_GAME_IOS_ENABLELOWSPEC:
- SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_IOS, nCheck, enable);
- break;
- case ID_GAME_IOS_ENABLEMEDIUMSPEC:
- SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_IOS, nCheck, enable);
- break;
- case ID_GAME_IOS_ENABLEHIGHSPEC:
- SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_IOS, nCheck, enable);
- break;
- case ID_GAME_IOS_ENABLEVERYHIGHSPEC:
- SetGameSpecCheck(CONFIG_VERYHIGH_SPEC, CONFIG_IOS, nCheck, enable);
- break;
-#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
-#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
- case ID_GAME_##CODENAME##_ENABLELOWSPEC:\
- SetGameSpecCheck(CONFIG_LOW_SPEC, CONFIG_##CODENAME, nCheck, enable);\
- break;\
- case ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC:\
- SetGameSpecCheck(CONFIG_MEDIUM_SPEC, CONFIG_##CODENAME, nCheck, enable);\
- break;\
- case ID_GAME_##CODENAME##_ENABLEHIGHSPEC:\
- SetGameSpecCheck(CONFIG_HIGH_SPEC, CONFIG_##CODENAME, nCheck, enable);\
- break;
- AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
-#undef AZ_RESTRICTED_PLATFORM_EXPANSION
-#endif
- }
- action->setChecked(nCheck);
- action->setEnabled(enable);
-}
-
//////////////////////////////////////////////////////////////////////////
RecentFileList* CCryEditApp::GetRecentFileList()
{
diff --git a/Code/Editor/CryEdit.h b/Code/Editor/CryEdit.h
index 0628289897..5de8aa5e6c 100644
--- a/Code/Editor/CryEdit.h
+++ b/Code/Editor/CryEdit.h
@@ -403,7 +403,6 @@ private:
void OnClearRegistryData();
void OnValidatelevel();
void OnToolsPreferences();
- void OnGraphicsSettings();
void OnSwitchToDefaultCamera();
void OnUpdateSwitchToDefaultCamera(QAction* action);
void OnSwitchToSequenceCamera();
@@ -416,9 +415,6 @@ private:
void OnOpenTrackView();
void OnOpenAudioControlsEditor();
void OnOpenUICanvasEditor();
- void OnChangeGameSpec(UINT nID);
- void SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable);
- void OnUpdateGameSpec(QAction* action);
void OnOpenQuickAccessBar();
public:
diff --git a/Code/Editor/CryEditPy.cpp b/Code/Editor/CryEditPy.cpp
index 02833a84e0..2e414da277 100644
--- a/Code/Editor/CryEditPy.cpp
+++ b/Code/Editor/CryEditPy.cpp
@@ -407,78 +407,6 @@ inline namespace Commands
}
}
-//////////////////////////////////////////////////////////////////////////
-void CCryEditApp::OnChangeGameSpec(UINT nID)
-{
- switch (nID)
- {
- case ID_GAME_PC_ENABLELOWSPEC:
- Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_PC);
- break;
- case ID_GAME_PC_ENABLEMEDIUMSPEC:
- Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_PC);
- break;
- case ID_GAME_PC_ENABLEHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_PC);
- break;
- case ID_GAME_PC_ENABLEVERYHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_PC);
- break;
- case ID_GAME_OSXMETAL_ENABLELOWSPEC:
- Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_OSX_METAL);
- break;
- case ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC:
- Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_OSX_METAL);
- break;
- case ID_GAME_OSXMETAL_ENABLEHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_OSX_METAL);
- break;
- case ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_OSX_METAL);
- break;
- case ID_GAME_ANDROID_ENABLELOWSPEC:
- Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_ANDROID);
- break;
- case ID_GAME_ANDROID_ENABLEMEDIUMSPEC:
- Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_ANDROID);
- break;
- case ID_GAME_ANDROID_ENABLEHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_ANDROID);
- break;
- case ID_GAME_ANDROID_ENABLEVERYHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_ANDROID);
- break;
- case ID_GAME_IOS_ENABLELOWSPEC:
- Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_IOS);
- break;
- case ID_GAME_IOS_ENABLEMEDIUMSPEC:
- Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_IOS);
- break;
- case ID_GAME_IOS_ENABLEHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_IOS);
- break;
- case ID_GAME_IOS_ENABLEVERYHIGHSPEC:
- Commands::PySetConfigSpec(CONFIG_VERYHIGH_SPEC, CONFIG_IOS);
- break;
-#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
-#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
- case ID_GAME_##CODENAME##_ENABLELOWSPEC:\
- Commands::PySetConfigSpec(CONFIG_LOW_SPEC, CONFIG_##CODENAME);\
- break;\
- case ID_GAME_##CODENAME##_ENABLEMEDIUMSPEC:\
- Commands::PySetConfigSpec(CONFIG_MEDIUM_SPEC, CONFIG_##CODENAME);\
- break;\
- case ID_GAME_##CODENAME##_ENABLEHIGHSPEC:\
- Commands::PySetConfigSpec(CONFIG_HIGH_SPEC, CONFIG_##CODENAME);\
- break;
- AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
-#undef AZ_RESTRICTED_PLATFORM_EXPANSION
-#endif
- }
-}
-
-
-
namespace AzToolsFramework
{
void CryEditPythonHandler::Reflect(AZ::ReflectContext* context)
diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp
index 1cfc3b6dd0..3f86260f8d 100644
--- a/Code/Editor/EditorViewportWidget.cpp
+++ b/Code/Editor/EditorViewportWidget.cpp
@@ -458,25 +458,7 @@ void EditorViewportWidget::Update()
SetFOV(cameraState.m_fovOrZoom);
m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip);
}
- else if (!ed_useNewCameraSystem)
- {
- m_renderViewport->GetViewportContext()->SetCameraTransform(LYTransformToAZTransform(m_Camera.GetMatrix()));
- }
- // Don't override the game mode FOV
- if (!GetIEditor()->IsInGameMode())
- {
- AZ::Matrix4x4 clipMatrix;
- AZ::MakePerspectiveFovMatrixRH(
- clipMatrix,
- GetFOV(),
- aznumeric_cast(width()) / aznumeric_cast(height()),
- m_Camera.GetNearPlane(),
- m_Camera.GetFarPlane(),
- true
- );
- m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix);
- }
// Reset the camera update flag now that we're finished updating our viewport context
m_updateCameraPositionNextTick = false;
@@ -632,7 +614,6 @@ void EditorViewportWidget::SetViewEntity(const AZ::EntityId& viewEntityId, bool
void EditorViewportWidget::ResetToViewSourceType(const ViewSourceType& viewSourceType)
{
LockCameraMovement(true);
- m_pCameraFOVVariable = nullptr;
m_viewEntityId.SetInvalid();
m_cameraObjectId = GUID_NULL;
m_viewSourceType = viewSourceType;
@@ -714,7 +695,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
if (m_renderViewport)
{
- m_renderViewport->GetControllerList()->SetEnabled(false);
+ m_renderViewport->SetInputProcessingEnabled(false);
}
}
break;
@@ -738,7 +719,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
if (m_renderViewport)
{
- m_renderViewport->GetControllerList()->SetEnabled(true);
+ m_renderViewport->SetInputProcessingEnabled(true);
}
break;
@@ -2547,13 +2528,26 @@ void EditorViewportWidget::CenterOnSliceInstance()
//////////////////////////////////////////////////////////////////////////
void EditorViewportWidget::SetFOV(float fov)
{
- if (m_pCameraFOVVariable)
+ if (m_viewEntityId.IsValid())
{
- m_pCameraFOVVariable->Set(fov);
+ Camera::CameraRequestBus::Event(m_viewEntityId, &Camera::CameraComponentRequests::SetFov, AZ::RadToDeg(fov));
}
else
{
m_camFOV = fov;
+ // Set the active camera's FOV
+ {
+ AZ::Matrix4x4 clipMatrix;
+ AZ::MakePerspectiveFovMatrixRH(
+ clipMatrix,
+ GetFOV(),
+ aznumeric_cast(width()) / aznumeric_cast(height()),
+ m_Camera.GetNearPlane(),
+ m_Camera.GetFarPlane(),
+ true
+ );
+ m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix);
+ }
}
if (m_viewPane)
@@ -2580,13 +2574,7 @@ float EditorViewportWidget::GetFOV() const
}
}
- if (m_pCameraFOVVariable)
- {
- float fov;
- m_pCameraFOVVariable->Get(fov);
- return fov;
- }
- else if (m_viewEntityId.IsValid())
+ if (m_viewEntityId.IsValid())
{
float fov = AZ::RadToDeg(m_camFOV);
Camera::CameraRequestBus::EventResult(fov, m_viewEntityId, &Camera::CameraComponentRequests::GetFov);
@@ -2970,7 +2958,12 @@ void EditorViewportWidget::RestoreViewportAfterGameMode()
{
Matrix34 preGameModeViewTM = m_preGameModeViewTM;
- QString text = QString("You are exiting Game Mode. Would you like to restore the camera in the viewport to where it was before you entered Game Mode?This option can always be changed in the General Preferences tab of the Editor Settings, by toggling the \"%1\" option. ").arg(EditorPreferencesGeneralRestoreViewportCameraSettingName);
+ QString text =
+ QString(
+ tr("When leaving \" Game Mode \" the engine will automatically restore your camera position to the default position before you "
+ "had entered Game mode.If you dislike this setting you can always change this anytime in the global "
+ "preferences. "))
+ .arg(EditorPreferencesGeneralRestoreViewportCameraSettingName);
QString restoreOnExitGameModePopupDisabledRegKey("Editor/AutoHide/ViewportCameraRestoreOnExitGameMode");
// Read the popup disabled registry value
@@ -2985,6 +2978,7 @@ void EditorViewportWidget::RestoreViewportAfterGameMode()
messageBox.setDefaultButton(QMessageBox::Yes);
QCheckBox* checkBox = new QCheckBox(QStringLiteral("Do not show this message again"));
+ checkBox->setChecked(true);
messageBox.setCheckBox(checkBox);
// Unconstrain the system cursor and make it visible before we show the dialog box, otherwise the user can't see the cursor.
diff --git a/Code/Editor/EditorViewportWidget.h b/Code/Editor/EditorViewportWidget.h
index a395ef50a4..69015dcc79 100644
--- a/Code/Editor/EditorViewportWidget.h
+++ b/Code/Editor/EditorViewportWidget.h
@@ -506,7 +506,6 @@ protected:
CPredefinedAspectRatios m_predefinedAspectRatios;
- IVariable* m_pCameraFOVVariable = nullptr;
bool m_bCursorHidden = false;
void OnMenuResolutionCustom();
diff --git a/Code/Editor/GraphicsSettingsDialog.cpp b/Code/Editor/GraphicsSettingsDialog.cpp
deleted file mode 100644
index dbd7a7fc1a..0000000000
--- a/Code/Editor/GraphicsSettingsDialog.cpp
+++ /dev/null
@@ -1,1392 +0,0 @@
-/*
- * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
-#include
-#include
-#include
-#include "ProjectDefines.h"
-#include "EditorDefs.h"
-
-#include "GraphicsSettingsDialog.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-// AzFramework
-#include
-#include
-#include
-#include
-
-// Editor
-#include "Util/AutoDirectoryRestoreFileDialog.h"
-
-AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
-#include "ui_graphicssettingsdialog.h"
-AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
-
-QString groupNames[] =
-{
- "Game Effects",
- "Light",
- "Object Detail",
- "Particles",
- "Physics",
- "Post Processing",
- "Quality",
- "Shading",
- "Shadows",
- "Sound",
- "Texture",
- "Texture Resolution",
- "Volumetric Effects",
- "Water",
- "Miscellaneous"
-};
-
-GraphicsSettingsDialog::GraphicsSettingsDialog(QWidget* parent /* = nullptr */)
- : QDialog(parent)
- , m_ui(new Ui::GraphicsSettingsDialog())
-{
- //Update qlabel color when disabled
- setStyleSheet("QLabel::disabled{color: gray;}");
-
- // Start initialization the dialog
- m_ui->setupUi(this);
- setWindowTitle("Graphics Settings");
- m_ui->m_applyButton->setDefault(true);
- m_headerView = new GraphicsSettingsHeaderView(this, Qt::Horizontal);
- m_headerView->setMouseTracking(true);
- m_ui->m_graphicsSettingsTreeView->setHeader(m_headerView);
- /////////////////////////////////////////////
-
- m_currentPlatform = GetISystem()->GetConfigPlatform();
- m_currentSpecIndex = 0;
- m_dirtyCVarCount = 0;
-
- m_showCustomSpec = true;
- ShowCustomSpecOption(false);
-
- // Show categories, disable apply button
- m_showCategories = true;
- m_ui->m_applyButton->setEnabled(false);
-
- m_graphicsSettingsModel = new GraphicsSettingsModel(this);
- m_ui->m_graphicsSettingsTreeView->setModel(m_graphicsSettingsModel);
-
- m_cfgFiles[CONFIG_PC].push_back("pc_low.cfg");
- m_cfgFiles[CONFIG_PC].push_back("pc_medium.cfg");
- m_cfgFiles[CONFIG_PC].push_back("pc_high.cfg");
- m_cfgFiles[CONFIG_PC].push_back("pc_veryhigh.cfg");
- m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_low.cfg");
- m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_medium.cfg");
- m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_high.cfg");
- m_cfgFiles[CONFIG_OSX_METAL].push_back("osx_metal_veryhigh.cfg");
- m_cfgFiles[CONFIG_ANDROID].push_back("android_low.cfg");
- m_cfgFiles[CONFIG_ANDROID].push_back("android_medium.cfg");
- m_cfgFiles[CONFIG_ANDROID].push_back("android_high.cfg");
- m_cfgFiles[CONFIG_ANDROID].push_back("android_veryhigh.cfg");
- m_cfgFiles[CONFIG_IOS].push_back("ios_low.cfg");
- m_cfgFiles[CONFIG_IOS].push_back("ios_medium.cfg");
- m_cfgFiles[CONFIG_IOS].push_back("ios_high.cfg");
- m_cfgFiles[CONFIG_IOS].push_back("ios_veryhigh.cfg");
-#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
-#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
- m_cfgFiles[CONFIG_##CODENAME].push_back(#publicname "_low.cfg");\
- m_cfgFiles[CONFIG_##CODENAME].push_back(#publicname "_medium.cfg");\
- m_cfgFiles[CONFIG_##CODENAME].push_back(#publicname "_high.cfg");
- AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
-#undef AZ_RESTRICTED_PLATFORM_EXPANSION
-#endif
- // Since the layout order is set by the .ui file we need to match the order here so that tabbing works correctly.
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_gameeffects.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_light.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_objectdetail.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_particles.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_physics.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_postprocessing.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_quality.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_shading.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_shadows.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_sound.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_texture.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_textureresolution.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_volumetriceffects.cfg");
- m_cvarGroupOrder.push_back("Config/CVarGroups/sys_spec_water.cfg");
- m_cvarGroupOrder.push_back("miscellaneous");
-
- m_platformStrings.push_back(AZStd::make_pair("PC", CONFIG_PC));
- m_platformStrings.push_back(AZStd::make_pair("OSX Metal", CONFIG_OSX_METAL));
- m_platformStrings.push_back(AZStd::make_pair("Android", CONFIG_ANDROID));
- m_platformStrings.push_back(AZStd::make_pair("iOS", CONFIG_IOS));
-#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
-#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
- m_platformStrings.push_back(AZStd::make_pair(PublicAuxName2, CONFIG_##CODENAME));
- AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
-#undef AZ_RESTRICTED_PLATFORM_EXPANSION
-#endif
- m_platformStrings.push_back(AZStd::make_pair("Custom", CONFIG_INVALID_PLATFORM));
-
- for (auto& platformString : m_platformStrings)
- {
- QString platform = platformString.first.c_str();
- m_ui->m_platformEntry->addItem(platform);
- }
-
- QSettings settings("O3DE", "O3DE");
- settings.beginGroup("GraphicsSettingsDialog");
-
- if (settings.contains("Platform"))
- {
- QString platformName = settings.value("Platform").toString();
- AZStd::string azPlatform = platformName.toUtf8().data();
- m_currentPlatform = GetConfigPlatformFromName(azPlatform);
- if (m_currentPlatform == CONFIG_INVALID_PLATFORM)
- {
- ShowCustomSpecOption(true);
- }
- }
-
- settings.endGroup();
-
- SetPlatformEntry(m_currentPlatform);
-
- BuildUI();
-
- connect(m_ui->m_graphicsSettingsTreeView, &QTreeView::collapsed, this, [&](const QModelIndex& index) { SetCollapsed(index, true); });
- connect(m_ui->m_graphicsSettingsTreeView, &QTreeView::expanded, this, [&](const QModelIndex& index) { SetCollapsed(index, false); });
-
- AzQtComponents::StyleManager::setStyleSheet(this, "style:GraphicsSettingsDialog.qss");
-}
-
-GraphicsSettingsDialog::~GraphicsSettingsDialog()
-{
- QSettings settings("O3DE", "O3DE");
- settings.beginGroup("GraphicsSettingsDialog");
-
- auto platformCheck = [this](AZStd::pair& stringConfigPair) { return stringConfigPair.second == m_currentPlatform; };
- auto platformStringsIterator = AZStd::find_if(m_platformStrings.begin(), m_platformStrings.end(), platformCheck);
- if (platformStringsIterator != m_platformStrings.end())
- {
- settings.setValue("Platform", platformStringsIterator->first.c_str());
- }
- else
- {
- settings.remove("Platform");
- }
-
- settings.beginGroup("cvarGroup");
-
- for (auto& collapseIterator : m_uiCollapseGroup)
- {
- settings.setValue(collapseIterator->m_groupName, collapseIterator->m_isCollapsed);
- }
-
- settings.endGroup();
- settings.endGroup();
- settings.sync();
-
- for (CollapseGroup* group : m_uiCollapseGroup)
- {
- // Destructor of CollapseGroup will set the members
- // pointing to nullptr. The actually destruction of the
- // widgets will be done on destruction of m_ui
- delete group;
- }
-
- for (ParameterWidget* widget : m_parameterWidgets)
- {
- // Destructor of ParameterWidget will set the members
- // pointing to nullptr. The actually destruction of the
- // widgets will be done on destruction of m_ui
- delete widget;
- }
-
- // Delete m_ui will destruct all the UI elements with in the ui file
- // Since m_ui is a QScopedPointer which will cleanup itself on the end
- // of the scope.
-}
-
-void GraphicsSettingsDialog::SetSettingsTree(int numColumns)
-{
- m_graphicsSettingsModel->clear();
- m_uiCollapseGroup.clear();
- m_graphicsSettingsModel->setColumnCount(numColumns);
-
- for (int i = 1; i < numColumns; ++i)
- {
- m_ui->m_graphicsSettingsTreeView->header()->setSectionResizeMode(i, QHeaderView::Stretch);
- }
-
- m_ui->m_graphicsSettingsTreeView->setColumnWidth(0, 200);
- m_ui->m_graphicsSettingsTreeView->header()->setMinimumSectionSize(100);
-
- m_graphicsSettingsModel->setHeaderData(0, Qt::Horizontal, "Properties");
-
- auto parentItem = m_graphicsSettingsModel->invisibleRootItem();
-
- for (int i = 0; i < aznumeric_cast(GraphicsSettings::numSettings); ++i)
- {
- QStandardItem* row = new QStandardItem();
- row->setData(groupNames[i], Qt::DisplayRole);
- parentItem->appendRow(row);
- SetCollapsedLayout(groupNames[i].replace(" ", ""), row);
- }
- m_numColumns = numColumns;
-
- m_cvarGroupData["Config/CVarGroups/sys_spec_gameeffects.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::GameEffects));
- m_cvarGroupData["Config/CVarGroups/sys_spec_light.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Light));
- m_cvarGroupData["Config/CVarGroups/sys_spec_objectdetail.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::ObjectDetail));
- m_cvarGroupData["Config/CVarGroups/sys_spec_particles.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Particles));
- m_cvarGroupData["Config/CVarGroups/sys_spec_physics.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Physics));
- m_cvarGroupData["Config/CVarGroups/sys_spec_postprocessing.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::PostProcessing));
- m_cvarGroupData["Config/CVarGroups/sys_spec_quality.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Quality));
- m_cvarGroupData["Config/CVarGroups/sys_spec_shading.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Shading));
- m_cvarGroupData["Config/CVarGroups/sys_spec_shadows.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Shadows));
- m_cvarGroupData["Config/CVarGroups/sys_spec_sound.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Sound));
- m_cvarGroupData["Config/CVarGroups/sys_spec_texture.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Texture));
- m_cvarGroupData["Config/CVarGroups/sys_spec_textureresolution.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::TextureResolution));
- m_cvarGroupData["Config/CVarGroups/sys_spec_volumetriceffects.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::VolumetricEffects));
- m_cvarGroupData["Config/CVarGroups/sys_spec_water.cfg"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Water));
- m_cvarGroupData["miscellaneous"].m_treeRowItem = m_graphicsSettingsModel->item(aznumeric_cast(GraphicsSettings::Miscellaneous));
-}
-
-void GraphicsSettingsDialog::OnLoadConfigurationEntry(const char* strKey, const char* strValue, const char* strGroup)
-{
- AZStd::string key = strKey;
- ICVar* cvar = gEnv->pConsole->GetCVar(strKey);
-
- if (cvar)
- {
- AZStd::transform(key.begin(), key.end(), key.begin(), tolower);
- if (azstricmp(key.c_str(), "sys_spec_full") == 0 || key.find("sys_spec_") == key.npos)
- {
- int type = cvar->GetType();
- AZStd::any val;
- if (type == CVAR_INT)
- {
- val = atoi(strValue);
- }
- else if (type == CVAR_FLOAT)
- {
- val = static_cast(atof(strValue));
- }
- else
- {
- val = AZStd::string(strValue);
- }
-
- // Platform cfg file (ex. pc_veryhigh.cfg)
- if (strGroup[0] == '\0')
- {
- // New cvar loaded into map
- if (m_cVarTracker.find(key) == m_cVarTracker.end())
- {
- m_cVarTracker[key].type = type;
- m_cVarTracker[key].cvarGroup = "miscellaneous";
- AZStd::any empty;
- if (type == CVAR_INT)
- {
- empty = 0;
- }
- else if (type == CVAR_FLOAT)
- {
- empty = 0.0f;
- }
- else
- {
- empty = AZStd::string("");
- }
- m_cVarTracker[key].fileVals.resize(m_numSpecLevels, CVarFileStatus(empty, empty, empty));
- }
-
- m_cVarTracker[key].fileVals[m_currentSpecIndex].editedValue = val;
- m_cVarTracker[key].fileVals[m_currentSpecIndex].overwrittenValue = val;
- }
- // default group in sys_spec cfg file
- else if (azstricmp(strGroup, "default") == 0)
- {
- CVarFileStatus defaultVal(val, val, val);
- if (m_cVarTracker.find(key) == m_cVarTracker.end())
- {
- // New cvar loaded into map
- CVarInfo& currentCVar = m_cVarTracker[key];
- currentCVar.type = cvar->GetType();
- currentCVar.fileVals.resize(m_numSpecLevels, defaultVal);
- }
- else
- {
- // Reset values, if there's a platform override it always follows the sys_spec_*.cfg files.
- // Resetting avoids the issue where some spec levels are never set because of an extra platform
- // override load happening earlier just to store the value of sys_spec_full.
- for (int specLevel = 0; specLevel < m_numSpecLevels; ++specLevel)
- {
- m_cVarTracker[key].fileVals[specLevel] = defaultVal;
- }
- }
- // Overwrite miscellaneous if mentioned in platform config file
- m_cVarTracker[key].cvarGroup = m_currentConfigFilename;
- }
- // specific index in sys_spec cfg file
- else
- {
- int group = 0;
-
- if (azsscanf(strGroup, "%d", &group) == 1)
- {
- auto sysSpecFull = m_cVarTracker.find("sys_spec_full");
- if (sysSpecFull != m_cVarTracker.end())
- {
- CVarFileStatus indexAssignment(val, val, val);
- for (int specLevel = 0; specLevel < m_numSpecLevels; ++specLevel)
- {
- // Only apply cvar change to configurations with sys_spec_Full matching the index
- int overwrittenValue = 0;
- if (AZStd::any_numeric_cast(&sysSpecFull->second.fileVals[specLevel].overwrittenValue, overwrittenValue) && group == overwrittenValue)
- {
- m_cVarTracker[key].fileVals[specLevel] = indexAssignment;
- }
- }
- }
- }
- }
- }
- }
-}
-
-// Loads UI column for specific cfg file (ex. pc_low.cfg)
-void GraphicsSettingsDialog::BuildColumn(int specLevel)
-{
- if (specLevel < 0 || specLevel >= m_numSpecLevels)
- {
- return;
- }
-
- for (auto& it : m_cvarGroupData)
- {
- it.second.m_currentRow = 0;
- }
-
- for (auto& it : m_cVarTracker)
- {
- QString str = it.first.c_str();
- QWidget* input = nullptr;
- if (it.second.type == CVAR_INT)
- {
- AzQtComponents::SpinBox* intval = new AzQtComponents::SpinBox(nullptr);
- intval->setFocusPolicy(Qt::StrongFocus);
- intval->setMaximum(INT32_MAX);
- intval->setMinimum(INT32_MIN);
- int editedValue;
- if (AZStd::any_numeric_cast(&it.second.fileVals[specLevel].editedValue, editedValue))
- {
- intval->setValue(editedValue);
- }
- m_cvarGroupData[it.second.cvarGroup].m_cvarSpinBoxes.push_back(intval);
- connect(intval, SIGNAL(valueChanged(int)), this, SLOT(CVarChanged(int)));
- input = intval;
- }
- else if (it.second.type == CVAR_FLOAT)
- {
- AzQtComponents::DoubleSpinBox* doubleval = new AzQtComponents::DoubleSpinBox(nullptr);
- doubleval->setFocusPolicy(Qt::StrongFocus);
- doubleval->setMaximum(FLT_MAX);
- doubleval->setMinimum(-FLT_MAX);
- float editedValue;
- if (AZStd::any_numeric_cast(&it.second.fileVals[specLevel].editedValue, editedValue))
- {
- doubleval->setValue(editedValue);
- }
- m_cvarGroupData[it.second.cvarGroup].m_cvarDoubleSpinBoxes.push_back(doubleval);
- connect(doubleval, SIGNAL(valueChanged(double)), this, SLOT(CVarChanged(double)));
- input = doubleval;
- }
- else
- {
- QLineEdit* stringval = new QLineEdit(nullptr);
- AZStd::string* editedValue = AZStd::any_cast(&it.second.fileVals[specLevel].editedValue);
- stringval->setText(editedValue->c_str());
- m_cvarGroupData[it.second.cvarGroup].m_cvarLineEdits.push_back(stringval);
- connect(stringval, SIGNAL(textChanged(const QString&)), this, SLOT(CVarChanged(const QString&)));
- input = stringval;
- }
-
- if (input)
- {
- input->setObjectName(str);
- input->setProperty("specLevel", specLevel);
- QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- sizePolicy.setHeightForWidth(input->sizePolicy().hasHeightForWidth());
- input->setSizePolicy(sizePolicy);
- input->setMinimumSize(QSize(INPUT_MIN_WIDTH, INPUT_MIN_HEIGHT));
- QStandardItem* parentItem = m_cvarGroupData[it.second.cvarGroup].m_treeRowItem;
- QModelIndex parentIndex = parentItem->index();
- QModelIndex thisIndex = m_graphicsSettingsModel->index(m_cvarGroupData[it.second.cvarGroup].m_currentRow++, specLevel + CVAR_VALUE_COLUMN_OFFSET, parentIndex);
- m_ui->m_graphicsSettingsTreeView->setIndexWidget(thisIndex, input);
- m_parameterWidgets.push_back(new ParameterWidget(input, it.first.c_str()));
- m_cvarGroupData[it.second.cvarGroup].m_widgetInsertOrder.push_back(input);
- }
- }
-}
-
-void GraphicsSettingsDialog::LoadPlatformConfigurations()
-{
- const int numColumns = m_cfgFiles[m_currentPlatform].size() + 1;
- SetSettingsTree(numColumns);
-
- for (ParameterWidget* widget : m_parameterWidgets)
- {
- delete widget;
- }
- m_parameterWidgets.clear();
-
- m_ui->m_applyButton->setEnabled(false);
- m_dirtyCVarCount = 0;
-
- // Load platform cfg files to load in sys_spec_Full
- for (size_t cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex)
- {
- m_currentSpecIndex = cfgFileIndex;
- m_currentConfigFilename = m_cfgFiles[m_currentPlatform][cfgFileIndex];
- GetISystem()->LoadConfiguration(m_currentConfigFilename.c_str(), this, true);
- }
-
- if (m_cVarTracker.find("sys_spec_full") == m_cVarTracker.end())
- {
- m_cVarTracker.clear();
- CleanUI();
- ShowCategories(false);
- QMessageBox::warning(this, "Warning", "Invalid custom spec file (missing sys_spec_full).",
- QMessageBox::Ok);
- return;
- }
-
- // Load sys_spec cfgs based on sys_spec_Full values
- LoadCVarGroupDirectory(m_cvarGroupsFolder);
-
- setUpdatesEnabled(false);
-
- // Reload platform cfg files to override sys_spec index assignments and load rows with filenames of given platform
- for (size_t cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex)
- {
- m_currentSpecIndex = cfgFileIndex;
- m_currentConfigFilename = m_cfgFiles[m_currentPlatform][cfgFileIndex];
- GetISystem()->LoadConfiguration(m_currentConfigFilename.c_str(), this, true);
-
- /*CVarGroupInfo& specFileGroup =*/ m_cvarGroupData["SpecFile"];
- m_graphicsSettingsModel->setHeaderData(cfgFileIndex + CVAR_VALUE_COLUMN_OFFSET, Qt::Horizontal, QApplication::translate("GraphicsSettingsDialog", m_cfgFiles[m_currentPlatform][cfgFileIndex].c_str()));
- }
-
- // Loads column of cvar names
- for (auto& it : m_cVarTracker)
- {
- QLabel* cVarLabel = new QLabel(nullptr);
- QString str = it.first.c_str();
- QString strLabel = str + "Label";
- cVarLabel->setObjectName(strLabel);
- QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
- sizePolicy.setHeightForWidth(cVarLabel->sizePolicy().hasHeightForWidth());
- cVarLabel->setSizePolicy(sizePolicy);
- cVarLabel->setMinimumSize(QSize(INPUT_MIN_WIDTH, INPUT_MIN_HEIGHT));
- cVarLabel->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
- QStandardItem* cVarItem = new QStandardItem();
- cVarItem->setData(QApplication::translate("GraphicsSettingsDialog", it.first.c_str(), 0), Qt::DisplayRole);
- QList items{ cVarItem };
- for (int i = 1; i < numColumns; ++i)
- {
- items << new QStandardItem();
- }
- m_cvarGroupData[it.second.cvarGroup].m_treeRowItem->appendRow(items);
- cVarLabel->setText(QApplication::translate("GraphicsSettingsDialog", it.first.c_str(), 0));
- m_cvarGroupData[it.second.cvarGroup].m_cvarLabels.push_back(cVarLabel);
-
- if (ICVar* cvar = gEnv->pConsole->GetCVar(it.first.c_str()))
- {
- cVarLabel->setToolTip(cvar->GetHelp());
- }
- }
-
- // Loads columns of cvar values for each platform cfg file
- for (int cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex)
- {
- BuildColumn(cfgFileIndex);
- }
-
- // Remove any section that has no visible controls
- for (auto& it : m_cvarGroupData)
- {
- int totalControlCount = 0;
- CVarGroupInfo& currentCvarGroupInfo = it.second;
- totalControlCount += currentCvarGroupInfo.m_cvarDoubleSpinBoxes.size();
- totalControlCount += currentCvarGroupInfo.m_cvarSpinBoxes.size();
- totalControlCount += currentCvarGroupInfo.m_cvarLineEdits.size();
- totalControlCount += currentCvarGroupInfo.m_platformLabels.size();
-
- if (totalControlCount == 0)
- {
- if (currentCvarGroupInfo.m_treeRowItem)
- {
- int i = 0;
- for (auto& collapseIterator : m_uiCollapseGroup)
- {
- if (collapseIterator->m_groupRow == currentCvarGroupInfo.m_treeRowItem)
- {
- m_uiCollapseGroup.remove(i);
- break;
- }
- ++i;
- }
- m_graphicsSettingsModel->removeRow(currentCvarGroupInfo.m_treeRowItem->row());
- }
- }
- }
-
- setUpdatesEnabled(true);
-
- QSettings settings("O3DE", "O3DE");
- settings.beginGroup("GraphicsSettingsDialog");
- settings.beginGroup("cvarGroup");
-
- for (auto& collapseIterator : m_uiCollapseGroup)
- {
- bool groupCollapsed = settings.value(collapseIterator->m_groupName, collapseIterator->m_isCollapsed).toBool();
- if (collapseIterator->m_isCollapsed != groupCollapsed)
- {
- collapseIterator->ToggleCollapsed();
- }
- }
-
- settings.endGroup();
- settings.endGroup();
-}
-
-void GraphicsSettingsDialog::LoadCVarGroupDirectory(const AZStd::string& path)
-{
- AZ::IO::LocalFileIO::FindFilesCallbackType fileFinderCb;
- fileFinderCb = [&](const char* fullPath) -> bool
- {
- if (gEnv->pFileIO->IsDirectory(fullPath))
- {
- // recurse into subdirectory
- gEnv->pFileIO->FindFiles(fullPath, "*.cfg", fileFinderCb);
- }
- else
- {
- m_currentConfigFilename = fullPath;
- GetISystem()->LoadConfiguration(fullPath, this, false);
- }
-
- return true; // keep searching
- };
-
- gEnv->pFileIO->FindFiles(path.c_str(), "*.cfg", fileFinderCb);
-}
-
-//Build UI, link signals and set the data for device list.
-void GraphicsSettingsDialog::BuildUI()
-{
- connect(m_ui->m_cancelButton, &QPushButton::clicked, this, &GraphicsSettingsDialog::reject);
- connect(m_ui->m_applyButton, &QPushButton::clicked, this, &GraphicsSettingsDialog::accept);
- connect(m_ui->m_platformEntry, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(PlatformChanged(const QString&)));
- connect(m_ui->m_selectCustomSpecButton, &QPushButton::clicked, this, &GraphicsSettingsDialog::OpenCustomSpecDialog);
-
- if (!m_cfgFiles[m_currentPlatform].empty())
- {
- LoadPlatformConfigurations();
- }
- else
- {
- m_cVarTracker.clear();
- CleanUI();
- ShowCategories(false);
- }
-}
-
-void GraphicsSettingsDialog::CleanUI()
-{
- setUpdatesEnabled(false);
-
- QSettings settings("O3DE", "O3DE");
- settings.beginGroup("GraphicsSettingsDialog");
- settings.beginGroup("cvarGroup");
-
- for (auto& collapseIterator : m_uiCollapseGroup)
- {
- settings.setValue(collapseIterator->m_groupName, collapseIterator->m_isCollapsed);
- }
-
- settings.endGroup();
- settings.endGroup();
- settings.sync();
-
- m_cVarTracker.clear();
-
- // Uncollapse groups
- for (auto& collapseIt : m_uiCollapseGroup)
- {
- if (collapseIt->m_isCollapsed)
- {
- collapseIt->ToggleCollapsed();
- }
- }
-
- setUpdatesEnabled(true);
-}
-
-void GraphicsSettingsDialog::ShowCategories(bool show)
-{
- if (m_showCategories == show)
- {
- return;
- }
-
- m_showCategories = show;
- m_ui->m_graphicsSettingsTreeView->setVisible(show);
-}
-
-void GraphicsSettingsDialog::ShowCustomSpecOption(bool show)
-{
- if (m_showCustomSpec == show)
- {
- return;
- }
-
- m_showCustomSpec = show;
- m_ui->m_selectCustomSpecButton->setVisible(m_showCustomSpec);
- m_ui->m_lineSpacer->setVisible(m_showCustomSpec);
-}
-
-void GraphicsSettingsDialog::PlatformChanged(const QString& platform)
-{
- bool change = true;
- if (m_dirtyCVarCount > 0 && !SendUnsavedChangesWarning(false))
- {
- change = false;
- }
-
- if (change)
- {
- AZStd::string azPlatform = platform.toStdString().c_str();
-
- m_currentPlatform = GetConfigPlatformFromName(azPlatform);
- if (m_currentPlatform == CONFIG_INVALID_PLATFORM) // "Custom" selected
- {
- ShowCustomSpecOption(true);
- CleanUI();
- if (m_cfgFiles[CONFIG_INVALID_PLATFORM].empty()) // if we don't have a custom spec
- {
- ShowCategories(false);
- m_ui->m_applyButton->setEnabled(false);
- m_dirtyCVarCount = 0;
- }
- else
- {
- ShowCategories(true);
- LoadPlatformConfigurations();
- }
- }
- else
- {
- ShowCustomSpecOption(false);
- ShowCategories(true);
- CleanUI();
- LoadPlatformConfigurations();
- }
- }
- else
- {
- m_ui->m_platformEntry->blockSignals(true);
- SetPlatformEntry(m_currentPlatform);
- m_ui->m_platformEntry->blockSignals(false);
- }
-}
-
-bool GraphicsSettingsDialog::SendUnsavedChangesWarning(bool cancel)
-{
- int result = QMessageBox::Yes;
-
- if (cancel)
- {
- result = QMessageBox::question(this, "Warning", "There are currently unsaved changed. Are you sure you want to cancel?",
- QMessageBox::Yes, QMessageBox::No);
- }
- else
- {
- result = QMessageBox::question(this, "Warning", "There are currently unsaved changed. Are you sure you want to change configurations?",
- QMessageBox::Yes, QMessageBox::No);
- }
-
- return (result == QMessageBox::Yes);
-}
-
-bool GraphicsSettingsDialog::CVarChanged(AZStd::any val, const char* cvarName, int specLevel)
-{
- // Checking if the edited value (before change) is equal to the overwritten value
- bool dirtyBefore = false;
- AZStd::string azcvarName = cvarName;
- AZStd::pair cvarInfo = AZStd::make_pair(azcvarName, m_cVarTracker[cvarName]);
- if (CheckCVarStatesForDiff(&cvarInfo, specLevel, EDITED_OVERWRITTEN_COMPARE))
- {
- dirtyBefore = true;
- }
-
- if (azstricmp(cvarName, "sys_spec_full") == 0)
- {
- //Pop out the warning dialog for sys_spec_Full since all cvars will be changed
- int result = QMessageBox::Ok;
-
- result = QMessageBox::question(this, "Warning", "Modifying sys_spec_full will override any unsaved changes.",
- QMessageBox::Ok, QMessageBox::Cancel);
-
- // Cancel - Change sys_spec_full qspinbox value back
- if (result == QMessageBox::Cancel)
- {
- return false;
- }
- else // OK - reload column
- {
- // Updating sys_spec_full for when adding cvargroup directory
- m_cVarTracker[cvarName].fileVals[specLevel].editedValue = val;
- gEnv->pSystem->AddCVarGroupDirectory(m_cvarGroupsFolder);
- m_currentConfigFilename = m_cfgFiles[m_currentPlatform][specLevel];
- m_currentSpecIndex = specLevel;
- GetISystem()->LoadConfiguration(m_currentConfigFilename.c_str(), this, true);
- // Updating sys_spec_full since overwritten from loading platform cfg
- m_cVarTracker[cvarName].fileVals[specLevel].editedValue = val;
- BuildColumn(specLevel);
- }
- }
- else
- {
- m_cVarTracker[cvarName].fileVals[specLevel].editedValue = val;
- }
-
- // Checking if the newly edited value is equal to the overwritten value
- cvarInfo = AZStd::make_pair(azcvarName, m_cVarTracker[cvarName]);
- if (CheckCVarStatesForDiff(&cvarInfo, specLevel, EDITED_OVERWRITTEN_COMPARE))
- {
- if (!dirtyBefore)
- {
- m_ui->m_applyButton->setEnabled(true);
- m_dirtyCVarCount++;
- }
- }
- else
- {
- if (dirtyBefore)
- {
- m_dirtyCVarCount--;
- if (m_dirtyCVarCount == 0)
- {
- m_ui->m_applyButton->setEnabled(false);
- }
- }
- }
-
- return true;
-}
-
-void GraphicsSettingsDialog::CVarChanged(int i)
-{
- AzQtComponents::SpinBox* box = static_cast(sender());
- QString str = box->objectName();
- QByteArray ba = str.toUtf8();
- const char* cvarName = ba.data();
-
- int specLevel = box->property("specLevel").toInt();
-
- AZStd::any val;
- val = i;
-
- if (!CVarChanged(val, cvarName, specLevel))
- {
- // sys_spec_full warning cancelled
- box->blockSignals(true);
- int editedValue;
- if (AZStd::any_numeric_cast(&m_cVarTracker[cvarName].fileVals[specLevel].editedValue, editedValue))
- {
- box->setValue(editedValue);
- }
- box->blockSignals(false);
- }
-}
-
-void GraphicsSettingsDialog::CVarChanged(double d)
-{
- AzQtComponents::DoubleSpinBox* box = static_cast(sender());
- QString str = box->objectName();
- QByteArray ba = str.toUtf8();
- const char* cvarName = ba.data();
-
- AZStd::any val;
- val = d;
-
- int specLevel = box->property("specLevel").toInt();
-
- if (!CVarChanged(val, cvarName, specLevel))
- {
- // only can return false from sys_spec_full, which is an int cvar
- }
-}
-
-void GraphicsSettingsDialog::CVarChanged(const QString& s)
-{
- QLineEdit* box = qobject_cast(sender());
- QString str = box->objectName();
- QByteArray ba = str.toUtf8();
- const char* cvarName = ba.data();
-
- AZStd::any val;
- val = AZStd::string(s.toStdString().c_str());
-
- int specLevel = box->property("specLevel").toInt();
-
- if (!CVarChanged(val, cvarName, specLevel))
- {
- // only can return false from sys_spec_full, which is an int cvar
- }
-}
-
-// Returns true if there is a difference between the two cvar states
-bool GraphicsSettingsDialog::CheckCVarStatesForDiff(AZStd::pair* it, int cfgFileIndex, CVarStateComparison cmp)
-{
- if (it->second.type == CVAR_INT)
- {
- int editedVal, overwrittenVal, originalVal;
- if (AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].editedValue, editedVal) &&
- AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].overwrittenValue, overwrittenVal) &&
- AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].originalValue, originalVal))
- {
- if ((cmp == EDITED_OVERWRITTEN_COMPARE && editedVal != overwrittenVal) ||
- (cmp == EDITED_ORIGINAL_COMPARE && editedVal != originalVal) ||
- (cmp == OVERWRITTEN_ORIGINAL_COMPARE && overwrittenVal != originalVal))
- {
- return true;
- }
- }
- }
- else if (it->second.type == CVAR_FLOAT)
- {
- float editedVal, overwrittenVal, originalVal;
- if (AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].editedValue, editedVal) &&
- AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].overwrittenValue, overwrittenVal) &&
- AZStd::any_numeric_cast(&it->second.fileVals[cfgFileIndex].originalValue, originalVal))
- {
- if ((cmp == EDITED_OVERWRITTEN_COMPARE && editedVal != overwrittenVal) ||
- (cmp == EDITED_ORIGINAL_COMPARE && editedVal != originalVal) ||
- (cmp == OVERWRITTEN_ORIGINAL_COMPARE && overwrittenVal != originalVal))
- {
- return true;
- }
- }
- }
- else
- {
- AZStd::string editedVal = *AZStd::any_cast(&it->second.fileVals[cfgFileIndex].editedValue);
- AZStd::string overwrittenVal = *AZStd::any_cast(&it->second.fileVals[cfgFileIndex].overwrittenValue);
- AZStd::string originalVal = *AZStd::any_cast(&it->second.fileVals[cfgFileIndex].originalValue);
- if ((cmp == EDITED_OVERWRITTEN_COMPARE && editedVal.compare(overwrittenVal) != 0) ||
- (cmp == EDITED_ORIGINAL_COMPARE && editedVal.compare(originalVal) != 0) ||
- (cmp == OVERWRITTEN_ORIGINAL_COMPARE && overwrittenVal.compare(originalVal) != 0))
- {
- return true;
- }
- }
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////
-// settings file management
-void GraphicsSettingsDialog::reject()
-{
- if (m_dirtyCVarCount > 0)
- {
- if (SendUnsavedChangesWarning(true))
- {
- QDialog::reject();
- }
- }
- else
- {
- QDialog::reject();
- }
-}
-
-void GraphicsSettingsDialog::accept()
-{
- int result = QMessageBox::Yes;
-
- //Pop out the warning dialog for customized setting
- result = QMessageBox::question(this, "Warning", "A non-tested setting could potentially crash the game if the setting does not match the device. Are you sure you want to apply the customized setting?",
- QMessageBox::Yes, QMessageBox::No);
-
- //Save and exit
- if (result == QMessageBox::Yes)
- {
- SaveSystemSettings();
- }
-}
-
-void GraphicsSettingsDialog::OpenCustomSpecDialog()
-{
- AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
- projectPath /= SETTINGS_FILE_PATH.toUtf8().constData();
- QString settingsPath = QString::fromUtf8(projectPath.c_str(), aznumeric_cast(projectPath.Native().size()));
-
- CAutoDirectoryRestoreFileDialog importCustomSpecDialog(QFileDialog::AcceptOpen, QFileDialog::ExistingFile, ".cfg", settingsPath, CFG_FILEFILTER, {}, {}, this);
-
- if (importCustomSpecDialog.exec())
- {
- QString file = importCustomSpecDialog.selectedFiles().first();
- if (!file.isEmpty())
- {
- ApplyCustomSpec(file);
- }
- }
-}
-
-void GraphicsSettingsDialog::ApplyCustomSpec(const QString& customFilePath)
-{
- if (customFilePath.isEmpty())
- {
- return;
- }
-
- QFile customFile(customFilePath);
- if (!customFile.exists())
- {
- QMessageBox::warning(this, "Warning", "Could not find custom spec file.",
- QMessageBox::Ok);
- return;
- }
-
- bool change = true;
- if (m_dirtyCVarCount > 0 && !SendUnsavedChangesWarning(false))
- {
- change = false;
- }
-
- if (change)
- {
- AZStd::string filename = customFilePath.toStdString().c_str();
- filename = filename.substr(filename.find_last_of('/') + 1);
-
- m_currentPlatform = CONFIG_INVALID_PLATFORM;
-
- bool alreadyLoaded = IsCustomSpecAlreadyLoaded(filename);
- if (m_cfgFiles[CONFIG_INVALID_PLATFORM].size() < m_numSpecLevels && !alreadyLoaded)
- {
- m_cfgFiles[CONFIG_INVALID_PLATFORM].push_back(filename);
- }
- else if (alreadyLoaded)
- {
- QMessageBox::warning(this, "Warning", "The selected custom spec file is already loaded. No changes have been made.",
- QMessageBox::Ok);
- return;
- }
-
- if (m_cfgFiles[CONFIG_INVALID_PLATFORM].size() == m_numSpecLevels)
- {
- m_ui->m_selectCustomSpecButton->setEnabled(false);
- }
-
- ShowCategories(true);
-
- CleanUI();
-
- LoadPlatformConfigurations();
- }
-}
-
-void GraphicsSettingsDialog::UnloadCustomSpec(int specLevel)
-{
- if (specLevel < 0 || specLevel >= m_cfgFiles[CONFIG_INVALID_PLATFORM].size())
- {
- return;
- }
-
- bool shouldUnload = m_dirtyCVarCount <= 0 || SendUnsavedChangesWarning(false);
-
- if (shouldUnload)
- {
- m_cfgFiles[CONFIG_INVALID_PLATFORM].erase(m_cfgFiles[CONFIG_INVALID_PLATFORM].begin() + specLevel);
-
- CleanUI();
-
- if (!m_cfgFiles[CONFIG_INVALID_PLATFORM].empty())
- {
- LoadPlatformConfigurations();
- }
- else
- {
- ShowCategories(false);
- }
- }
-}
-
-bool GraphicsSettingsDialog::IsCustomSpecAlreadyLoaded(const AZStd::string& filename) const
-{
- auto& customConfigFilenames = m_cfgFiles.at(CONFIG_INVALID_PLATFORM);
- const auto& findResult = AZStd::find(customConfigFilenames.begin(), customConfigFilenames.end(), filename.c_str());
-
- return findResult != customConfigFilenames.end();
-}
-
-void GraphicsSettingsDialog::SetCollapsedLayout(const QString& groupName, QStandardItem* groupRow)
-{
- CollapseGroup* cgroup = new CollapseGroup(m_ui->m_graphicsSettingsTreeView);
- cgroup->m_groupName = groupName;
- cgroup->m_groupRow = groupRow;
- m_uiCollapseGroup.push_back(cgroup);
-}
-
-void GraphicsSettingsDialog::SetPlatformEntry(ESystemConfigPlatform platform)
-{
- auto platformCheck = [&platform](AZStd::pair& stringConfigPair) { return stringConfigPair.second == platform; };
- auto platformStringsIterator = AZStd::find_if(m_platformStrings.begin(), m_platformStrings.end(), platformCheck);
- if (platformStringsIterator != m_platformStrings.end())
- {
- int platformIndex = m_ui->m_platformEntry->findText(platformStringsIterator->first.c_str());
- m_ui->m_platformEntry->setCurrentIndex(platformIndex);
- }
- else
- {
- AZ_Assert(false, "Platform not found in platform strings vector.");
- }
-}
-
-ESystemConfigPlatform GraphicsSettingsDialog::GetConfigPlatformFromName(const AZStd::string& platformName)
-{
- ESystemConfigPlatform configPlatform = CONFIG_INVALID_PLATFORM;
-
- auto platformNameCheck = [&platformName](AZStd::pair& stringConfigPair) { return (stringConfigPair.first == platformName); };
- auto configPlatformIterator = AZStd::find_if(m_platformStrings.begin(), m_platformStrings.end(), platformNameCheck);
- if (configPlatformIterator != m_platformStrings.end())
- {
- configPlatform = configPlatformIterator->second;
- }
- else
- {
- AZ_Assert(false, "Platform name not found in platform strings vector.");
- }
-
- return configPlatform;
-}
-
-// Save the current UI options to system qsettings
-void GraphicsSettingsDialog::SaveSystemSettings()
-{
- AZStd::vector successFiles;
- AZStd::vector nochangeFiles;
-
- for (int cfgFileIndex = 0; cfgFileIndex < m_cfgFiles[m_currentPlatform].size(); ++cfgFileIndex)
- {
- const QString eq = " = ";
- const QString cvarGroupString1 = "\n------------------------\n-- ";
- const QString cvarGroupString2 = "\n------------------------\n";
- QString commandList = "";
-
- int sysSpecFull;
- if (AZStd::any_numeric_cast(&m_cVarTracker["sys_spec_full"].fileVals[cfgFileIndex].editedValue, sysSpecFull))
- {
- commandList += "sys_spec_full" + eq + QString::number(sysSpecFull) + '\n';
- }
-
- QMap cvarGroupStrings;
-
- // Set to true as soon as cvar is found which is unique from current cfg file and index assignment
- bool saveOut = false;
-
- // Adding any dirty cvars not equal to sys_spec_full or any cvar in miscellaneous to command list
- for (auto& it : m_cVarTracker)
- {
- if ((CheckCVarStatesForDiff(&it, cfgFileIndex, EDITED_ORIGINAL_COMPARE) || it.second.cvarGroup == "miscellaneous") && azstricmp(it.first.c_str(), "sys_spec_full"))
- {
- AZStd::string cvarGroup = it.second.cvarGroup;
- if (azstricmp(cvarGroup.c_str(), "miscellaneous") != 0)
- {
- int fileIndex = cvarGroup.find_last_of('/') + 1;
- cvarGroup = cvarGroup.substr(fileIndex, cvarGroup.size() - fileIndex - 4);
- }
- QString qcvarGroup = cvarGroup.c_str();
- if (cvarGroupStrings.find(qcvarGroup) == cvarGroupStrings.end())
- {
- cvarGroupStrings[qcvarGroup] = cvarGroupString1 + qcvarGroup + cvarGroupString2;
- }
-
- if (it.second.type == CVAR_INT)
- {
- int val;
- if (AZStd::any_numeric_cast(&it.second.fileVals[cfgFileIndex].editedValue, val))
- {
- cvarGroupStrings[qcvarGroup] += it.first.c_str() + eq + QString::number(val) + '\n';
- }
- }
- else if (it.second.type == CVAR_FLOAT)
- {
- float val;
- if (AZStd::any_numeric_cast(&it.second.fileVals[cfgFileIndex].editedValue, val))
- {
- cvarGroupStrings[qcvarGroup] += it.first.c_str() + eq + QString::number(val) + '\n';
- }
- }
- else
- {
- cvarGroupStrings[qcvarGroup] += it.first.c_str() + eq + AZStd::any_cast(it.second.fileVals[cfgFileIndex].editedValue).c_str() + '\n';
- }
- }
-
- if (!saveOut)
- {
- saveOut = CheckCVarStatesForDiff(&it, cfgFileIndex, EDITED_OVERWRITTEN_COMPARE);
- }
- }
-
- // Adding the project name to the path so that the file is created there if it doesn't already exist
- // as we don't want to modify the version in Engine/config.
- AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
- projectPath /= SETTINGS_FILE_PATH.toUtf8().constData();
- QString settingsPath = QString::fromUtf8(projectPath.c_str(), aznumeric_cast(projectPath.Native().size()));
-
- QString settingsFile = settingsPath + m_cfgFiles[m_currentPlatform][cfgFileIndex].c_str();
-
- // Check if current settings differ from existing cfg
- if (saveOut)
- {
- // Adding any dirty cvars not equal to sys_spec_full to command list
- for (auto& it : cvarGroupStrings)
- {
- commandList += it;
- }
-
- if (CFileUtil::OverwriteFile(settingsFile.toStdString().c_str()))
- {
- if (!CFileUtil::CreateDirectory(settingsPath.toStdString().c_str()))
- {
- QMessageBox::warning(this, "Warning", "Could not create the directory for file \"" + settingsFile + "\". Failed to apply Graphics Setting.",
- QMessageBox::Ok);
- continue;
- }
-
- QByteArray dataArray = commandList.toUtf8().data();
-
- QFile file(settingsFile);
- if (!file.open(QIODevice::WriteOnly) || file.write(dataArray) != dataArray.size())
- {
- QMessageBox::warning(this, "Warning", "Could not write settings to file \"" + settingsFile + ". Failed to apply Graphics Setting.",
- QMessageBox::Ok);
- file.close();
- continue;
- }
-
- successFiles.push_back(settingsFile);
-
- // Update platform cvars to reflect new values
- for (auto& it : m_cVarTracker)
- {
- it.second.fileVals[cfgFileIndex].overwrittenValue = it.second.fileVals[cfgFileIndex].editedValue;
- }
-
- file.close();
- }
- else
- {
- QMessageBox::warning(this, "Warning", "Could not check out or make file writable: \"" + settingsFile + "\". Failed to apply Graphics Setting.",
- QMessageBox::Ok);
- }
- }
- else
- {
- nochangeFiles.push_back(settingsFile);
- }
- }
-
- // Print list of files which had no changes made
- if (nochangeFiles.size() > 0)
- {
- QString message = "No changes have been made to the following files:\n";
- for (int i = 0; i < nochangeFiles.size(); ++i)
- {
- message += nochangeFiles[i] + "\n";
- }
- QMessageBox::information(this, "Log", message, QMessageBox::Ok);
- }
-
- // Print list of files which were successfully saved
- if (successFiles.size() > 0)
- {
- QString message = "Updated the graphics setting correctly for the following files:\n";
- for (int i = 0; i < successFiles.size(); ++i)
- {
- message += successFiles[i] + "\n";
- }
- QMessageBox::information(this, "Log", message, QMessageBox::Ok);
- }
-
- // if we saved all of the files that we needed to then disable the save button again
- if (nochangeFiles.size() + successFiles.size() == m_cfgFiles[m_currentPlatform].size())
- {
- m_dirtyCVarCount = 0;
- m_ui->m_applyButton->setEnabled(false);
- }
-}
-
-void GraphicsSettingsDialog::SetCollapsed(const QModelIndex& index, bool flags)
-{
- QStandardItem* item = m_graphicsSettingsModel->itemFromIndex(index);
-
- for (auto& collapseIterator : m_uiCollapseGroup)
- {
- if (collapseIterator->m_groupRow == item)
- {
- collapseIterator->m_isCollapsed = flags;
- break;
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////
-// Collapse Group
-GraphicsSettingsDialog::CollapseGroup::CollapseGroup(QTreeView* treeView)
- : m_treeView(treeView)
- , m_isCollapsed(true)
-{
-}
-
-void GraphicsSettingsDialog::CollapseGroup::ToggleCollapsed()
-{
- m_isCollapsed = !m_isCollapsed;
- const QModelIndex index = m_groupRow->index();
- if (m_isCollapsed)
- {
- m_treeView->collapse(index);
- }
- else
- {
- m_treeView->expand(index);
- }
-}
-
-///////////////////////////////////////////////////////////////////
-// ParameterWidget
-GraphicsSettingsDialog::ParameterWidget::ParameterWidget(QWidget* widget, QString parameterName)
- : m_widget(widget)
- , m_parameterName(parameterName)
-{
- m_widget->setToolTip(GetToolTip());
-}
-
-QString GraphicsSettingsDialog::ParameterWidget::GetToolTip() const
-{
- if (!m_parameterName.isEmpty())
- {
- QString tooltipText = QString(PARAMETER_TOOLTIP).arg(m_parameterName);
- return tooltipText;
- }
- return "";
-}
-
-GraphicsSettingsTreeView::GraphicsSettingsTreeView(QWidget* parent)
- : QTreeView(parent)
-{
-}
-
-GraphicsSettingsHeaderView::GraphicsSettingsHeaderView(GraphicsSettingsDialog* dialog, Qt::Orientation orientation, QWidget* parent)
- : QHeaderView(orientation, parent)
- , m_dialog(dialog)
-{
- setDefaultAlignment(Qt::AlignLeft);
-}
-
-bool GraphicsSettingsHeaderView::event(QEvent* e)
-{
- if (m_dialog->IsCustom())
- {
- GraphicsSettingsTreeView* treeView = qobject_cast(parent());
- if (treeView)
- {
- switch (e->type())
- {
- case QEvent::Enter:
- m_index = logicalIndexAt(static_cast(e)->pos());
- if (m_index > 0)
- {
- treeView->setSortingEnabled(true);
- treeView->sortByColumn(m_index, Qt::AscendingOrder);
- }
- break;
- case QEvent::Leave:
- treeView->setSortingEnabled(false);
- break;
- }
- }
- }
- return QHeaderView::event(e);
-}
-
-void GraphicsSettingsHeaderView::mouseReleaseEvent(QMouseEvent* e)
-{
- AZ_UNUSED(e);
- if (QMessageBox::question(
- this, QObject::tr("Unload Resource"),
- QObject::tr("Are you sure you want to unload the resource?"),
- QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes)
- {
- m_dialog->UnloadCustomSpec(m_index - 1);
- }
-
-}
-
-void GraphicsSettingsHeaderView::mouseMoveEvent(QMouseEvent* e)
-{
- AZ_UNUSED(e);
- if (m_dialog->IsCustom())
- {
- GraphicsSettingsTreeView* treeView = qobject_cast(parent());
- int index = logicalIndexAt(e->pos());
- if (index != m_index)
- {
- m_index = index;
- if (m_index > 0)
- {
- treeView->setSortingEnabled(true);
- treeView->sortByColumn(m_index, Qt::AscendingOrder);
- }
- else
- {
- treeView->setSortingEnabled(false);
- }
- }
- }
-}
-
-GraphicsSettingsModel::GraphicsSettingsModel(QObject* parent)
- : QStandardItemModel(parent)
-{
-}
-
-Qt::ItemFlags GraphicsSettingsModel::flags(const QModelIndex& index) const
-{
- Qt::ItemFlags flags = Qt::NoItemFlags;
-
- if (index.column() == 0)
- {
- flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled;
- }
- return flags;
-}
-
-#include
diff --git a/Code/Editor/GraphicsSettingsDialog.h b/Code/Editor/GraphicsSettingsDialog.h
deleted file mode 100644
index 66a498cd10..0000000000
--- a/Code/Editor/GraphicsSettingsDialog.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
-#pragma once
-
-#if !defined(Q_MOC_RUN)
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-#endif
-
-class QGridLayout;
-class QLabel;
-
-namespace Ui
-{
- class GraphicsSettingsDialog;
-}
-
-// Description:
-// Status of cvar for a specifc platform and spec level
-// editedValue - current setting within Graphics Settings Dialog box
-// overwrittenValue - original setting from platform config file (set to originalValue if not found)
-// originalValue - original settings from sys_spec config file index
-
-struct CVarFileStatus
-{
- AZStd::any editedValue;
- AZStd::any overwrittenValue;
- AZStd::any originalValue;
- CVarFileStatus(AZStd::any edit, AZStd::any over, AZStd::any orig) : editedValue(edit), overwrittenValue(over), originalValue(orig) {}
-};
-
-// Description:
-// Status of specific cvar for Editor mapping
-// type - CVAR_INT / CVAR_FLOAT / CVAR_STRING
-// cvarGroup - source of cvar (sys_spec_particles, sys_spec_physics, etc.) or "miscellaneous" if only specified in platform config file
-// fileVals = CVarFileStatus for each spec level of a specific platform
-
-struct CVarInfo
-{
- int type;
- AZStd::string cvarGroup;
- AZStd::vector fileVals;
-};
-
-enum class GraphicsSettings
-{
- GameEffects,
- Light,
- ObjectDetail,
- Particles,
- Physics,
- PostProcessing,
- Quality,
- Shading,
- Shadows,
- Sound,
- Texture,
- TextureResolution,
- VolumetricEffects,
- Water,
- Miscellaneous,
- numSettings
-};
-
-class GraphicsSettingsHeaderView;
-
-class GraphicsSettingsTreeView
- : public QTreeView
-{
- Q_OBJECT
-
-public:
- GraphicsSettingsTreeView(QWidget* parent = nullptr);
-
-};
-
-class GraphicsSettingsModel
- : public QStandardItemModel
-{
- Q_OBJECT
-
-public:
- explicit GraphicsSettingsModel(QObject* parent = 0);
-
- Qt::ItemFlags flags(const QModelIndex& index) const override;
-};
-
-class GraphicsSettingsDialog
- : public QDialog,
- public ILoadConfigurationEntrySink
-{
- Q_OBJECT
-
-public:
-
- explicit GraphicsSettingsDialog(QWidget* parent = nullptr);
- virtual ~GraphicsSettingsDialog();
-
- bool IsCustom(void) { return m_showCustomSpec; }
- void UnloadCustomSpec(int specLevel);
-
- // ILoadConfigurationEntrySink
- void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup) override;
-
-public slots:
- //Accept and reject
- void reject() override;
- void accept() override;
-
-private slots:
- //Update UIs
- void PlatformChanged(const QString& platform);
- bool CVarChanged(AZStd::any val, const char* cvarName, int specLevel);
- void CVarChanged(int i);
- void CVarChanged(double d);
- void CVarChanged(const QString& s);
-
-private:
-
- // The struct ParameterWidget is used to store the parameter widget
- // m_parameterName will be the name of the parameter the widget represent.
- struct ParameterWidget
- {
- ParameterWidget(QWidget* widget, QString parameterName = "");
-
- QString GetToolTip() const;
-
- const char* PARAMETER_TOOLTIP = "The variable will update render parameter \"%1\".";
- QWidget* m_widget;
- QString m_parameterName;
- };
-
- struct CollapseGroup
- {
- QString m_groupName;
- QStandardItem* m_groupRow;
- QTreeView* m_treeView;
- bool m_isCollapsed;
-
- CollapseGroup(QTreeView* treeView);
-
- void ToggleCollapsed();
- };
-
- void OpenCustomSpecDialog();
- void ApplyCustomSpec(const QString& customFilePath);
- bool IsCustomSpecAlreadyLoaded(const AZStd::string& filename) const;
- void SetSettingsTree(int numColumns);
- void SetCollapsed(const QModelIndex& index, bool flag);
-
- enum CVarStateComparison
- {
- EDITED_OVERWRITTEN_COMPARE = 1,
- EDITED_ORIGINAL_COMPARE = 2,
- OVERWRITTEN_ORIGINAL_COMPARE = 3,
-
- END_CVARSTATE_COMPARE,
- };
-
- bool CheckCVarStatesForDiff(AZStd::pair* it, int cfgFileIndex, CVarStateComparison cmp);
-
- // Save out settings into project-level cfg files
- void SaveSystemSettings();
-
- // Load in project-level cfg files for current platform
- void LoadPlatformConfigurations();
- // Build UI column for spec level of current platform
- void BuildColumn(int specLevel);
- // Initial UI building
- void BuildUI();
- // Cleaning out UI before loading new platform information
- void CleanUI();
- // Shows/hides custom spec option
- void ShowCustomSpecOption(bool show);
- // Shows/hides category labels and dropdowns
- void ShowCategories(bool show);
- // Warns about unsaved changes (returns true if accepted)
- bool SendUnsavedChangesWarning(bool cancel);
-
- void LoadCVarGroupDirectory(const AZStd::string& path);
-
- /////////////////////////////////////////////
- // UI help functions
-
- // Setup collapsed buttons
- void SetCollapsedLayout(const QString& groupName, QStandardItem* groupItem);
- // Sets the platform entry index for the given platform
- void SetPlatformEntry(ESystemConfigPlatform platform);
- // Gets the platform enum given the platform name
- ESystemConfigPlatform GetConfigPlatformFromName(const AZStd::string& platformName);
-
- ////////////////////////////////////////////
- // Members
-
- // Qt values
- const int INPUT_MIN_WIDTH = 100;
- const int INPUT_MIN_HEIGHT = 20;
- const int INPUT_ROW_SPAN = 1;
- const int INPUT_COLUMN_SPAN = 1;
- const int CVAR_ROW_OFFSET = 2;
- const int CVAR_VALUE_COLUMN_OFFSET = 1;
- const int PLATFORM_LABEL_ROW = 1;
- const int CVAR_LABEL_COLUMN = 1;
-
- // Tool tips
- const QString SETTINGS_FILE_PATH = "Config/spec/";
- const char* CFG_FILEFILTER = "Cfg File(*.cfg);;All files(*)";
-
- const int m_numSpecLevels = 4;
-
- bool m_showCustomSpec;
- bool m_showCategories;
- GraphicsSettingsModel* m_graphicsSettingsModel;
- GraphicsSettingsHeaderView* m_headerView;
- int m_numColumns{ 0 };
-
- const char* m_cvarGroupsFolder = "Config/CVarGroups";
-
- QScopedPointer m_ui;
-
- QVector m_uiCollapseGroup;
-
- QVector m_parameterWidgets;
-
- AZStd::string m_currentConfigFilename;
- size_t m_currentSpecIndex;
-
- // cvar name --> pair(type, CVarStatus for each file)
- AZStd::unordered_map m_cVarTracker;
-
- AZStd::unordered_map > m_cfgFiles;
-
- AZStd::vector > m_platformStrings;
-
- struct CVarGroupInfo
- {
- QVector m_platformLabels;
- QVector m_cvarLabels;
- QVector m_cvarSpinBoxes;
- QVector m_cvarDoubleSpinBoxes;
- QVector m_cvarLineEdits;
- QVector m_specFileArea;
- QVector m_widgetInsertOrder;
- QStandardItem* m_treeRowItem;
- int m_currentRow;
- };
-
- AZStd::unordered_map m_cvarGroupData;
- AZStd::vector m_cvarGroupOrder;
-
- ESystemConfigPlatform m_currentPlatform;
-
- int m_dirtyCVarCount;
-};
-
-class GraphicsSettingsHeaderView
- : public QHeaderView
-{
- Q_OBJECT
-public:
- GraphicsSettingsHeaderView(GraphicsSettingsDialog* dialog, Qt::Orientation orientation, QWidget* parent = nullptr);
-
-private:
- bool event(QEvent* e) override;
- void mouseMoveEvent(QMouseEvent* e) override;
- void mouseReleaseEvent(QMouseEvent* e) override;
-
- GraphicsSettingsDialog* m_dialog;
- int m_index{ -1 };
-};
-
-
diff --git a/Code/Editor/LegacyViewportCameraController.cpp b/Code/Editor/LegacyViewportCameraController.cpp
index 0750db8d97..f437196548 100644
--- a/Code/Editor/LegacyViewportCameraController.cpp
+++ b/Code/Editor/LegacyViewportCameraController.cpp
@@ -404,7 +404,7 @@ bool LegacyViewportCameraControllerInstance::HandleInputChannelEvent(const AzFra
}
else if (auto key = GetKeyboardKey(event.m_inputChannel); key != Qt::Key_unknown)
{
- if (state == InputChannel::State::Ended)
+ if (!event.m_inputChannel.IsActive())
{
m_pressedKeys.erase(key);
}
diff --git a/Code/Editor/MainWindow.cpp b/Code/Editor/MainWindow.cpp
index 261fab48d1..c7e32fb82a 100644
--- a/Code/Editor/MainWindow.cpp
+++ b/Code/Editor/MainWindow.cpp
@@ -41,6 +41,7 @@ AZ_POP_DISABLE_WARNING
// AzToolsFramework
#include
+#include
#include
#include
#include
@@ -93,6 +94,8 @@ AZ_POP_DISABLE_WARNING
#include "AssetEditor/AssetEditorWindow.h"
#include "ActionManager.h"
+#include
+
using namespace AZ;
using namespace AzQtComponents;
using namespace AzToolsFramework;
@@ -489,6 +492,16 @@ void MainWindow::Initialize()
ActionOverrideRequestBus::Event(
GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, this);
+ if (auto imGuiManager = AZ::Interface::Get())
+ {
+ auto handleImGuiStateChangeFn = [](bool enabled)
+ {
+ EditorWindowUIRequestBus::Broadcast(&EditorWindowUIRequests::SetEditorUiEnabled, enabled);
+ };
+ m_handleImGuiStateChangeHandler = ImGui::IImGuiManager::ImGuiSetEnabledEvent::Handler(handleImGuiStateChangeFn);
+ imGuiManager->ConnectImGuiSetEnabledChangedHandler(m_handleImGuiStateChangeHandler);
+ }
+
AzToolsFramework::EditorEventsBus::Broadcast(&AzToolsFramework::EditorEvents::NotifyMainWindowInitialized, this);
}
@@ -674,49 +687,6 @@ void MainWindow::InitActions()
am->AddAction(ID_FILE_PROJECT_MANAGER_SETTINGS, tr("Edit Project Settings..."));
am->AddAction(ID_FILE_PROJECT_MANAGER_NEW, tr("New Project..."));
am->AddAction(ID_FILE_PROJECT_MANAGER_OPEN, tr("Open Project..."));
- am->AddAction(ID_GAME_PC_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_PC_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_PC_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_PC_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_OSXMETAL_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_OSXMETAL_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_ANDROID_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_ANDROID_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_ANDROID_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_ANDROID_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_IOS_ENABLEVERYHIGHSPEC, tr("Very High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_IOS_ENABLEHIGHSPEC, tr("High")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_IOS_ENABLEMEDIUMSPEC, tr("Medium")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
- am->AddAction(ID_GAME_IOS_ENABLELOWSPEC, tr("Low")).SetCheckable(true)
- .RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateGameSpec);
-#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
-#if defined(TOOLS_SUPPORT_JASPER)
-#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, jasper)
-#endif
-#if defined(TOOLS_SUPPORT_PROVO)
-#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, provo)
-#endif
-#if defined(TOOLS_SUPPORT_SALEM)
-#include AZ_RESTRICTED_FILE_EXPLICIT(MainWindow_cpp, salem)
-#endif
-#endif
am->AddAction(ID_TOOLS_CUSTOMIZEKEYBOARD, tr("Customize &Keyboard..."))
.Connect(&QAction::triggered, this, &MainWindow::ShowKeyboardCustomization);
am->AddAction(ID_TOOLS_EXPORT_SHORTCUTS, tr("&Export Keyboard Settings..."))
@@ -724,7 +694,6 @@ void MainWindow::InitActions()
am->AddAction(ID_TOOLS_IMPORT_SHORTCUTS, tr("&Import Keyboard Settings..."))
.Connect(&QAction::triggered, this, &MainWindow::ImportKeyboardShortcuts);
am->AddAction(ID_TOOLS_PREFERENCES, tr("Global Preferences..."));
- am->AddAction(ID_GRAPHICS_SETTINGS, tr("&Graphics Settings..."));
for (int i = ID_FILE_MRU_FIRST; i <= ID_FILE_MRU_LAST; ++i)
{
diff --git a/Code/Editor/MainWindow.h b/Code/Editor/MainWindow.h
index 34b121537d..99af2ea326 100644
--- a/Code/Editor/MainWindow.h
+++ b/Code/Editor/MainWindow.h
@@ -249,6 +249,7 @@ private:
QPointer m_toolbarCustomizationDialog;
QScopedPointer m_sourceControlNotifHandler;
+ AZ::Event::Handler m_handleImGuiStateChangeHandler;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
static MainWindow* m_instance;
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt b/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt
index 4744b4e174..5aab2a2056 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt
@@ -27,6 +27,7 @@ ly_add_target(
BUILD_DEPENDENCIES
PRIVATE
3rdParty::Qt::Core
+ 3rdParty::Qt::Widgets
AZ::AzCore
AZ::AzToolsFramework
Legacy::CryCommon
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp
index c1af8d76d7..a6c1ed6598 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerDisplayOptionsMenu.cpp
@@ -66,3 +66,5 @@ namespace EntityOutliner
emit OnOptionToggled(DisplayOption::AutoExpand, checked);
}
}
+
+#include
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp
index 660ea137cf..89cd361fb6 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSortFilterProxyModel.cpp
@@ -32,7 +32,24 @@ bool OutlinerSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelI
bool OutlinerSortFilterProxyModel::lessThan(const QModelIndex& leftIndex, const QModelIndex& rightIndex) const
{
- return sourceModel()->data(leftIndex).toString() < sourceModel()->data(rightIndex).toString();
+ if (leftIndex.isValid() && rightIndex.isValid())
+ {
+ QVariant leftData = sourceModel()->data(leftIndex);
+ QVariant rightData = sourceModel()->data(rightIndex);
+
+ // make sure to compare the correct data types for sorting the current column
+ AZ_Assert(leftData.type() == rightData.type(), "OutlinerSortFilterProxyModel::lessThan types do not agree!");
+ if (static_cast(leftData.type()) == QMetaType::QString)
+ {
+ return leftData.toString() < rightData.toString();
+ }
+ else if (static_cast(leftData.type()) == QMetaType::ULongLong)
+ {
+ return leftData.toULongLong() < rightData.toULongLong();
+ }
+ AZ_Error("Editor", false, "Error! Unhandled type \"%s\" in OutlinerSortFilterProxyModel::lessThan", leftData.typeName());
+ }
+ return false;
}
void OutlinerSortFilterProxyModel::sort(int /*column*/, Qt::SortOrder /*order*/)
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp
index d69480b169..02dabb8b20 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.cpp
@@ -269,10 +269,12 @@ OutlinerWidget::OutlinerWidget(QWidget* pParent, Qt::WindowFlags flags)
AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
AzToolsFramework::GetEntityContextId());
AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusConnect();
+ AzToolsFramework::EditorWindowUIRequestBus::Handler::BusConnect();
}
OutlinerWidget::~OutlinerWidget()
{
+ AzToolsFramework::EditorWindowUIRequestBus::Handler::BusDisconnect();
AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusDisconnect();
AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect();
@@ -1321,16 +1323,25 @@ static void SetEntityOutlinerState(Ui::OutlinerWidgetUI* entityOutlinerUi, const
AzQtComponents::SetWidgetInteractEnabled(entityOutlinerUi->m_searchWidget, on);
}
+void OutlinerWidget::EnableUi(bool enable)
+{
+ SetEntityOutlinerState(m_gui, enable);
+ setEnabled(enable);
+}
+
+void OutlinerWidget::SetEditorUiEnabled(bool enable)
+{
+ EnableUi(enable);
+}
+
void OutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes)
{
- SetEntityOutlinerState(m_gui, false);
- setEnabled(false);
+ EnableUi(false);
}
void OutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes)
{
- setEnabled(true);
- SetEntityOutlinerState(m_gui, true);
+ EnableUi(true);
}
void OutlinerWidget::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& /*ticket*/)
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx
index 75991424bb..aff305e0fe 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerWidget.hxx
@@ -13,6 +13,7 @@
#include
#include
+#include
#include
#include
#include
@@ -57,6 +58,7 @@ class OutlinerWidget
, private AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler
, private AzToolsFramework::EditorEntityInfoNotificationBus::Handler
, private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
+ , private AzToolsFramework::EditorWindowUIRequestBus::Handler
{
Q_OBJECT;
public:
@@ -106,6 +108,9 @@ private:
void EnteredComponentMode(const AZStd::vector& componentModeTypes) override;
void LeftComponentMode(const AZStd::vector& componentModeTypes) override;
+ // EditorWindowUIRequestBus overrides
+ void SetEditorUiEnabled(bool enable) override;
+
// Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored.
template
QItemSelection BuildSelectionFromEntities(const EntityIdCollection& entityIds);
@@ -171,6 +176,7 @@ private:
AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index) const;
QModelIndex GetIndexFromEntityId(const AZ::EntityId& entityId) const;
void ExtractEntityIdsFromSelection(const QItemSelection& selection, AzToolsFramework::EntityIdList& entityIdList) const;
+ void EnableUi(bool enable);
// AzToolsFramework::OutlinerModelNotificationBus::Handler
// Receive notification from the outliner model that we should scroll
diff --git a/Code/Editor/Plugins/EditorCommon/EditorCommon.def b/Code/Editor/Plugins/EditorCommon/EditorCommon.def
deleted file mode 100644
index a8d10ff297..0000000000
--- a/Code/Editor/Plugins/EditorCommon/EditorCommon.def
+++ /dev/null
@@ -1,6 +0,0 @@
-; EditorCommon.def : Declares the module parameters for the DLL.
-
-LIBRARY
-
-EXPORTS
- ; Explicit exports can go here
diff --git a/Code/Editor/Plugins/EditorCommon/res/EditorCommon.rc2 b/Code/Editor/Plugins/EditorCommon/res/EditorCommon.rc2
deleted file mode 100644
index 8ffc09417a..0000000000
Binary files a/Code/Editor/Plugins/EditorCommon/res/EditorCommon.rc2 and /dev/null differ
diff --git a/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt b/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt
index 342151f24a..909ec193f3 100644
--- a/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt
+++ b/Code/Editor/Plugins/FFMPEGPlugin/CMakeLists.txt
@@ -23,6 +23,7 @@ ly_add_target(
.
BUILD_DEPENDENCIES
PRIVATE
+ 3rdParty::Qt::Core
AZ::AzCore
Legacy::CryCommon
Legacy::EditorLib
diff --git a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h
index 3b015dd9a5..33ca3390f1 100644
--- a/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h
+++ b/Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h
@@ -17,19 +17,8 @@
/////////////////////////////////////////////////////////////////////////////
#include
-
-/////////////////////////////////////////////////////////////////////////////
-// STL
-/////////////////////////////////////////////////////////////////////////////
-#include
-#include
-#include
-#include
-#include
-
/////////////////////////////////////////////////////////////////////////////
// CRY Stuff ////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
#include
-#include "Util/EditorUtils.h"
#include "EditorCoreAPI.h"
diff --git a/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt b/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt
index 15a1147166..bd4661fa0f 100644
--- a/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt
+++ b/Code/Editor/Plugins/PerforcePlugin/CMakeLists.txt
@@ -31,6 +31,8 @@ ly_add_target(
.
BUILD_DEPENDENCIES
PRIVATE
+ 3rdParty::Qt::Core
+ 3rdParty::Qt::Widgets
AZ::AzCore
Legacy::CryCommon
Legacy::EditorLib
diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp
index f1a2aafd1e..f4e4fed973 100644
--- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp
+++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp
@@ -585,31 +585,11 @@ namespace ProjectSettingsTool
ShowAllErrorsThenExitIfInvalid();
m_ui->reconfigureLog->setText("");
- int result = QMessageBox::question
- (
- this,
- tr("Reconfigure Project"),
- tr("For new settings to be applied the project must be reconfigured. Would you like run configure now?"),
- QMessageBox::Yes,
- QMessageBox::No
- );
+ QMessageBox::information(this, tr("Project Settings Saved"),
+ tr("The project may need to be manually reconfigured for the new settings to be applied."));
- if (QMessageBox::Yes == result)
- {
- m_ui->reconfigureLog->show();
- #if defined(AZ_PLATFORM_WINDOWS)
- m_reconfigureProcess.start("cmd.exe", { QString("/C %1").arg("lmbr_waf.bat configure") });
- #elif defined(AZ_PLATFORM_MAC) || defined(AZ_PLATFORM_LINUX)
- m_reconfigureProcess.start("/bin/sh", { QString("%1").arg("lmbr_waf.sh configure") });
- #else
- #error "Needs to be implemented"
- #endif
- }
- else
- {
- m_ui->reloadButton->setEnabled(true);
- m_ui->saveButton->setEnabled(true);
- }
+ m_ui->reloadButton->setEnabled(true);
+ m_ui->saveButton->setEnabled(true);
}
// Show a message box telling user settings failed to save
else
diff --git a/Code/Editor/Plugins/ProjectSettingsTool/Validators.cpp b/Code/Editor/Plugins/ProjectSettingsTool/Validators.cpp
index 8484a2937a..c17da8e40b 100644
--- a/Code/Editor/Plugins/ProjectSettingsTool/Validators.cpp
+++ b/Code/Editor/Plugins/ProjectSettingsTool/Validators.cpp
@@ -172,8 +172,9 @@ namespace ProjectSettingsTool
// Returns true if valid ios version number
RetType IOSVersionNumber(const QString& value)
{
+ // support up to 4-component numerical-only version strings
return RegularExpressionValidator
- ("(0|[1-9][0-9]{0,8}|[1-2][0-1][0-9]{0,8})(\\.(0|[1-9][0-9]{0,8}|[1-2][0-1][0-9]{0,8})){0,2}",
+ ("^(\\d+)(\\.\\d+){0,3}$",
value,
maxIosVersionLength);
}
diff --git a/Code/Editor/Plugins/QtMocRule.props b/Code/Editor/Plugins/QtMocRule.props
deleted file mode 100644
index af7c107071..0000000000
--- a/Code/Editor/Plugins/QtMocRule.props
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- %(RootDir)%(Directory)%(FileName).moc
- $(QTDIR)\bin\moc.exe [AllOptions] [Inputs]
- Moc'ing %(Filename)%(Extension)...
-
-
-
diff --git a/Code/Editor/Plugins/QtMocRule.targets b/Code/Editor/Plugins/QtMocRule.targets
deleted file mode 100644
index fdcb95e6a3..0000000000
--- a/Code/Editor/Plugins/QtMocRule.targets
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
- _QtMOC
-
-
-
- $(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml
-
-
-
-
-
-
-
- @(QtMOC, '|')
-
-
-
-
-
-
-
diff --git a/Code/Editor/Plugins/QtMocRule.xml b/Code/Editor/Plugins/QtMocRule.xml
deleted file mode 100644
index 21850b34ab..0000000000
--- a/Code/Editor/Plugins/QtMocRule.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
- General
-
-
-
-
- Command Line
-
-
-
-
-
-
-
-
-
-
-
-
-
- Additional Options
-
-
- Additional Options
-
-
-
-
-
-
diff --git a/Code/Editor/Plugins/QtRccRule.props b/Code/Editor/Plugins/QtRccRule.props
deleted file mode 100644
index 9c06b5c082..0000000000
--- a/Code/Editor/Plugins/QtRccRule.props
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- %(RootDir)%(Directory)rcc_%(FileName).h
- $(QTDIR)\bin\rcc.exe [AllOptions] [Inputs]
- Rcc'ing %(Filename)%(Extension)...
-
-
-
diff --git a/Code/Editor/Plugins/QtRccRule.targets b/Code/Editor/Plugins/QtRccRule.targets
deleted file mode 100644
index bd4e7ae90e..0000000000
--- a/Code/Editor/Plugins/QtRccRule.targets
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
- _QtRCC
-
-
-
- $(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml
-
-
-
-
-
-
-
- @(QtRCC, '|')
-
-
-
-
-
-
-
diff --git a/Code/Editor/Plugins/QtRccRule.xml b/Code/Editor/Plugins/QtRccRule.xml
deleted file mode 100644
index ce7b98c323..0000000000
--- a/Code/Editor/Plugins/QtRccRule.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
- General
-
-
-
-
- Command Line
-
-
-
-
-
-
-
-
-
-
-
-
-
- Additional Options
-
-
- Additional Options
-
-
-
-
-
-
diff --git a/Code/Editor/Plugins/QtUicRule.props b/Code/Editor/Plugins/QtUicRule.props
deleted file mode 100644
index ce08b40be7..0000000000
--- a/Code/Editor/Plugins/QtUicRule.props
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- %(RootDir)%(Directory)ui_%(FileName).h
- $(QTDIR)\bin\uic.exe [AllOptions] [Inputs]
- Uic'ing %(Filename)%(Extension)...
-
-
-
diff --git a/Code/Editor/Plugins/QtUicRule.targets b/Code/Editor/Plugins/QtUicRule.targets
deleted file mode 100644
index a5ada15f79..0000000000
--- a/Code/Editor/Plugins/QtUicRule.targets
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
- _QtUIC
-
-
-
- $(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml
-
-
-
-
-
-
-
- @(QtUIC, '|')
-
-
-
-
-
-
-
-
diff --git a/Code/Editor/Plugins/QtUicRule.xml b/Code/Editor/Plugins/QtUicRule.xml
deleted file mode 100644
index ec7ce4b214..0000000000
--- a/Code/Editor/Plugins/QtUicRule.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
- General
-
-
-
-
- Command Line
-
-
-
-
-
-
-
-
-
-
-
-
-
- Additional Options
-
-
- Additional Options
-
-
-
-
-
-
diff --git a/Code/Editor/QtViewPaneManager.cpp b/Code/Editor/QtViewPaneManager.cpp
index 35b2160a1f..9f2b9f9cf8 100644
--- a/Code/Editor/QtViewPaneManager.cpp
+++ b/Code/Editor/QtViewPaneManager.cpp
@@ -525,6 +525,7 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent)
// view pane manager is interested when we enter/exit ComponentMode
m_componentModeNotifications.BusConnect(AzToolsFramework::GetEntityContextId());
+ m_windowRequest.BusConnect();
m_componentModeNotifications.SetEnteredComponentModeFunc(
[this](const AZStd::vector& /*componentModeTypes*/)
@@ -545,10 +546,23 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent)
AzQtComponents::SetWidgetInteractEnabled(widget, on);
});
});
+
+ m_windowRequest.SetEnableEditorUiFunc(
+ [this](bool enable)
+ {
+ // gray out panels when entering ImGui mode
+ SetDefaultActionsEnabled(
+ enable, m_registeredPanes,
+ [](QWidget* widget, bool on)
+ {
+ AzQtComponents::SetWidgetInteractEnabled(widget, on);
+ });
+ });
}
QtViewPaneManager::~QtViewPaneManager()
{
+ m_windowRequest.BusDisconnect();
m_componentModeNotifications.BusDisconnect();
}
diff --git a/Code/Editor/QtViewPaneManager.h b/Code/Editor/QtViewPaneManager.h
index aa382c41c0..2b3412aad6 100644
--- a/Code/Editor/QtViewPaneManager.h
+++ b/Code/Editor/QtViewPaneManager.h
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
@@ -249,8 +250,12 @@ private:
QPointer m_advancedDockManager;
using EditorComponentModeNotificationBusImpl = AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBusImpl;
- EditorComponentModeNotificationBusImpl m_componentModeNotifications; /**< Helper for EditorComponentModeNotificationBus so
- * QtViewPaneManager does not need to inherit directly from it. */
+ EditorComponentModeNotificationBusImpl m_componentModeNotifications; //!< Helper for EditorComponentModeNotificationBus so
+ //!< QtViewPaneManager does not need to inherit directly from it. */
+
+ using EditorWindowRequestBusImpl = AzToolsFramework::EditorWindowRequestBusImpl;
+ EditorWindowRequestBusImpl m_windowRequest; //!< Helper for EditorWindowRequestBus so
+ //!< QtViewPaneManager does not need to inherit directly from it. */
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
diff --git a/Code/Editor/RenderViewport.cpp b/Code/Editor/RenderViewport.cpp
index 8d6bcf021b..bb269ba298 100644
--- a/Code/Editor/RenderViewport.cpp
+++ b/Code/Editor/RenderViewport.cpp
@@ -4083,7 +4083,12 @@ void CRenderViewport::RestoreViewportAfterGameMode()
{
Matrix34 preGameModeViewTM = m_preGameModeViewTM;
- QString text = QString("You are exiting Game Mode. Would you like to restore the camera in the viewport to where it was before you entered Game Mode?This option can always be changed in the General Preferences tab of the Editor Settings, by toggling the \"%1\" option. ").arg(EditorPreferencesGeneralRestoreViewportCameraSettingName);
+ QString text =
+ QString(
+ tr("When leaving \" Game Mode \" the engine will automatically restore your camera position to the default position before you "
+ "had entered Game mode.If you dislike this setting you can always change this anytime in the global "
+ "preferences. "))
+ .arg(EditorPreferencesGeneralRestoreViewportCameraSettingName);
QString restoreOnExitGameModePopupDisabledRegKey("Editor/AutoHide/ViewportCameraRestoreOnExitGameMode");
// Read the popup disabled registry value
@@ -4098,6 +4103,7 @@ void CRenderViewport::RestoreViewportAfterGameMode()
messageBox.setDefaultButton(QMessageBox::Yes);
QCheckBox* checkBox = new QCheckBox(QStringLiteral("Do not show this message again"));
+ checkBox->setChecked(true);
messageBox.setCheckBox(checkBox);
// Unconstrain the system cursor and make it visible before we show the dialog box, otherwise the user can't see the cursor.
diff --git a/Code/Editor/RenderViewport.h b/Code/Editor/RenderViewport.h
index 1764028dd6..2a67e1bbc6 100644
--- a/Code/Editor/RenderViewport.h
+++ b/Code/Editor/RenderViewport.h
@@ -219,6 +219,7 @@ public:
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
+ float GetDpiScaleFactor() const override { return 1.0f; };
void ConnectViewportInteractionRequestBus();
void DisconnectViewportInteractionRequestBus();
diff --git a/Code/Editor/Resource.h b/Code/Editor/Resource.h
index 22bbece700..3ae1024550 100644
--- a/Code/Editor/Resource.h
+++ b/Code/Editor/Resource.h
@@ -187,7 +187,6 @@
#define ID_SWITCHCAMERA_SEQUENCECAMERA 33701
#define ID_SWITCHCAMERA_SELECTEDCAMERA 33702
#define ID_TV_RECORD_AUTO 33703
-#define ID_GRAPHICS_SETTINGS 33705
#define ID_VIEW_OPENVIEWPANE 33709
#define ID_VIEW_OPENPANE_FIRST 33712
#define ID_VIEW_OPENPANE_LAST 33811
@@ -219,10 +218,6 @@
#define ID_SPLINE_SNAP_GRID_X 33933
#define ID_SPLINE_SNAP_GRID_Y 33934
#define ID_FREEZE_TANGENTS 33935
-#define ID_GAME_PC_ENABLELOWSPEC 33960
-#define ID_GAME_PC_ENABLEMEDIUMSPEC 33961
-#define ID_GAME_PC_ENABLEHIGHSPEC 33962
-#define ID_GAME_PC_ENABLEVERYHIGHSPEC 33963
#define ID_PANEL_VEG_CREATE_SEL 33990
#define ID_TOOLS_UPDATEPROCEDURALVEGETATION 33999
#define ID_DISPLAY_GOTOPOSITION 34004
@@ -287,14 +282,6 @@
#define ID_CLEAR_REGISTRY 34470
#define ID_SOUND_STOPALLSOUNDS 34476
#define ID_AUDIO_REFRESH_AUDIO_SYSTEM 34477
-#define ID_GAME_ANDROID_ENABLELOWSPEC 34490
-#define ID_GAME_ANDROID_ENABLEMEDIUMSPEC 34491
-#define ID_GAME_ANDROID_ENABLEHIGHSPEC 34492
-#define ID_GAME_ANDROID_ENABLEVERYHIGHSPEC 34493
-#define ID_GAME_IOS_ENABLELOWSPEC 34494
-#define ID_GAME_IOS_ENABLEMEDIUMSPEC 34495
-#define ID_GAME_IOS_ENABLEHIGHSPEC 34496
-#define ID_GAME_IOS_ENABLEVERYHIGHSPEC 34497
#define ID_OPEN_AUDIO_CONTROLS_BROWSER 34580
#define ID_CREATE_GLOBAL_FG_MODULE_FROM_SELECTION 35076
#define ID_CREATE_LEVEL_FG_MODULE_FROM_SELECTION 35077
@@ -324,19 +311,6 @@
#define ID_DOCUMENTATION_FEEDBACK 36043
#define ID_OPEN_SUBSTANCE_EDITOR 36060
#define ID_IMPORT_ASSET 36069
-#define ID_GAME_PROVO_ENABLELOWSPEC 34603
-#define ID_GAME_PROVO_ENABLEMEDIUMSPEC 34604
-#define ID_GAME_PROVO_ENABLEHIGHSPEC 34605
-#define ID_GAME_OSXMETAL_ENABLELOWSPEC 34606
-#define ID_GAME_OSXMETAL_ENABLEMEDIUMSPEC 34607
-#define ID_GAME_OSXMETAL_ENABLEHIGHSPEC 34608
-#define ID_GAME_OSXMETAL_ENABLEVERYHIGHSPEC 34609
-#define ID_GAME_SALEM_ENABLELOWSPEC 34610
-#define ID_GAME_SALEM_ENABLEMEDIUMSPEC 34611
-#define ID_GAME_SALEM_ENABLEHIGHSPEC 34612
-#define ID_GAME_JASPER_ENABLELOWSPEC 34613
-#define ID_GAME_JASPER_ENABLEMEDIUMSPEC 34614
-#define ID_GAME_JASPER_ENABLEHIGHSPEC 34615
#define ID_FILE_RESAVESLICES 36210
#define FIRST_QT_ACTION 50000
#define ID_VIEW_CONSOLEWINDOW 50001
diff --git a/Code/Editor/Style/GraphicsSettingsDialog.qss b/Code/Editor/Style/GraphicsSettingsDialog.qss
deleted file mode 100644
index 3af8c4c05b..0000000000
--- a/Code/Editor/Style/GraphicsSettingsDialog.qss
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
-
-#GraphicsSettingsDialog QHeaderView::section
-{
- background: #2D2D2D;
-}
-
-#GraphicsSettingsDialog QHeaderView::down-arrow
-{
- width: 14px;
- height: 14px;
- image: url(:/Gallery/Delete.svg);
-}
-
-#GraphicsSettingsDialog QHeaderView::up-arrow
-{
- width: 14px;
- height: 14px;
- image: url(:/Gallery/Delete.svg);
-}
diff --git a/Code/Editor/Style/resources.qrc b/Code/Editor/Style/resources.qrc
index aec7e2cf68..24682d2be3 100644
--- a/Code/Editor/Style/resources.qrc
+++ b/Code/Editor/Style/resources.qrc
@@ -3,6 +3,5 @@
Editor.qss
EditorPreferencesDialog.qss
LayoutConfigDialog.qss
- GraphicsSettingsDialog.qss
diff --git a/Code/Editor/TrackView/AtomOutputFrameCapture.cpp b/Code/Editor/TrackView/AtomOutputFrameCapture.cpp
index d5ceeae9b2..cd5a977367 100644
--- a/Code/Editor/TrackView/AtomOutputFrameCapture.cpp
+++ b/Code/Editor/TrackView/AtomOutputFrameCapture.cpp
@@ -73,7 +73,7 @@ namespace TrackView
bool startedCapture = false;
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
startedCapture, &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachmentWithCallback, m_passHierarchy,
- AZStd::string("Output"), attachmentReadbackCallback);
+ AZStd::string("Output"), attachmentReadbackCallback, AZ::RPI::PassAttachmentReadbackOption::Output);
return startedCapture;
}
diff --git a/Code/Editor/ViewportManipulatorController.cpp b/Code/Editor/ViewportManipulatorController.cpp
index c7d2885cb2..fb696a61f3 100644
--- a/Code/Editor/ViewportManipulatorController.cpp
+++ b/Code/Editor/ViewportManipulatorController.cpp
@@ -216,7 +216,8 @@ namespace SandboxEditor
interactionHandled, AzToolsFramework::GetEntityContextId(), targetInteractionEvent, mouseInteractionEvent);
}
- return interactionHandled;
+ // Only filter button/key press events, not release events
+ return interactionHandled && event.m_inputChannel.IsActive();
}
void ViewportManipulatorControllerInstance::ResetInputChannels()
diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp
index f9560aef55..49d9c58159 100644
--- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp
+++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp
@@ -40,10 +40,6 @@
#include "CryEdit.h"
#include "LevelFileDialog.h"
-// NewsShared
-#include // for News::ResourceManifest
-#include // for News::ArticleViewContainer
-
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
#include
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h
index 4338a8250f..39c0ad6316 100644
--- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h
+++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.h
@@ -8,8 +8,6 @@
#if !defined(Q_MOC_RUN)
#include
-#include "NewsShared/LogType.h"
-#include "NewsShared/ErrorCodes.h"
#endif
namespace News {
@@ -62,9 +60,6 @@ private:
void OnRecentLevelTableItemClicked(const QModelIndex& index);
void OnCloseBtnClicked(bool checked);
- void SyncFail(News::ErrorCode error);
- void SyncSuccess();
-
private Q_SLOTS:
void previewAreaScrolled();
};
diff --git a/Code/Editor/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake
index 562623dab2..3181474b35 100644
--- a/Code/Editor/editor_lib_files.cmake
+++ b/Code/Editor/editor_lib_files.cmake
@@ -21,7 +21,6 @@ set(FILES
res/TreeView.bmp
res/VisualLog_PlayerButtons.bmp
res/ab_toolbar.bmp
- res/about_dark.bmp
res/anim.bmp
res/animatio.bmp
res/animations_tree_soundevent.bmp
@@ -137,7 +136,6 @@ set(FILES
res/litebulb.bmp
res/lock_sel.bmp
res/locksele.bmp
- res/logo.bmp
res/mainfram.bmp
res/mann_tagdef_toolbar.bmp
res/mann_tagdef_tree.bmp
@@ -184,8 +182,6 @@ set(FILES
res/rename.ico
res/replace.ico
res/ribbon_system_button.png
- res/sandbox_dark.bmp
- res/sb_welcome_dark.bmp
res/selectobj.bmp
res/seq_1_colour_keys.bmp
res/seq_2_colour_keys.bmp
@@ -587,9 +583,6 @@ set(FILES
SettingsManager.h
SettingsManagerDialog.h
SettingsManagerDialog.ui
- GraphicsSettingsDialog.h
- GraphicsSettingsDialog.cpp
- graphicssettingsdialog.ui
AboutDialog.cpp
ErrorReportTableModel.h
ErrorReportTableModel.cpp
diff --git a/Code/Editor/graphicssettingsdialog.ui b/Code/Editor/graphicssettingsdialog.ui
deleted file mode 100644
index ca8770e9e3..0000000000
--- a/Code/Editor/graphicssettingsdialog.ui
+++ /dev/null
@@ -1,270 +0,0 @@
-
-
- GraphicsSettingsDialog
-
-
-
- 0
- 0
- 1292
- 565
-
-
-
-
- 0
- 0
-
-
-
-
- 800
- 400
-
-
-
-
- 16777215
- 16777215
-
-
-
- Graphics Settings
-
-
- -
-
-
-
- 0
-
-
- 6
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
- -
-
-
-
-
-
- -
-
-
-
- 100
- 0
-
-
-
-
- 16777215
- 20
-
-
-
- Add Resource
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 60
- 20
-
-
-
- Platform
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 13
- 0
-
-
-
- Qt::Vertical
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- true
-
-
-
-
- 0
- 0
- 1272
- 452
-
-
-
-
- 0
- 0
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- 8
-
-
- false
-
-
-
-
-
-
-
- -
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- background-color: rgb(233, 118, 17);
-
-
- Save
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Cancel
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
-
- line
- m_scrollArea
- line_2
- widget
-
-
-
- GraphicsSettingsTreeView
- QTreeView
-
-
-
-
- m_cancelButton
- m_applyButton
- m_scrollArea
-
-
-
-
diff --git a/Code/Editor/res/about_dark.bmp b/Code/Editor/res/about_dark.bmp
deleted file mode 100644
index 2bf31764a6..0000000000
--- a/Code/Editor/res/about_dark.bmp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:887d184cf49cf78c62a1fe53eac3cb8e7b071bb67e09b801a4893445ac4c800f
-size 542456
diff --git a/Code/Editor/res/logo.bmp b/Code/Editor/res/logo.bmp
deleted file mode 100644
index c67ca02a07..0000000000
--- a/Code/Editor/res/logo.bmp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8b65af2765042354ae4110dc7bcbde905e4a55a4995f66b626d15ec6c0fa18c1
-size 96056
diff --git a/Code/Editor/res/logo.gif b/Code/Editor/res/logo.gif
deleted file mode 100644
index 00534c61cc..0000000000
--- a/Code/Editor/res/logo.gif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:79412e83b32bb6712d9701f78465878a2057a590698a4dc8d8c7aa11de2623ef
-size 4227
diff --git a/Code/Editor/res/sandbox_dark.bmp b/Code/Editor/res/sandbox_dark.bmp
deleted file mode 100644
index 2bf31764a6..0000000000
--- a/Code/Editor/res/sandbox_dark.bmp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:887d184cf49cf78c62a1fe53eac3cb8e7b071bb67e09b801a4893445ac4c800f
-size 542456
diff --git a/Code/Editor/res/sb_welcome_dark.bmp b/Code/Editor/res/sb_welcome_dark.bmp
deleted file mode 100644
index 979c61e4af..0000000000
--- a/Code/Editor/res/sb_welcome_dark.bmp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:704faeb96d930d3e6992a1449908aa6d7860b648e2feb38da8bf37cd7268a694
-size 184856
diff --git a/Code/Framework/AzCore/AzCore/EBus/Event.inl b/Code/Framework/AzCore/AzCore/EBus/Event.inl
index 006ff81e34..493dea4a3f 100644
--- a/Code/Framework/AzCore/AzCore/EBus/Event.inl
+++ b/Code/Framework/AzCore/AzCore/EBus/Event.inl
@@ -27,11 +27,17 @@ namespace AZ
template
EventHandler::EventHandler(const EventHandler& rhs)
: m_callback(rhs.m_callback)
+ , m_event(rhs.m_event)
{
- // Copy the callback function, then perform a Connect with the new event
- if (rhs.m_event)
+ // Copy the callback and event, then perform a Connect to the event
+ if (m_callback && m_event)
{
- rhs.m_event->Connect(*this);
+ m_event->Connect(*this);
+ }
+ else
+ {
+ // It was not possible to connect to the event, set it to nullptr
+ m_event = nullptr;
}
}
@@ -65,9 +71,16 @@ namespace AZ
{
Disconnect();
m_callback = rhs.m_callback;
- if (rhs.m_event)
+ m_event = rhs.m_event;
+ // Copy the callback and event, then perform a Connect to the event
+ if (m_callback && m_event)
{
- rhs.m_event->Connect(*this);
+ m_event->Connect(*this);
+ }
+ else
+ {
+ // It was not possible to connect to the event, set it to nullptr
+ m_event = nullptr;
}
}
diff --git a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp
index 7e83d5c307..b2d92854e9 100644
--- a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp
@@ -23,6 +23,8 @@ namespace AZ
}
JsonUuidSerializer::JsonUuidSerializer()
+ : m_zeroUuidString(AZ::Uuid::CreateNull().ToString())
+ , m_zeroUuidStringNoDashes(AZ::Uuid::CreateNull().ToString(true, false))
{
m_uuidFormat = AZStd::regex(R"(\{[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{12}\})",
AZStd::regex_constants::icase | AZStd::regex_constants::optimize);
@@ -53,7 +55,7 @@ namespace AZ
Uuid* valAsUuid = reinterpret_cast(outputValue);
- if (IsExplicitDefault(inputValue))
+ if (IsExplicitDefault(inputValue) || (inputValue == m_zeroUuidString.c_str()) || (inputValue == m_zeroUuidStringNoDashes.c_str()))
{
*valAsUuid = AZ::Uuid::CreateNull();
return MessageResult("Uuid value set to default of null.", JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed));
diff --git a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h
index e3c1f4c7ed..a0a594d573 100644
--- a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h
@@ -47,6 +47,8 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context);
private:
+ const AZStd::string m_zeroUuidString;
+ const AZStd::string m_zeroUuidStringNoDashes;
AZStd::regex m_uuidFormat;
};
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
index 84988d23c3..6e57deed74 100644
--- a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
+++ b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
@@ -3252,6 +3252,7 @@ LUA_API const Node* lua_getDummyNode()
else if (Internal::LuaScriptNumber::FromStack(param, result)) return result;
else if (Internal::LuaScriptNumber::FromStack(param, result)) return result;
else if (Internal::LuaScriptNumber::FromStack(param, result)) return result;
+ else if (Internal::LuaScriptNumber::FromStack(param, result)) return result;
else if (Internal::LuaScriptNumber::FromStack(param, result)) return result;
else if (Internal::LuaScriptNumber::FromStack(param, result)) return result;
else if (Internal::LuaScriptNumber::FromStack(param, result)) return result;
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp
index efbc0eaa1f..5a709f9324 100644
--- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp
@@ -32,6 +32,15 @@ namespace AZ
{
if (m_hashes.size() < m_hashes.max_size())
{
+ constexpr size_t MaxTagSize = TagName{}.max_size();
+ if (specialization.size() > MaxTagSize)
+ {
+ AZ_Error("Settings Registry", false, R"(Cannot append Specialization tag of "%.*s.")"
+ " It is longer than the MaxTagNameSize of %zu", AZ_STRING_ARG(specialization),
+ MaxTagSize);
+ return false;
+ }
+
m_names.push_back(TagName{ specialization });
TagName& tag = m_names.back();
AZStd::to_lower(tag.begin(), tag.end());
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h
index baeca89636..f0077db2ca 100644
--- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h
@@ -49,7 +49,7 @@ namespace AZ
class Specializations
{
public:
- static constexpr size_t MaxTagNameSize = 32;
+ static constexpr size_t MaxTagNameSize = 64;
static constexpr size_t MaxCount = 15;
static constexpr size_t NotFound = static_cast(-1);
using TagName = AZStd::fixed_string;
diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp
index 9b2ccbe754..39f6c02bde 100644
--- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp
+++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp
@@ -146,7 +146,7 @@ namespace AZ {
AZStd::mutex g_dbgLoadingMutex;
HANDLE g_currentProcess = 0; /// We deal with only one process for now.
CRITICAL_SECTION g_csDbgHelpDll; /// All dbg help functions are single threaded, so we need to control the access.
- AZStd::fixed_vector g_moduleInfo;
+ AZStd::fixed_vector g_moduleInfo;
// reserve 4k of scratch space so that we can get some callstack information without any allocations and as little stack frame usage as possible.
const size_t g_scratchSpaceSize = 2048;
diff --git a/Code/Framework/AzCore/Tests/EventTests.cpp b/Code/Framework/AzCore/Tests/EventTests.cpp
index 7640201e0d..571bdd5345 100644
--- a/Code/Framework/AzCore/Tests/EventTests.cpp
+++ b/Code/Framework/AzCore/Tests/EventTests.cpp
@@ -257,6 +257,48 @@ namespace UnitTest
EXPECT_FALSE(testEvent1.HasHandlerConnected());
EXPECT_TRUE(testEvent2.HasHandlerConnected());
}
+
+ TEST_F(EventTests, TestHandlerCopyConstructorOperator)
+ {
+ int32_t invokedCounter = 0;
+
+ AZ::Event<> testEvent;
+ AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; });
+
+ testHandler.Connect(testEvent);
+
+ AZ::Event<>::Handler testHandler2(testHandler);
+
+ EXPECT_TRUE(testHandler.IsConnected());
+ EXPECT_TRUE(testHandler2.IsConnected());
+
+ EXPECT_TRUE(invokedCounter == 0);
+ testEvent.Signal();
+ EXPECT_TRUE(invokedCounter == 2);
+ }
+
+ TEST_F(EventTests, TestHandlerCopyAssignmentOperator)
+ {
+ int32_t invokedCounter = 0;
+
+ AZ::Event<> testEvent;
+ AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; });
+
+ testHandler.Connect(testEvent);
+
+ AZ::Event<>::Handler testHandler2;
+
+ EXPECT_TRUE(testHandler.IsConnected());
+ EXPECT_FALSE(testHandler2.IsConnected());
+
+ testHandler2 = testHandler;
+
+ EXPECT_TRUE(testHandler2.IsConnected());
+
+ EXPECT_TRUE(invokedCounter == 0);
+ testEvent.Signal();
+ EXPECT_TRUE(invokedCounter == 2);
+ }
}
#if defined(HAVE_BENCHMARK)
diff --git a/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp b/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp
index e654ef4aa3..b505bba5dd 100644
--- a/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp
+++ b/Code/Framework/AzCore/Tests/Platform/Windows/Tests/IO/Streamer/StorageDriveTests_Windows.cpp
@@ -1155,7 +1155,7 @@ namespace Benchmark
class StorageDriveWindowsFixture : public benchmark::Fixture
{
public:
- constexpr static char* TestFileName = "StreamerBenchmark.bin";
+ constexpr static const char* TestFileName = "StreamerBenchmark.bin";
constexpr static size_t FileSize = 64_mib;
void SetupStreamer(bool enableFileSharing)
diff --git a/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.cpp b/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.cpp
index 7625679d69..75346227ed 100644
--- a/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.cpp
@@ -454,8 +454,8 @@ namespace AzFramework
}
////////////////////////////////////////////////////////////////////////////////////////////////
- InputDeviceKeyboard::InputDeviceKeyboard()
- : InputDevice(Id)
+ InputDeviceKeyboard::InputDeviceKeyboard(AzFramework::InputDeviceId id)
+ : InputDevice(id)
, m_modifierKeyStates(AZStd::make_shared())
, m_allChannelsById()
, m_keyChannelsById()
diff --git a/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h b/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h
index ea0aa1beec..9f61ba96f7 100644
--- a/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h
+++ b/Code/Framework/AzFramework/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h
@@ -240,7 +240,7 @@ namespace AzFramework
////////////////////////////////////////////////////////////////////////////////////////////
//! Constructor
- InputDeviceKeyboard();
+ InputDeviceKeyboard(AzFramework::InputDeviceId id = Id);
////////////////////////////////////////////////////////////////////////////////////////////
// Disable copying
diff --git a/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.cpp b/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.cpp
index a7180d7ec1..5cd940e989 100644
--- a/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.cpp
@@ -95,8 +95,8 @@ namespace AzFramework
}
////////////////////////////////////////////////////////////////////////////////////////////////
- InputDeviceMouse::InputDeviceMouse()
- : InputDevice(Id)
+ InputDeviceMouse::InputDeviceMouse(AzFramework::InputDeviceId id)
+ : InputDevice(id)
, m_allChannelsById()
, m_buttonChannelsById()
, m_movementChannelsById()
diff --git a/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.h b/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.h
index 7fc6a7a505..3feb79ac68 100644
--- a/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.h
+++ b/Code/Framework/AzFramework/AzFramework/Input/Devices/Mouse/InputDeviceMouse.h
@@ -111,7 +111,7 @@ namespace AzFramework
////////////////////////////////////////////////////////////////////////////////////////////
//! Constructor
- explicit InputDeviceMouse();
+ explicit InputDeviceMouse(AzFramework::InputDeviceId id = Id);
////////////////////////////////////////////////////////////////////////////////////////////
// Disable copying
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Character.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Character.cpp
index 59f492359d..df66442b11 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/Character.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Physics/Character.cpp
@@ -84,7 +84,7 @@ namespace Physics
if (serializeContext)
{
serializeContext->Class()
- ->Version(2)
+ ->Version(3)
->Field("CollisionLayer", &CharacterConfiguration::m_collisionLayer)
->Field("CollisionGroupId", &CharacterConfiguration::m_collisionGroupId)
->Field("Material", &CharacterConfiguration::m_materialSelection)
@@ -94,6 +94,7 @@ namespace Physics
->Field("MinDistance", &CharacterConfiguration::m_minimumMovementDistance)
->Field("MaxSpeed", &CharacterConfiguration::m_maximumSpeed)
->Field("ColliderTag", &CharacterConfiguration::m_colliderTag)
+ ->Field("ApplyMoveOnPhysicsTick", &CharacterConfiguration::m_applyMoveOnPhysicsTick)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
@@ -127,6 +128,9 @@ namespace Physics
->Attribute(AZ::Edit::Attributes::Step, 1.0f)
->DataElement(AZ::Edit::UIHandlers::Default, &CharacterConfiguration::m_colliderTag,
"Collider Tag", "Used to identify the collider associated with the character controller")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &CharacterConfiguration::m_applyMoveOnPhysicsTick,
+ "Apply Move On Tick", "Requests to add velocity will be accumulated and applied once on the physics pre-simulation tick "
+ "If unticked, explicit call to apply requested velocity is required")
;
}
}
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Character.h b/Code/Framework/AzFramework/AzFramework/Physics/Character.h
index ac46120879..e822736fd8 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/Character.h
+++ b/Code/Framework/AzFramework/AzFramework/Physics/Character.h
@@ -76,6 +76,7 @@ namespace Physics
AZStd::string m_colliderTag; //!< Used to identify the collider associated with the character controller.
AZStd::shared_ptr m_shapeConfig; //!< The shape to use when creating the character controller.
AZStd::vector> m_colliders; //!< The list of colliders to attach to the character controller.
+ bool m_applyMoveOnPhysicsTick = true; //!< Should accumulated velocity be applied on the physics tick.
};
/// Basic implementation of common character-style needs as a WorldBody. Is not a full-functional ship-ready
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp
index 3ccf093e4f..02597123db 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSceneQueries.cpp
@@ -136,6 +136,7 @@ namespace AzPhysics
->Property("Distance", BehaviorValueProperty(&RayCastRequest::m_distance))
->Property("Start", BehaviorValueProperty(&RayCastRequest::m_start))
->Property("Direction", BehaviorValueProperty(&RayCastRequest::m_direction))
+ ->Property("ReportMultipleHits", BehaviorValueProperty(&RayCastRequest::m_reportMultipleHits))
;
}
}
@@ -153,6 +154,45 @@ namespace AzPhysics
->Field("ReportMultipleHits", &ShapeCastRequest::m_reportMultipleHits)
;
}
+
+ if (auto* behaviorContext = azdynamic_cast(context))
+ {
+ behaviorContext->Class("ShapeCastRequest")
+ ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
+ ->Attribute(AZ::Script::Attributes::Module, "physics")
+ ->Attribute(AZ::Script::Attributes::Category, "PhysX")
+ ->Property("Distance", BehaviorValueProperty(&ShapeCastRequest::m_distance))
+ ->Property("Start", BehaviorValueProperty(&ShapeCastRequest::m_start))
+ ->Property("Direction", BehaviorValueProperty(&ShapeCastRequest::m_direction))
+ ;
+
+ behaviorContext->Method(
+ "CreateSphereCastRequest",
+ [](float radius, const AZ::Transform& startPose, const AZ::Vector3& direction, float distance,
+ SceneQuery::QueryType queryType, CollisionGroup collisionGroup)
+ {
+ return ShapeCastRequestHelpers::CreateSphereCastRequest(
+ radius, startPose, direction, distance, queryType, collisionGroup, nullptr);
+ });
+
+ behaviorContext->Method(
+ "CreateBoxCastRequest",
+ [](const AZ::Vector3& boxDimensions, const AZ::Transform& startPose, const AZ::Vector3& direction, float distance,
+ SceneQuery::QueryType queryType, CollisionGroup collisionGroup)
+ {
+ return ShapeCastRequestHelpers::CreateBoxCastRequest(
+ boxDimensions, startPose, direction, distance, queryType, collisionGroup, nullptr);
+ });
+
+ behaviorContext->Method(
+ "CreateCapsuleCastRequest",
+ [](float capsuleRadius, float capsuleHeight, const AZ::Transform& startPose, const AZ::Vector3& direction, float distance,
+ SceneQuery::QueryType queryType, CollisionGroup collisionGroup)
+ {
+ return ShapeCastRequestHelpers::CreateCapsuleCastRequest(
+ capsuleRadius, capsuleHeight, startPose, direction, distance, queryType, collisionGroup, nullptr);
+ });
+ }
}
namespace ShapeCastRequestHelpers
@@ -219,6 +259,40 @@ namespace AzPhysics
->Field("ShapeConfiguration", &OverlapRequest::m_shapeConfiguration)
;
}
+
+ if (auto* behaviorContext = azdynamic_cast(context))
+ {
+ behaviorContext->Class("OverlapRequest")
+ ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
+ ->Attribute(AZ::Script::Attributes::Module, "physics")
+ ->Attribute(AZ::Script::Attributes::Category, "PhysX")
+ ->Property("Pose", BehaviorValueProperty(&OverlapRequest::m_pose))
+ ;
+
+ behaviorContext->Method(
+ "CreateSphereOverlapRequest",
+ [](float radius, const AZ::Transform& pose)
+ {
+ return OverlapRequestHelpers::CreateSphereOverlapRequest(
+ radius, pose, nullptr);
+ });
+
+ behaviorContext->Method(
+ "CreateBoxOverlapRequest",
+ [](const AZ::Vector3& boxDimensions, const AZ::Transform& pose)
+ {
+ return OverlapRequestHelpers::CreateBoxOverlapRequest(
+ boxDimensions, pose, nullptr);
+ });
+
+ behaviorContext->Method(
+ "CreateCapsuleOverlapRequest",
+ [](float height, float radius, const AZ::Transform& pose)
+ {
+ return OverlapRequestHelpers::CreateCapsuleOverlapRequest(
+ height, radius, pose, nullptr);
+ });
+ }
}
namespace OverlapRequestHelpers
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp
index cdcdbe4655..05f41cc8da 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp
@@ -504,7 +504,7 @@ namespace Physics
}
}
- const AZ::Data::Asset& MaterialSelection::GetMaterialLibrary()
+ AZ::Data::Asset MaterialSelection::GetMaterialLibrary()
{
if (auto* physicsSystem = AZ::Interface::Get())
{
@@ -516,7 +516,7 @@ namespace Physics
return s_invalidMaterialLibrary;
}
- const AZ::Data::AssetId& MaterialSelection::GetMaterialLibraryId()
+ AZ::Data::AssetId MaterialSelection::GetMaterialLibraryId()
{
return GetMaterialLibrary().GetId();
}
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Material.h b/Code/Framework/AzFramework/AzFramework/Physics/Material.h
index bd15dd338e..455da207d1 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/Material.h
+++ b/Code/Framework/AzFramework/AzFramework/Physics/Material.h
@@ -306,8 +306,8 @@ namespace Physics
void SyncSelectionToMaterialLibrary();
- static const AZ::Data::Asset& GetMaterialLibrary();
- static const AZ::Data::AssetId& GetMaterialLibraryId();
+ static AZ::Data::Asset GetMaterialLibrary();
+ static AZ::Data::AssetId GetMaterialLibraryId();
bool AreMaterialSlotsReadOnly() const;
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.cpp b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.cpp
index 7840d10a6c..1b8117bd3e 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.cpp
@@ -48,6 +48,7 @@ namespace AzPhysics
->Attribute(AZ::Script::Attributes::Category, "Physics")
->Method("GetOnGravityChangeEvent", getOnGravityChange)
->Attribute(AZ::Script::Attributes::AzEventDescription, gravityChangedEventDescription)
+ ->Method("QueryScene", &Scene::QueryScene)
;
}
}
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp
index 4d41ab13b4..06f1802cc9 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp
@@ -41,7 +41,7 @@ namespace AzPhysics
{"Tick time"} // Parameters
};
- behaviorContext->Class("System Interface")
+ behaviorContext->Class("PhysicsSystemInterface")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
@@ -49,7 +49,21 @@ namespace AzPhysics
->Attribute(AZ::Script::Attributes::AzEventDescription, presimulateEventDescription)
->Method("GetOnPostsimulateEvent", getOnPostsimulateEvent)
->Attribute(AZ::Script::Attributes::AzEventDescription, postsimulateEventDescription)
- ;
+ ->Method("GetSceneHandle", &SystemInterface::GetSceneHandle)
+ ->Method("GetScene", &SystemInterface::GetScene);
+
+ behaviorContext->Method(
+ "GetPhysicsSystem",
+ []()
+ {
+ return AZ::Interface::Get();
+ });
+
+ behaviorContext
+ ->Constant("DefaultPhysicsSceneName", BehaviorConstant(DefaultPhysicsSceneName))
+ ->Constant("DefaultPhysicsSceneId", BehaviorConstant(DefaultPhysicsSceneId))
+ ->Constant("EditorPhysicsSceneName", BehaviorConstant(EditorPhysicsSceneName))
+ ->Constant("EditorPhysicsSceneId", BehaviorConstant(EditorPhysicsSceneId));
}
}
} // namespace AzPhysics
diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h
index c7d32739f2..694dcb7b72 100644
--- a/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h
+++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h
@@ -27,7 +27,7 @@ namespace AzFramework
AZStd::string m_ipAddress;
// The port number for the session.
- uint16_t m_port;
+ uint16_t m_port = 0;
};
//! SessionConnectionConfig
@@ -35,7 +35,7 @@ namespace AzFramework
struct PlayerConnectionConfig
{
// A unique identifier for player connection.
- uint32_t m_playerConnectionId;
+ uint32_t m_playerConnectionId = 0;
// A unique identifier for registered player in session.
AZStd::string m_playerSessionId;
diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h
index ae2896c337..a3262d0eb9 100644
--- a/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h
+++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h
@@ -37,7 +37,7 @@ namespace AzFramework
AZStd::string m_sessionName;
// The maximum number of players that can be connected simultaneously to the session.
- uint64_t m_maxPlayer;
+ uint64_t m_maxPlayer = 0;
};
//! SearchSessionsRequest
@@ -58,7 +58,7 @@ namespace AzFramework
AZStd::string m_sortExpression;
// The maximum number of results to return.
- uint8_t m_maxResult;
+ uint8_t m_maxResult = 0;
// A token that indicates the start of the next sequential page of results.
AZStd::string m_nextToken;
diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
index 17f61317e6..5f7f736514 100644
--- a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
+++ b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
@@ -24,10 +24,10 @@ namespace AzFramework
virtual ~SessionConfig() = default;
// A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.
- uint64_t m_creationTime;
+ uint64_t m_creationTime = 0;
// A time stamp indicating when this data object was terminated. Same format as creation time.
- uint64_t m_terminationTime;
+ uint64_t m_terminationTime = 0;
// A unique identifier for a player or entity creating the session.
AZStd::string m_creatorId;
@@ -48,13 +48,13 @@ namespace AzFramework
AZStd::string m_ipAddress;
// The port number for the session.
- uint16_t m_port;
+ uint16_t m_port = 0;
// The maximum number of players that can be connected simultaneously to the session.
- uint64_t m_maxPlayer;
+ uint64_t m_maxPlayer = 0;
// Number of players currently in the session.
- uint64_t m_currentPlayer;
+ uint64_t m_currentPlayer = 0;
// Current status of the session.
AZStd::string m_status;
diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp
index 3658f9cd22..0516cdd591 100644
--- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp
@@ -747,19 +747,24 @@ namespace AzFramework
return button == inputChannelId;
});
- if (inputChannelId == InputDeviceMouse::Movement::X)
+ // accept active mouse channel updates, inactive movement channels will just have a 0 delta
+ if (inputChannel.IsActive())
{
- return HorizontalMotionEvent{ aznumeric_cast(inputChannel.GetValue()) };
+ if (inputChannelId == InputDeviceMouse::Movement::X)
+ {
+ return HorizontalMotionEvent{ aznumeric_cast(inputChannel.GetValue()) };
+ }
+ else if (inputChannelId == InputDeviceMouse::Movement::Y)
+ {
+ return VerticalMotionEvent{ aznumeric_cast(inputChannel.GetValue()) };
+ }
+ else if (inputChannelId == InputDeviceMouse::Movement::Z)
+ {
+ return ScrollEvent{ inputChannel.GetValue() };
+ }
}
- else if (inputChannelId == InputDeviceMouse::Movement::Y)
- {
- return VerticalMotionEvent{ aznumeric_cast(inputChannel.GetValue()) };
- }
- else if (inputChannelId == InputDeviceMouse::Movement::Z)
- {
- return ScrollEvent{ inputChannel.GetValue() };
- }
- else if (wasMouseButton || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
+
+ if (wasMouseButton || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
{
return DiscreteInputEvent{ inputChannelId, inputChannel.GetState() };
}
diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp
index b92d8dc3bc..3e7d67888f 100644
--- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp
@@ -116,6 +116,11 @@ namespace AzFramework
SetFullScreenState(!GetFullScreenState());
}
+ float NativeWindow::GetDpiScaleFactor() const
+ {
+ return m_pimpl->GetDpiScaleFactor();
+ }
+
/*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow()
{
NativeWindowHandle defaultWindowHandle = nullptr;
@@ -228,4 +233,10 @@ namespace AzFramework
return false;
}
+ float NativeWindow::Implementation::GetDpiScaleFactor() const
+ {
+ // For platforms that aren't DPI-aware, we simply return a 1.0 ratio for no scaling
+ return 1.0f;
+ }
+
} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h
index 0b53b5b31c..2d5a897146 100644
--- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h
+++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h
@@ -128,6 +128,7 @@ namespace AzFramework
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
+ float GetDpiScaleFactor() const override;
//! Get the full screen state of the default window.
//! \return True if the default window is currently in full screen, false otherwise.
@@ -169,6 +170,7 @@ namespace AzFramework
virtual bool GetFullScreenState() const;
virtual void SetFullScreenState(bool fullScreenState);
virtual bool CanToggleFullScreenState() const;
+ virtual float GetDpiScaleFactor() const;
protected:
uint32_t m_width = 0;
diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h
index 959d7cc07b..f21993b80a 100644
--- a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h
+++ b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h
@@ -68,6 +68,11 @@ namespace AzFramework
//! Toggle the full screen state of the window.
virtual void ToggleFullScreenState() = 0;
+
+ //! Returns a scalar multiplier representing how many dots-per-inch this window has, compared
+ //! to a "standard" value of 96, the default for Windows in a DPI unaware setting. This can
+ //! be used to scale user interface elements to ensure legibility on high density displays.
+ virtual float GetDpiScaleFactor() const = 0;
};
using WindowRequestBus = AZ::EBus;
@@ -87,6 +92,9 @@ namespace AzFramework
//! This is called once when the window is Activated and also called if the user resizes the window.
virtual void OnWindowResized(uint32_t width, uint32_t height) { AZ_UNUSED(width); AZ_UNUSED(height); };
+ //! This is called if the window's underyling DPI scaling factor changes.
+ virtual void OnDpiScaleFactorChanged(float dpiScaleFactor) { AZ_UNUSED(dpiScaleFactor); }
+
//! This is called when the window is deactivated from code or if the user closes the window.
virtual void OnWindowClosed() {};
};
diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h b/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h
index 98893e2d01..2cf5b3f87e 100644
--- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h
+++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/AzFramework_Traits_Linux.h
@@ -12,5 +12,5 @@
#define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 1
#define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 0
#define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh"
-#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0
+#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1
#define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0
diff --git a/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h b/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h
index 6af4294a5c..73f6d212d4 100644
--- a/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h
+++ b/Code/Framework/AzFramework/Platform/Mac/AzFramework/AzFramework_Traits_Mac.h
@@ -12,5 +12,5 @@
#define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 0
#define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 1
#define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh"
-#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0
+#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1
#define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0
diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp
index 44a3757aea..470594853c 100644
--- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp
+++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
namespace AzFramework
@@ -17,7 +18,7 @@ namespace AzFramework
{
public:
AZ_CLASS_ALLOCATOR(NativeWindowImpl_Win32, AZ::SystemAllocator, 0);
- NativeWindowImpl_Win32() = default;
+ NativeWindowImpl_Win32();
~NativeWindowImpl_Win32() override;
// NativeWindow::Implementation overrides...
@@ -33,6 +34,7 @@ namespace AzFramework
bool GetFullScreenState() const override;
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override { return true; }
+ float GetDpiScaleFactor() const override;
private:
static DWORD ConvertToWin32WindowStyleMask(const WindowStyleMasks& styleMasks);
@@ -49,6 +51,9 @@ namespace AzFramework
RECT m_windowRectToRestoreOnFullScreenExit; //!< The position and size of the window to restore when exiting full screen.
UINT m_windowStyleToRestoreOnFullScreenExit; //!< The style(s) of the window to restore when exiting full screen.
bool m_isInBorderlessWindowFullScreenState = false; //!< Was a borderless window used to enter full screen state?
+
+ using GetDpiForWindowType = UINT(HWND hwnd);
+ GetDpiForWindowType* m_getDpiFunction = nullptr;
};
const char* NativeWindowImpl_Win32::s_defaultClassName = "O3DEWin32Class";
@@ -58,6 +63,15 @@ namespace AzFramework
return aznew NativeWindowImpl_Win32();
}
+ NativeWindowImpl_Win32::NativeWindowImpl_Win32()
+ {
+ // Attempt to load GetDpiForWindow from user32 at runtime, available on Windows 10+ versions >= 1607
+ if (auto user32module = AZ::DynamicModuleHandle::Create("user32"); user32module->Load(false))
+ {
+ m_getDpiFunction = user32module->GetFunction("GetDpiForWindow");
+ }
+ }
+
NativeWindowImpl_Win32::~NativeWindowImpl_Win32()
{
DestroyWindow(m_win32Handle);
@@ -237,6 +251,12 @@ namespace AzFramework
// Send all other WM_SYSKEYDOWN messages to the default WndProc.
break;
}
+ case WM_DPICHANGED:
+ {
+ const float newScaleFactor = nativeWindowImpl->GetDpiScaleFactor();
+ WindowNotificationBus::Event(nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnDpiScaleFactorChanged, newScaleFactor);
+ break;
+ }
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
@@ -330,6 +350,17 @@ namespace AzFramework
}
}
+ float NativeWindowImpl_Win32::GetDpiScaleFactor() const
+ {
+ constexpr UINT defaultDotsPerInch = 96;
+ UINT dotsPerInch = defaultDotsPerInch;
+ if (m_getDpiFunction)
+ {
+ dotsPerInch = m_getDpiFunction(m_win32Handle);
+ }
+ return aznumeric_cast(dotsPerInch) / aznumeric_cast(defaultDotsPerInch);
+ }
+
void NativeWindowImpl_Win32::EnterBorderlessWindowFullScreen()
{
if (m_isInBorderlessWindowFullScreenState)
diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp
index 130739ca39..651eff820e 100644
--- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp
+++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp
@@ -41,7 +41,7 @@ namespace AzNetworking
void TcpSocketManager::ProcessEvents(AZ::TimeMs maxBlockMs, const SocketEventCallback& readCallback, const SocketEventCallback& writeCallback)
{
- if(static_cast(m_maxFd) <= 0 && m_socketFds.empty())
+ if(static_cast(m_maxFd) <= 0 || m_socketFds.empty())
{
// There are no available sockets to process
return;
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
index 4c5e2adabd..7417bed2a0 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
@@ -3288,15 +3288,20 @@ namespace AzQtComponents
}
// Untab tabbed dock widgets before restoring, as the restore only works on dock widgets parented directly to the main window
- const QList dockWidgets = m_mainWindow->findChildren();
- for (QDockWidget* dockWidget : dockWidgets)
+ for (QDockWidget* dockWidget : m_mainWindow->findChildren(
+ QRegularExpression(QString("%1.*").arg(m_tabContainerIdentifierPrefix)), Qt::FindChildrenRecursively))
{
- if (QStackedWidget* stackedWidget = qobject_cast(dockWidget->parentWidget()))
+ DockTabWidget* tabWidget = qobject_cast(dockWidget->widget());
+ if (!tabWidget)
{
- if (AzQtComponents::DockTabWidget* tabWidget = qobject_cast(stackedWidget->parentWidget()))
- {
- tabWidget->removeTab(dockWidget);
- }
+ continue;
+ }
+
+ // Remove the tabs from the tab widget (we don't actually want to close them, which could delete them at this point)
+ int numTabs = tabWidget->count();
+ for (int i = 0; i < numTabs; ++i)
+ {
+ tabWidget->removeTab(0);
}
}
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Style.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Style.cpp
index 3356955ae7..05de144ff5 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Style.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Style.cpp
@@ -1303,6 +1303,10 @@ namespace AzQtComponents
}
break;
+ case QStyle::SP_MessageBoxInformation:
+ return QIcon(QString::fromUtf8(":/stylesheet/img/UI20/Info.svg"));
+ break;
+
default:
break;
}
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/BaseStyleSheet.qss b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/BaseStyleSheet.qss
index 894b2921d4..3499404572 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/BaseStyleSheet.qss
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/BaseStyleSheet.qss
@@ -123,6 +123,7 @@ QPlainTextEdit:focus
@import "LineEdit.qss";
@import "Menu.qss";
@import "MenuBar.qss";
+@import "MessageBox.qss";
@import "ProgressBar.qss";
@import "PushButton.qss";
@import "QDockWidget.qss";
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/MessageBox.qss b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/MessageBox.qss
new file mode 100644
index 0000000000..81aa7fd8d8
--- /dev/null
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/MessageBox.qss
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+ /* correct the padding around the two main labels to give space at the borders */
+QMessageBox QLabel#qt_msgbox_label
+{
+ padding-top: 20px;
+ padding-right: 20px;
+ padding-bottom: 20px;
+}
+
+QMessageBox QLabel#qt_msgboxex_icon_label
+{
+ padding-left: 20px;
+ padding-top: 20px;
+}
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
index 20a25f8fcb..909510d63b 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
@@ -354,17 +354,17 @@
img/UI20/toolbar/Grid.svg
img/UI20/toolbar/Lighting.svg
img/UI20/toolbar/Load.svg
- img/UI20/toolbar/Local.svg
+ img/UI20/toolbar/Local.svg
img/UI20/toolbar/Locked.svg
img/UI20/toolbar/Locked_Status.svg
- img/UI20/toolbar/LUA.svg
+ img/UI20/toolbar/LUA.svg
img/UI20/toolbar/Material.svg
img/UI20/toolbar/Measure.svg
img/UI20/toolbar/Move.svg
img/UI20/toolbar/Object_follow_terrain.svg
img/UI20/toolbar/Object_height.svg
img/UI20/toolbar/Object_list.svg
- img/UI20/toolbar/Parent.svg
+ img/UI20/toolbar/Parent.svg
img/UI20/toolbar/particle.svg
img/UI20/toolbar/Play.svg
img/UI20/toolbar/Redo.svg
@@ -385,7 +385,7 @@
img/UI20/toolbar/undo.svg
img/UI20/toolbar/Unlocked.svg
img/UI20/toolbar/Vertex_snapping.svg
- img/UI20/toolbar/World.svg
+ img/UI20/toolbar/World.svg
img/UI20/toolbar/X_axis.svg
img/UI20/toolbar/Y_axis.svg
img/UI20/toolbar/Z_axis.svg
@@ -459,6 +459,7 @@
Widgets/ComboBoxConfig.ini
Widgets/Menu.qss
Widgets/MenuBar.qss
+ Widgets/MessageBox.qss
Widgets/ProgressBarConfig.ini
Widgets/ProgressBar.qss
Widgets/PushButton.qss
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h
index 03bb76b03a..ef4d2deb5e 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorWindowRequestBus.h
@@ -36,8 +36,47 @@ namespace AzToolsFramework
/// Retrieve the main application window.
virtual QWidget* GetAppMainWindow() { return nullptr; }
};
-
using EditorWindowRequestBus = AZ::EBus;
+
+ class EditorWindowUIRequests : public AZ::EBusTraits
+ {
+ public:
+ using Bus = AZ::EBus;
+
+ //////////////////////////////////////////////////////////////////////////
+ // EBusTraits overrides
+ static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
+ //////////////////////////////////////////////////////////////////////////
+
+ /// Enable/Disable the Editor UI.
+ virtual void SetEditorUiEnabled([[maybe_unused]] bool enable) {}
+ };
+ using EditorWindowUIRequestBus = AZ::EBus;
+
+ using EnableUiFunction = AZStd::function;
+
+ /// Helper for EditorWindowRequests to be used as a
+ /// member instead of inheriting from EBus directly.
+ class EditorWindowRequestBusImpl
+ : public EditorWindowUIRequestBus::Handler
+ {
+ public:
+ /// Set the function to be called when entering ImGui Mode.
+ void SetEnableEditorUiFunc(const EnableUiFunction enableEditorUiFunc)
+ {
+ m_enableEditorUiFunc = AZStd::move(enableEditorUiFunc);
+ }
+
+ private:
+ // EditorWindowRequestBus
+ void SetEditorUiEnabled( [[maybe_unused]] bool enable) override
+ {
+ m_enableEditorUiFunc(enable);
+ }
+
+ EnableUiFunction m_enableEditorUiFunc; ///< Function to call when entering ImGui Mode.
+ };
+
} // namespace AzToolsFramework
#endif // AZTOOLSFRAMEWORK_EDITORWINDOWREQUESTBUS_H
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp
index 9db1e2e170..f89bd285de 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.cpp
@@ -222,6 +222,21 @@ namespace AzToolsFramework
void AssetBrowserTreeView::UpdateAfterFilter(bool hasFilter, bool selectFirstValidEntry)
{
+ const QModelIndexList& selectedIndexes = selectionModel()->selectedRows();
+
+ // If we've cleared the filter but had something selected, ensure it stays selected and visible.
+ if (!hasFilter && !selectedIndexes.isEmpty())
+ {
+ QModelIndex curIndex = selectedIndexes[0];
+ m_expandToEntriesByDefault = true;
+ m_treeStateSaver->ApplySnapshot();
+
+ setCurrentIndex(curIndex);
+ scrollTo(curIndex);
+
+ return;
+ }
+
// Flag our default expansion state so that we expand down to source entries after filtering
m_expandToEntriesByDefault = hasFilter;
// Then ask our state saver to apply its current snapshot again, falling back on asking us if entries should be expanded or not
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
index 8c541a2392..9dce8ff946 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
@@ -597,22 +597,23 @@ namespace AzToolsFramework
{
if (m_rootInstance && m_playInEditorData.m_isEnabled)
{
- auto end = m_playInEditorData.m_deactivatedEntities.rend();
- for (auto it = m_playInEditorData.m_deactivatedEntities.rbegin(); it != end; ++it)
- {
- AZ_Assert(*it, "Invalid entity added to list for re-activation after play-in-editor stopped.");
- (*it)->Activate();
- }
- m_playInEditorData.m_deactivatedEntities.clear();
-
AZ_Assert(m_playInEditorData.m_entities.IsSet(),
"Invalid Game Mode Entities Container encountered after play-in-editor stopped. "
"Confirm that the container was initialized correctly");
m_playInEditorData.m_entities.DespawnAllEntities();
m_playInEditorData.m_entities.Alert(
- [assets = AZStd::move(m_playInEditorData.m_assets)]([[maybe_unused]]uint32_t generation) mutable
+ [assets = AZStd::move(m_playInEditorData.m_assets),
+ deactivatedEntities = AZStd::move(m_playInEditorData.m_deactivatedEntities)]
+ ([[maybe_unused]]uint32_t generation) mutable
{
+ auto end = deactivatedEntities.rend();
+ for (auto it = deactivatedEntities.rbegin(); it != end; ++it)
+ {
+ AZ_Assert(*it, "Invalid entity added to list for re-activation after play-in-editor stopped.");
+ (*it)->Activate();
+ }
+
for (auto& asset : assets)
{
if (asset)
@@ -624,13 +625,21 @@ namespace AzToolsFramework
}
}
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
+
+ // This is a workaround until the replacement for GameEntityContext is done
+ AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesReset);
});
m_playInEditorData.m_entities.Clear();
-
- // This is a workaround until the replacement for GameEntityContext is done
- AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesReset);
}
+ // Game entity cleanup is queued onto the next tick via the DespawnEntities call.
+ // To avoid both game entities and Editor entities active at the same time
+ // we flush the tick queue to ensure the game entities are cleared first.
+ // The Alert callback that follows the DespawnEntities call will then reactivate the editor entities
+ // This should be considered temporary as a move to a less rigid event sequence that supports async entity clean up
+ // is the desired direction forward.
+ AZ::TickBus::ExecuteQueuedEvents();
+
m_playInEditorData.m_isEnabled = false;
}
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp
new file mode 100644
index 0000000000..eb5034fdd5
--- /dev/null
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace AzToolsFramework
+{
+ void QtEventToAzInputMapper::InitializeKeyMappings()
+ {
+ // This assumes modifier keys (ctrl/shift/alt) map to the left control/shift/alt keys as Qt provides no way to disambiguate
+ // in a platform agnostic manner. This could be expanded later with a PAL mapping from native scan codes acquired from
+ // QKeyEvents, if needed.
+ m_keyMappings = { {
+ { Qt::Key_0, AzFramework::InputDeviceKeyboard::Key::Alphanumeric0 },
+ { Qt::Key_1, AzFramework::InputDeviceKeyboard::Key::Alphanumeric1 },
+ { Qt::Key_2, AzFramework::InputDeviceKeyboard::Key::Alphanumeric2 },
+ { Qt::Key_3, AzFramework::InputDeviceKeyboard::Key::Alphanumeric3 },
+ { Qt::Key_4, AzFramework::InputDeviceKeyboard::Key::Alphanumeric4 },
+ { Qt::Key_5, AzFramework::InputDeviceKeyboard::Key::Alphanumeric5 },
+ { Qt::Key_6, AzFramework::InputDeviceKeyboard::Key::Alphanumeric6 },
+ { Qt::Key_7, AzFramework::InputDeviceKeyboard::Key::Alphanumeric7 },
+ { Qt::Key_8, AzFramework::InputDeviceKeyboard::Key::Alphanumeric8 },
+ { Qt::Key_9, AzFramework::InputDeviceKeyboard::Key::Alphanumeric9 },
+ { Qt::Key_A, AzFramework::InputDeviceKeyboard::Key::AlphanumericA },
+ { Qt::Key_B, AzFramework::InputDeviceKeyboard::Key::AlphanumericB },
+ { Qt::Key_C, AzFramework::InputDeviceKeyboard::Key::AlphanumericC },
+ { Qt::Key_D, AzFramework::InputDeviceKeyboard::Key::AlphanumericD },
+ { Qt::Key_E, AzFramework::InputDeviceKeyboard::Key::AlphanumericE },
+ { Qt::Key_F, AzFramework::InputDeviceKeyboard::Key::AlphanumericF },
+ { Qt::Key_G, AzFramework::InputDeviceKeyboard::Key::AlphanumericG },
+ { Qt::Key_H, AzFramework::InputDeviceKeyboard::Key::AlphanumericH },
+ { Qt::Key_I, AzFramework::InputDeviceKeyboard::Key::AlphanumericI },
+ { Qt::Key_J, AzFramework::InputDeviceKeyboard::Key::AlphanumericJ },
+ { Qt::Key_K, AzFramework::InputDeviceKeyboard::Key::AlphanumericK },
+ { Qt::Key_L, AzFramework::InputDeviceKeyboard::Key::AlphanumericL },
+ { Qt::Key_M, AzFramework::InputDeviceKeyboard::Key::AlphanumericM },
+ { Qt::Key_N, AzFramework::InputDeviceKeyboard::Key::AlphanumericN },
+ { Qt::Key_O, AzFramework::InputDeviceKeyboard::Key::AlphanumericO },
+ { Qt::Key_P, AzFramework::InputDeviceKeyboard::Key::AlphanumericP },
+ { Qt::Key_Q, AzFramework::InputDeviceKeyboard::Key::AlphanumericQ },
+ { Qt::Key_R, AzFramework::InputDeviceKeyboard::Key::AlphanumericR },
+ { Qt::Key_S, AzFramework::InputDeviceKeyboard::Key::AlphanumericS },
+ { Qt::Key_T, AzFramework::InputDeviceKeyboard::Key::AlphanumericT },
+ { Qt::Key_U, AzFramework::InputDeviceKeyboard::Key::AlphanumericU },
+ { Qt::Key_V, AzFramework::InputDeviceKeyboard::Key::AlphanumericV },
+ { Qt::Key_W, AzFramework::InputDeviceKeyboard::Key::AlphanumericW },
+ { Qt::Key_X, AzFramework::InputDeviceKeyboard::Key::AlphanumericX },
+ { Qt::Key_Y, AzFramework::InputDeviceKeyboard::Key::AlphanumericY },
+ { Qt::Key_Z, AzFramework::InputDeviceKeyboard::Key::AlphanumericZ },
+ { Qt::Key_Backspace, AzFramework::InputDeviceKeyboard::Key::EditBackspace },
+ { Qt::Key_CapsLock, AzFramework::InputDeviceKeyboard::Key::EditCapsLock },
+ { Qt::Key_Enter, AzFramework::InputDeviceKeyboard::Key::EditEnter },
+ { Qt::Key_Space, AzFramework::InputDeviceKeyboard::Key::EditSpace },
+ { Qt::Key_Tab, AzFramework::InputDeviceKeyboard::Key::EditTab },
+ { Qt::Key_Escape, AzFramework::InputDeviceKeyboard::Key::Escape },
+ { Qt::Key_F1, AzFramework::InputDeviceKeyboard::Key::Function01 },
+ { Qt::Key_F2, AzFramework::InputDeviceKeyboard::Key::Function02 },
+ { Qt::Key_F3, AzFramework::InputDeviceKeyboard::Key::Function03 },
+ { Qt::Key_F4, AzFramework::InputDeviceKeyboard::Key::Function04 },
+ { Qt::Key_F5, AzFramework::InputDeviceKeyboard::Key::Function05 },
+ { Qt::Key_F6, AzFramework::InputDeviceKeyboard::Key::Function06 },
+ { Qt::Key_F7, AzFramework::InputDeviceKeyboard::Key::Function07 },
+ { Qt::Key_F8, AzFramework::InputDeviceKeyboard::Key::Function08 },
+ { Qt::Key_F9, AzFramework::InputDeviceKeyboard::Key::Function09 },
+ { Qt::Key_F10, AzFramework::InputDeviceKeyboard::Key::Function10 },
+ { Qt::Key_F11, AzFramework::InputDeviceKeyboard::Key::Function11 },
+ { Qt::Key_F12, AzFramework::InputDeviceKeyboard::Key::Function12 },
+ { Qt::Key_F13, AzFramework::InputDeviceKeyboard::Key::Function13 },
+ { Qt::Key_F14, AzFramework::InputDeviceKeyboard::Key::Function14 },
+ { Qt::Key_F15, AzFramework::InputDeviceKeyboard::Key::Function15 },
+ { Qt::Key_F16, AzFramework::InputDeviceKeyboard::Key::Function16 },
+ { Qt::Key_F17, AzFramework::InputDeviceKeyboard::Key::Function17 },
+ { Qt::Key_F18, AzFramework::InputDeviceKeyboard::Key::Function18 },
+ { Qt::Key_F19, AzFramework::InputDeviceKeyboard::Key::Function19 },
+ { Qt::Key_F20, AzFramework::InputDeviceKeyboard::Key::Function20 },
+ { Qt::Key_Alt, AzFramework::InputDeviceKeyboard::Key::ModifierAltL },
+ { Qt::Key_Control, AzFramework::InputDeviceKeyboard::Key::ModifierCtrlL },
+ { Qt::Key_Shift, AzFramework::InputDeviceKeyboard::Key::ModifierShiftL },
+ { Qt::Key_Super_L, AzFramework::InputDeviceKeyboard::Key::ModifierSuperL },
+ { Qt::Key_Super_R, AzFramework::InputDeviceKeyboard::Key::ModifierSuperR },
+ { Qt::Key_Down, AzFramework::InputDeviceKeyboard::Key::NavigationArrowDown },
+ { Qt::Key_Left, AzFramework::InputDeviceKeyboard::Key::NavigationArrowLeft },
+ { Qt::Key_Right, AzFramework::InputDeviceKeyboard::Key::NavigationArrowRight },
+ { Qt::Key_Up, AzFramework::InputDeviceKeyboard::Key::NavigationArrowUp },
+ { Qt::Key_Delete, AzFramework::InputDeviceKeyboard::Key::NavigationDelete },
+ { Qt::Key_End, AzFramework::InputDeviceKeyboard::Key::NavigationEnd },
+ { Qt::Key_Home, AzFramework::InputDeviceKeyboard::Key::NavigationHome },
+ { Qt::Key_Insert, AzFramework::InputDeviceKeyboard::Key::NavigationInsert },
+ { Qt::Key_PageDown, AzFramework::InputDeviceKeyboard::Key::NavigationPageDown },
+ { Qt::Key_PageUp, AzFramework::InputDeviceKeyboard::Key::NavigationPageUp },
+ { Qt::Key_Apostrophe, AzFramework::InputDeviceKeyboard::Key::PunctuationApostrophe },
+ { Qt::Key_Backslash, AzFramework::InputDeviceKeyboard::Key::PunctuationBackslash },
+ { Qt::Key_BracketLeft, AzFramework::InputDeviceKeyboard::Key::PunctuationBracketL },
+ { Qt::Key_BracketRight, AzFramework::InputDeviceKeyboard::Key::PunctuationBracketR },
+ { Qt::Key_Comma, AzFramework::InputDeviceKeyboard::Key::PunctuationComma },
+ { Qt::Key_Equal, AzFramework::InputDeviceKeyboard::Key::PunctuationEquals },
+ { Qt::Key_hyphen, AzFramework::InputDeviceKeyboard::Key::PunctuationHyphen },
+ { Qt::Key_Period, AzFramework::InputDeviceKeyboard::Key::PunctuationPeriod },
+ { Qt::Key_Semicolon, AzFramework::InputDeviceKeyboard::Key::PunctuationSemicolon },
+ { Qt::Key_Slash, AzFramework::InputDeviceKeyboard::Key::PunctuationSlash },
+ { Qt::Key_QuoteLeft, AzFramework::InputDeviceKeyboard::Key::PunctuationTilde },
+ { Qt::Key_Pause, AzFramework::InputDeviceKeyboard::Key::WindowsSystemPause },
+ { Qt::Key_Print, AzFramework::InputDeviceKeyboard::Key::WindowsSystemPrint },
+ { Qt::Key_ScrollLock, AzFramework::InputDeviceKeyboard::Key::WindowsSystemScrollLock },
+ } };
+ }
+
+ void QtEventToAzInputMapper::InitializeMouseButtonMappings()
+ {
+ m_mouseButtonMappings = { {
+ { Qt::MouseButton::LeftButton, AzFramework::InputDeviceMouse::Button::Left },
+ { Qt::MouseButton::RightButton, AzFramework::InputDeviceMouse::Button::Right },
+ { Qt::MouseButton::MiddleButton, AzFramework::InputDeviceMouse::Button::Middle },
+ { Qt::MouseButton::ExtraButton1, AzFramework::InputDeviceMouse::Button::Other1 },
+ { Qt::MouseButton::ExtraButton2, AzFramework::InputDeviceMouse::Button::Other2 },
+ } };
+ }
+
+ // Currently this is only set for modifier keys.
+ // This should only be expanded sparingly, any keys handled here will not be bubbled up to the shortcut system.
+ // ex: If Key_S was here, the viewport would consume S key presses before the application could process a QAction with a Ctrl+S
+ // shortcut.
+ void QtEventToAzInputMapper::InitializeHighPriorityKeys()
+ {
+ m_highPriorityKeys = { Qt::Key_Alt, Qt::Key_Control, Qt::Key_Shift, Qt::Key_Super_L, Qt::Key_Super_R };
+ }
+
+ QtEventToAzInputMapper::EditorQtKeyboardDevice::EditorQtKeyboardDevice(AzFramework::InputDeviceId id)
+ : AzFramework::InputDeviceKeyboard(id)
+ {
+ // Disable all platform native processing in favor of our Qt event handling
+ SetImplementation(nullptr);
+ }
+
+ QtEventToAzInputMapper::EditorQtMouseDevice::EditorQtMouseDevice(AzFramework::InputDeviceId id)
+ : AzFramework::InputDeviceMouse(id)
+ {
+ // Disable all platform native processing in favor of our Qt event handling
+ SetImplementation(nullptr);
+ }
+
+ QtEventToAzInputMapper::QtEventToAzInputMapper(QWidget* sourceWidget, int syntheticDeviceId)
+ : QObject(sourceWidget)
+ , m_sourceWidget(sourceWidget)
+ , m_keyboardModifiers(AZStd::make_shared())
+ , m_cursorPosition(AZStd::make_shared())
+ {
+ InitializeKeyMappings();
+ InitializeMouseButtonMappings();
+ InitializeHighPriorityKeys();
+
+ // Add an arbitrary offset to our device index to avoid collision with real physical device index.
+ // We still have to use the keyboard and mouse device channel names because input channels are only addressed
+ // by their own name and their device index, so overlapping input channels between devices would conflict.
+ constexpr AZ::u32 syntheticDeviceOffset = 1000;
+ const AzFramework::InputDeviceId keyboardDeviceId(
+ AzFramework::InputDeviceKeyboard::Id.GetName(), syntheticDeviceId + syntheticDeviceOffset);
+ const AzFramework::InputDeviceId mouseDeviceId(
+ AzFramework::InputDeviceMouse::Id.GetName(), syntheticDeviceId + syntheticDeviceOffset);
+
+ m_keyboardDevice = AZStd::make_unique(keyboardDeviceId);
+ m_mouseDevice = AZStd::make_unique(mouseDeviceId);
+
+ AddChannels(m_keyboardDevice->m_allChannelsById);
+ AddChannels(m_mouseDevice->m_allChannelsById);
+
+ // Install a global event filter to ensure we don't miss mouse and key release events.
+ QApplication::instance()->installEventFilter(this);
+ }
+
+ bool QtEventToAzInputMapper::HandlesInputEvent(const AzFramework::InputChannel& channel) const
+ {
+ const AzFramework::InputChannelId& channelId = channel.GetInputChannelId();
+ if (channelId == AzFramework::InputDeviceMouse::Movement::X || channelId == AzFramework::InputDeviceMouse::Movement::Y)
+ {
+ return false;
+ }
+
+ // We map keyboard and mouse events from Qt, so flag all events coming from those devices
+ // as handled by our synthetic event system.
+ const AzFramework::InputDeviceId& deviceId = channel.GetInputDevice().GetInputDeviceId();
+ return deviceId.GetNameCrc32() == AzFramework::InputDeviceMouse::Id.GetNameCrc32() ||
+ deviceId.GetNameCrc32() == AzFramework::InputDeviceKeyboard::Id.GetNameCrc32();
+ }
+
+ void QtEventToAzInputMapper::SetEnabled(bool enabled)
+ {
+ m_enabled = enabled;
+ if (!enabled)
+ {
+ // Send an internal focus change event to reset our input state to fresh if we're disabled.
+ HandleFocusChange(nullptr);
+ }
+ }
+
+ bool QtEventToAzInputMapper::eventFilter(QObject* object, QEvent* event)
+ {
+ // Abort if processing isn't enabled.
+ if (!m_enabled)
+ {
+ return false;
+ }
+
+ // Because there's no "end" to mouse movement and wheel events, we reset mouse movement channels that have been opened
+ // during the next processed non-mouse event.
+ if (m_mouseChannelsNeedUpdate && event->type() != QEvent::Type::MouseMove && event->type() != QEvent::Type::Wheel)
+ {
+ m_cursorPosition->m_normalizedPositionDelta = AZ::Vector2::CreateZero();
+ ProcessPendingMouseEvents();
+ m_mouseChannelsNeedUpdate = false;
+ }
+
+ // Only accept mouse & key release events that originate from an object that is not our target widget,
+ // as we don't want to erroneously intercept user input meant for another component.
+ if (object != m_sourceWidget && event->type() != QEvent::Type::KeyRelease && event->type() != QEvent::Type::MouseButtonRelease)
+ {
+ return false;
+ }
+
+ // If our focus changes, go ahead and reset all input devices.
+ if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
+ {
+ HandleFocusChange(event);
+ }
+ // Map key events to input channels.
+ // ShortcutOverride is used in lieu of KeyPress for high priority input channels like Alt
+ // that need to be accepted and stopped before they bubble up and cause unintended behavior.
+ else if (
+ event->type() == QEvent::Type::KeyPress || event->type() == QEvent::Type::KeyRelease ||
+ event->type() == QEvent::Type::ShortcutOverride)
+ {
+ QKeyEvent* keyEvent = static_cast(event);
+ HandleKeyEvent(keyEvent);
+ }
+ // Map mouse events to input channels.
+ else if (event->type() == QEvent::Type::MouseButtonPress || event->type() == QEvent::Type::MouseButtonRelease || event->type() == QEvent::Type::MouseButtonDblClick)
+ {
+ QMouseEvent* mouseEvent = static_cast(event);
+ HandleMouseButtonEvent(mouseEvent);
+ }
+ // Map mouse movement to the movement input channels.
+ // This includes SystemCursorPosition alongside Movement::X and Movement::Y.
+ else if (event->type() == QEvent::Type::MouseMove)
+ {
+ QMouseEvent* mouseEvent = static_cast(event);
+ HandleMouseMoveEvent(mouseEvent);
+ }
+ // Map wheel events to the mouse Z movement channel.
+ else if (event->type() == QEvent::Type::Wheel)
+ {
+ QWheelEvent* wheelEvent = static_cast(event);
+ HandleWheelEvent(wheelEvent);
+ }
+
+ return false;
+ }
+
+ void QtEventToAzInputMapper::NotifyUpdateChannelIfNotIdle(const AzFramework::InputChannel* channel, QEvent* event)
+ {
+ if (channel->GetState() != AzFramework::InputChannel::State::Idle)
+ {
+ emit InputChannelUpdated(channel, event);
+ }
+ }
+
+ void QtEventToAzInputMapper::ProcessPendingMouseEvents()
+ {
+ auto systemCursorChannel =
+ GetInputChannel(AzFramework::InputDeviceMouse::SystemCursorPosition);
+ auto mouseWheelChannel =
+ GetInputChannel(AzFramework::InputDeviceMouse::Movement::Z);
+
+ systemCursorChannel->ProcessRawInputEvent(m_cursorPosition->m_normalizedPositionDelta.GetLength());
+ mouseWheelChannel->ProcessRawInputEvent(0.f);
+
+ NotifyUpdateChannelIfNotIdle(systemCursorChannel, nullptr);
+ NotifyUpdateChannelIfNotIdle(mouseWheelChannel, nullptr);
+ }
+
+ void QtEventToAzInputMapper::HandleMouseButtonEvent(QMouseEvent* mouseEvent)
+ {
+ const Qt::MouseButton button = mouseEvent->button();
+
+ if (auto buttonIt = m_mouseButtonMappings.find(button); buttonIt != m_mouseButtonMappings.end())
+ {
+ auto buttonChannel = GetInputChannel(buttonIt->second);
+
+ if (buttonChannel)
+ {
+ if (mouseEvent->type() != QEvent::Type::MouseButtonRelease)
+ {
+ buttonChannel->UpdateState(true);
+ }
+ else
+ {
+ buttonChannel->UpdateState(false);
+ }
+
+ NotifyUpdateChannelIfNotIdle(buttonChannel, mouseEvent);
+ }
+ }
+ }
+
+ void QtEventToAzInputMapper::HandleMouseMoveEvent(QMouseEvent* mouseEvent)
+ {
+ const QPoint mousePos = mouseEvent->pos();
+ const float normalizedX = aznumeric_cast(mousePos.x()) / aznumeric_cast(m_sourceWidget->width());
+ const float normalizedY = aznumeric_cast(mousePos.y()) / aznumeric_cast(m_sourceWidget->height());
+ const AZ::Vector2 normalizedPosition(normalizedX, normalizedY);
+ m_cursorPosition->m_normalizedPositionDelta = normalizedPosition - m_cursorPosition->m_normalizedPosition;
+ m_cursorPosition->m_normalizedPosition = normalizedPosition;
+ ProcessPendingMouseEvents();
+ m_mouseChannelsNeedUpdate = true;
+ }
+
+ void QtEventToAzInputMapper::HandleKeyEvent(QKeyEvent* keyEvent)
+ {
+ // Ignore key repeat events, they're unrelated to actual physical button presses.
+ if (keyEvent->isAutoRepeat())
+ {
+ return;
+ }
+
+ const Qt::Key key = static_cast(keyEvent->key());
+
+ // For ShortcutEvent, only continue processing if we're in the HighPriorityKeys set.
+ if (keyEvent->type() != QEvent::Type::ShortcutOverride || m_highPriorityKeys.find(key) != m_highPriorityKeys.end())
+ {
+ if (auto keyIt = m_keyMappings.find(key); keyIt != m_keyMappings.end())
+ {
+ auto keyChannel = GetInputChannel(keyIt->second);
+
+ if (keyChannel)
+ {
+ if (keyEvent->type() == QEvent::Type::KeyPress || keyEvent->type() == QEvent::Type::ShortcutOverride)
+ {
+ keyChannel->UpdateState(true);
+ }
+ else
+ {
+ keyChannel->UpdateState(false);
+ }
+
+ NotifyUpdateChannelIfNotIdle(keyChannel, keyEvent);
+ }
+ }
+ }
+ }
+
+ void QtEventToAzInputMapper::HandleWheelEvent(QWheelEvent* wheelEvent)
+ {
+ auto cursorZChannel =
+ GetInputChannel(AzFramework::InputDeviceMouse::Movement::Z);
+ const QPoint angleDelta = wheelEvent->angleDelta();
+ // Check both angles, as the alt modifier can change the wheel direction.
+ int wheelAngle = angleDelta.x();
+ if (wheelAngle == 0)
+ {
+ wheelAngle = angleDelta.y();
+ }
+ cursorZChannel->ProcessRawInputEvent(aznumeric_cast(wheelAngle));
+ NotifyUpdateChannelIfNotIdle(cursorZChannel, wheelEvent);
+ m_mouseChannelsNeedUpdate = true;
+ }
+
+ void QtEventToAzInputMapper::HandleFocusChange(QEvent* event)
+ {
+ for (auto& channelData : m_channels)
+ {
+ // If resetting the input device changed the channel state, submit it to the mapped channel list
+ // for processing.
+ if (channelData.second->IsActive())
+ {
+ channelData.second->UpdateState(false);
+ NotifyUpdateChannelIfNotIdle(channelData.second, event);
+ }
+ }
+ m_mouseChannelsNeedUpdate = false;
+ }
+} // namespace AzToolsFramework
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h
new file mode 100644
index 0000000000..6d95f3a4b0
--- /dev/null
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#if !defined(Q_MOC_RUN)
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#endif //! defined(Q_MOC_RUN)
+
+class QWidget;
+class QKeyEvent;
+class QMouseEvent;
+class QWheelEvent;
+
+namespace AzToolsFramework
+{
+ //! Maps events from the Qt input system to synthetic InputChannels in AzFramework
+ //! that can be used by AzFramework::ViewportControllers.
+ class QtEventToAzInputMapper final : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ QtEventToAzInputMapper(QWidget* sourceWidget, int syntheticDeviceId = 0);
+ ~QtEventToAzInputMapper() = default;
+
+ //! Queries whether a given input channel has a synthetic equivalent mapped
+ //! by this system.
+ //! \returns true if the channel is handled by MapQtEventToAzInput.
+ bool HandlesInputEvent(const AzFramework::InputChannel& channel) const;
+
+ //! Sets whether or not this input mapper should be updating its input channels from Qt events.
+ void SetEnabled(bool enabled);
+
+ // QObject overrides...
+ bool eventFilter(QObject* object, QEvent* event) override;
+
+ signals:
+ //! This signal fires whenever the state of the specified input channel changes.
+ //! This is determined by Qt events dispatched to the source widget.
+ //! \param channel The AZ input channel that has been updated.
+ //! \param event The underlying Qt event that triggered this change, if applicable.
+ void InputChannelUpdated(const AzFramework::InputChannel* channel, QEvent* event);
+
+ private:
+ // Gets an input channel of the specified type by ID.
+ template
+ TInputChannel* GetInputChannel(const AzFramework::InputChannelId& id)
+ {
+ auto channelIt = m_channels.find(id);
+ if (channelIt != m_channels.end())
+ {
+ return static_cast(channelIt->second);
+ }
+ return nullptr;
+ }
+
+ // Adds channels from the specified channel container to our input channel ID -> input channel lookup table.
+ // Used for rapid lookup.
+ template
+ void AddChannels(const TContainer& container)
+ {
+ for (const auto& channelData : container)
+ {
+ // Break const as we're taking these input channels from devices we own.
+ m_channels.emplace(channelData.first, const_cast(channelData.second));
+ }
+ }
+
+ // Our synthetic Keyboard device, does no internal keyboard handling and instead listens to this class for updates.
+ class EditorQtKeyboardDevice : public AzFramework::InputDeviceKeyboard
+ {
+ public:
+ EditorQtKeyboardDevice(AzFramework::InputDeviceId id);
+
+ friend class QtEventToAzInputMapper;
+ };
+
+ // Our synthetic Mouse device, does no internal keyboard handling and instead listens to this class for updates.
+ class EditorQtMouseDevice : public AzFramework::InputDeviceMouse
+ {
+ public:
+ EditorQtMouseDevice(AzFramework::InputDeviceId id);
+
+ friend class QtEventToAzInputMapper;
+ };
+
+ // Emits InputChannelUpdated if channel has transitioned in state (i.e. has gone from active to inactive or vice versa).
+ void NotifyUpdateChannelIfNotIdle(const AzFramework::InputChannel* channel, QEvent* event);
+
+ // Processes any pending mouse movement events, this allows mouse movement channels to close themselves.
+ void ProcessPendingMouseEvents();
+
+ // Handle mouse click events.
+ void HandleMouseButtonEvent(QMouseEvent* mouseEvent);
+ // Handle mouse move events.
+ void HandleMouseMoveEvent(QMouseEvent* mouseEvent);
+ // Handles key press / release events (or ShortcutOverride events for keys listed in m_highPriorityKeys).
+ void HandleKeyEvent(QKeyEvent* keyEvent);
+ // Handles mouse wheel events.
+ void HandleWheelEvent(QWheelEvent* wheelEvent);
+ // Handles focus change events.
+ void HandleFocusChange(QEvent* event);
+
+ // Populates m_keyMappings.
+ void InitializeKeyMappings();
+ // Populates m_mouseButtonMappings.
+ void InitializeMouseButtonMappings();
+ // Populates m_highPriorityKeys.
+ void InitializeHighPriorityKeys();
+
+ // The current keyboard modifier state used by our synthetic key input channels.
+ AZStd::shared_ptr m_keyboardModifiers;
+ // The current normalized cursor position used by our synthetic system cursor event.
+ AZStd::shared_ptr m_cursorPosition;
+ // A lookup table for Qt key -> AZ input channel.
+ AZStd::unordered_map m_keyMappings;
+ // A lookup table for Qt mouse button -> AZ input channel.
+ AZStd::unordered_map m_mouseButtonMappings;
+ // A set of high priority keys that need to be processed at the ShortcutOverride level instead of the
+ // KeyEvent level. This prevents e.g. the main menu bar from processing a press of the "alt" key when the
+ // viewport consumes the event.
+ AZStd::unordered_set m_highPriorityKeys;
+ // A lookup table for AZ input channel ID -> physical input channel on our mouse or keyboard device.
+ AZStd::unordered_map m_channels;
+ // The source widget to map events from, used to calculate the relative mouse position within the widget bounds.
+ QWidget* m_sourceWidget;
+ // Flags when mouse movement channels have been opened and may need to be closed (as there are no movement ended events).
+ bool m_mouseChannelsNeedUpdate = false;
+ // Flags whether or not Qt events should currently be processed.
+ bool m_enabled = true;
+
+ // Our viewport-specific AZ devices. We control their internal input channel states.
+ AZStd::unique_ptr m_mouseDevice;
+ AZStd::unique_ptr m_keyboardDevice;
+ };
+} // namespace AzToolsFramework
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
index 4d02c61b3d..bac63d94b4 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
@@ -47,7 +47,7 @@ namespace AzToolsFramework
return valueIterator->value;
}
- bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom)
+ bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom, StoreInstanceFlags flags)
{
InstanceEntityIdMapper entityIdMapper;
entityIdMapper.SetStoringInstance(instance);
@@ -58,6 +58,11 @@ namespace AzToolsFramework
settings.m_metadata.Add(static_cast(&entityIdMapper));
settings.m_metadata.Add(&entityIdMapper);
+ if ((flags & StoreInstanceFlags::StripDefaultValues) != StoreInstanceFlags::StripDefaultValues)
+ {
+ settings.m_keepDefaults = true;
+ }
+
AZ::JsonSerializationResult::ResultCode result =
AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), instance, settings);
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h
index 20ba49e0ca..709461022e 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h
@@ -36,13 +36,25 @@ namespace AzToolsFramework
PrefabDomValueReference FindPrefabDomValue(PrefabDomValue& parentValue, const char* valueName);
PrefabDomValueConstReference FindPrefabDomValue(const PrefabDomValue& parentValue, const char* valueName);
+ enum class StoreInstanceFlags : uint8_t
+ {
+ //! No flags used during the call to LoadInstanceFromPrefabDom.
+ None = 0,
+
+ //! By default an instance will be stored with default values. In cases where we want to store less json without defaults
+ //! such as saving to disk, this flag will control that behavior.
+ StripDefaultValues = 1 << 0
+ };
+ AZ_DEFINE_ENUM_BITWISE_OPERATORS(StoreInstanceFlags);
+
/**
* Stores a valid Prefab Instance within a Prefab Dom. Useful for generating Templates
* @param instance The instance to store
* @param prefabDom The prefabDom that will be used to store the Instance data
+ * @param flags Controls behavior such as whether to store default values
* @return bool on whether the operation succeeded
*/
- bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom);
+ bool StoreInstanceInPrefabDom(const Instance& instance, PrefabDom& prefabDom, StoreInstanceFlags flags = StoreInstanceFlags::None);
enum class LoadInstanceFlags : uint8_t
{
@@ -52,13 +64,13 @@ namespace AzToolsFramework
//! unique, e.g. when they are duplicates of live entities, this flag will assign them a random new id.
AssignRandomEntityId = 1 << 0
};
- AZ_DEFINE_ENUM_BITWISE_OPERATORS(LoadInstanceFlags)
+ AZ_DEFINE_ENUM_BITWISE_OPERATORS(LoadInstanceFlags);
/**
* Loads a valid Prefab Instance from a Prefab Dom. Useful for generating Instances.
* @param instance The Instance to load.
* @param prefabDom The prefabDom that will be used to load the Instance data.
- * @param shouldClearContainers Whether to clear containers in Instance while loading.
+ * @param flags Controls behavior such as random entity id assignment.
* @return bool on whether the operation succeeded.
*/
bool LoadInstanceFromPrefabDom(
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp
index 92ff87b9ba..c29eea9e80 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp
@@ -172,7 +172,7 @@ namespace AzToolsFramework
progressedFilePathsSet.emplace(relativePath);
// Get 'Instances' value from Template.
- bool isLoadedWithErrors = false;
+ bool isLoadSuccessful = true;
PrefabDomValueReference instancesReference = newTemplate.GetInstancesValue();
if (instancesReference.has_value())
{
@@ -185,7 +185,7 @@ namespace AzToolsFramework
{
if (!LoadNestedInstance(instanceIterator, newTemplateId, progressedFilePathsSet))
{
- isLoadedWithErrors = true;
+ isLoadSuccessful = false;
AZ_Error(
"Prefab", false,
"PrefabLoader::LoadTemplate - "
@@ -196,7 +196,10 @@ namespace AzToolsFramework
}
}
}
- newTemplate.MarkAsLoadedWithErrors(isLoadedWithErrors);
+
+ isLoadSuccessful &= SanitizeLoadedTemplate(newTemplate.GetPrefabDom());
+
+ newTemplate.MarkAsLoadedWithErrors(!isLoadSuccessful);
// Un-mark the file as being in progress.
progressedFilePathsSet.erase(originPath);
@@ -277,6 +280,63 @@ namespace AzToolsFramework
return !nestedTemplateReference->get().IsLoadedWithErrors();
}
+ bool PrefabLoader::SanitizeLoadedTemplate(PrefabDomReference loadedTemplateDom)
+ {
+ // Prefabs are stored to disk with default values stripped. However, while in memory, we need those default values to be
+ // present to make patches work consistently. To accomplish this, we'll instantiate the Dom, then serialize the instance
+ // back into a Dom with all of the default values preserved.
+ // Note that this is the default behavior in Prefab serialization, so we don't need to specify StoreInstanceFlags.
+
+ if (!loadedTemplateDom)
+ {
+ return false;
+ }
+
+ Instance loadedPrefabInstance;
+ if (!PrefabDomUtils::LoadInstanceFromPrefabDom(loadedPrefabInstance, loadedTemplateDom->get()))
+ {
+ return false;
+ }
+
+ PrefabDom storedPrefabDom(&loadedTemplateDom->get().GetAllocator());
+ if (!PrefabDomUtils::StoreInstanceInPrefabDom(loadedPrefabInstance, storedPrefabDom))
+ {
+ return false;
+ }
+
+ loadedTemplateDom->get().CopyFrom(storedPrefabDom, loadedTemplateDom->get().GetAllocator());
+ return true;
+ }
+
+ bool PrefabLoader::SanitizeSavingTemplate(PrefabDomReference savingTemplateDom)
+ {
+ // Prefabs are stored in memory with default values spelled out to make patches work consistently. However, when we store them
+ // to disk, we strip those default values to save on file size. To accomplish this, we'll instantiate the Dom, then serialize
+ // the instance back into a Dom with all of the default values stripped.
+
+ if (!savingTemplateDom)
+ {
+ return false;
+ }
+
+ Instance savingPrefabInstance;
+ if (!PrefabDomUtils::LoadInstanceFromPrefabDom(savingPrefabInstance, savingTemplateDom->get()))
+ {
+ return false;
+ }
+
+ PrefabDom storedPrefabDom(&savingTemplateDom->get().GetAllocator());
+ if (!PrefabDomUtils::StoreInstanceInPrefabDom(savingPrefabInstance, storedPrefabDom,
+ PrefabDomUtils::StoreInstanceFlags::StripDefaultValues))
+ {
+ return false;
+ }
+
+ savingTemplateDom->get().CopyFrom(storedPrefabDom, savingTemplateDom->get().GetAllocator());
+
+ return true;
+ }
+
bool PrefabLoader::SaveTemplate(TemplateId templateId)
{
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
@@ -395,7 +455,7 @@ namespace AzToolsFramework
// Make a copy of a our prefab DOM where nested instances become file references with patch data
PrefabDom templateDomToSave;
- if (!templateToSave.CopyTemplateIntoPrefabFileFormat(templateDomToSave))
+ if (!CopyTemplateIntoPrefabFileFormat(templateToSave, templateDomToSave))
{
AZ_Error(
"Prefab", false,
@@ -410,6 +470,80 @@ namespace AzToolsFramework
return { { AZStd::move(templateDomToSave), templateToSave.GetFilePath() } };
}
+ bool PrefabLoader::CopyTemplateIntoPrefabFileFormat(TemplateReference templateRef, PrefabDom& output)
+ {
+ AZ_Assert(
+ templateRef.has_value(),
+ "CopyTemplateIntoPrefabFileFormat called on empty template reference."
+ );
+
+ PrefabDom& prefabDom = templateRef->get().GetPrefabDom();
+
+ // Start by making a copy of our dom
+ output.CopyFrom(prefabDom, prefabDom.GetAllocator());
+
+ SanitizeSavingTemplate(output);
+
+ for (const LinkId& linkId : templateRef->get().GetLinks())
+ {
+ AZStd::optional> findLinkResult = m_prefabSystemComponentInterface->FindLink(linkId);
+
+ if (!findLinkResult.has_value())
+ {
+ AZ_Error(
+ "Prefab", false,
+ "Link with id %llu could not be found while attempting to store "
+ "Prefab Template with source path %s in Prefab File format. "
+ "Unable to proceed.",
+ linkId, templateRef->get().GetFilePath().c_str());
+
+ return false;
+ }
+
+ if (!findLinkResult->get().IsValid())
+ {
+ AZ_Error(
+ "Prefab", false,
+ "Link with id %llu and is invalid during attempt to store "
+ "Prefab Template with source path %s in Prefab File format. "
+ "Unable to Proceed.",
+ linkId, templateRef->get().GetFilePath().c_str());
+
+ return false;
+ }
+
+ Link& link = findLinkResult->get();
+
+ PrefabDomPath instancePath = link.GetInstancePath();
+ PrefabDom& linkDom = link.GetLinkDom();
+
+ // Get the instance value of the Template copy
+ // This currently stores a fully realized nested Template Dom
+ PrefabDomValue* instanceValue = instancePath.Get(output);
+
+ if (!instanceValue)
+ {
+ AZ_Error(
+ "Prefab", false,
+ "Template::CopyTemplateIntoPrefabFileFormat: Unable to recover nested instance Dom value from link with id %llu "
+ "while attempting to store a collapsed version of a Prefab Template with source path %s. Unable to proceed.",
+ linkId, templateRef->get().GetFilePath().c_str());
+
+ return false;
+ }
+
+ // Copy the contents of the Link to overwrite our Template Dom copies Instance
+ // The instance is now "collapsed" as it contains the file reference and patches from the link
+ instanceValue->CopyFrom(linkDom, prefabDom.GetAllocator());
+ }
+
+ // Remove Source parameter from the dom. It will be added on file load, and should not be stored to disk.
+ PrefabDomPath sourcePath = PrefabDomPath((AZStd::string("/") + PrefabDomUtils::SourceName).c_str());
+ sourcePath.Erase(output);
+
+ return true;
+ }
+
bool PrefabLoader::IsValidPrefabPath(AZ::IO::PathView path)
{
// Check for OS invalid character and paths ending on '/' '\\' separators as final char
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.h
index b1c8daeaac..20d1f209e9 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.h
@@ -25,6 +25,8 @@ namespace AzToolsFramework
namespace Prefab
{
class PrefabSystemComponentInterface;
+ class Template;
+ using TemplateReference = AZStd::optional>;
/**
* The Prefab Loader helps saving/loading Prefab files.
@@ -106,6 +108,16 @@ namespace AzToolsFramework
static bool IsValidPrefabPath(AZ::IO::PathView path);
private:
+ /**
+ * Copies the template dom provided and manipulates it into the proper format to be saved to disk.
+ * @param templateRef The template whose dom we want to transform into the proper format to be saved to disk.
+ * @param[out] output The PrefabDom reference we want to store the result into.
+ * @return True if the operation was completed correctly, false otherwise.
+ */
+ bool CopyTemplateIntoPrefabFileFormat(
+ TemplateReference templateRef,
+ PrefabDom& output
+ );
/**
* Load Prefab Template from given file path to memory and return the id of loaded Template.
@@ -141,6 +153,20 @@ namespace AzToolsFramework
TemplateId targetTemplateId,
AZStd::unordered_set