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/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/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/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/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/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/editor_lib_files.cmake b/Code/Editor/editor_lib_files.cmake
index 562623dab2..fc1694240e 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
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/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/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/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/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/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/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/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/UI/LegacyFramework/Core/EditorFrameworkApplication.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.cpp
index ccc7ef1fd7..f342b1afab 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.cpp
@@ -151,6 +151,12 @@ namespace LegacyFramework
specializations.Append("tools");
}
+ void Application::CreateReflectionManager()
+ {
+ AZ::ComponentApplication::CreateReflectionManager();
+ GetSerializeContext()->CreateEditContext();
+ }
+
int Application::Run(const ApplicationDesc& desc)
{
if (!AZ::AllocatorInstance::IsReady())
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.h
index 42aacf3dbd..5cde088c2d 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.h
@@ -56,6 +56,8 @@ namespace LegacyFramework
virtual int Run(const ApplicationDesc& desc);
Application();
+ void CreateReflectionManager() override;
+
protected:
// ------------------------------------------------------------------
diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake
index 85976e1cb9..628b5fffac 100644
--- a/Code/LauncherUnified/launcher_generator.cmake
+++ b/Code/LauncherUnified/launcher_generator.cmake
@@ -122,6 +122,8 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC
FOLDER ${project_name}
)
+ # After ensuring that we correctly support DPI scaling, this should be switched to "PerMonitor"
+ set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DPI_AWARE "OFF")
if(LY_DEFAULT_PROJECT_PATH)
set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\"")
endif()
diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp
index 7602ed05aa..3c1f1b4cda 100644
--- a/Code/Legacy/CrySystem/SystemInit.cpp
+++ b/Code/Legacy/CrySystem/SystemInit.cpp
@@ -1043,7 +1043,7 @@ string GetUniqueLogFileName(string logFileName)
logFileNamePrefix = logFileName.substr(0, extensionIndex);
}
- logFileName.Format("%s(%d)%s", logFileNamePrefix.c_str(), instance, logFileExtension.c_str());
+ logFileName = AZStd::string::format("%s(%d)%s", logFileNamePrefix.c_str(), instance, logFileExtension.c_str()).c_str();
return logFileName;
}
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp
index 9959ccf5cd..28f8d9bb4e 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.cpp
@@ -346,7 +346,8 @@ namespace TestImpact
return orphans;
}
- ChangeDependencyList DynamicDependencyMap::ApplyAndResoveChangeList(const ChangeList& changeList)
+ ChangeDependencyList DynamicDependencyMap::ApplyAndResoveChangeList(
+ const ChangeList& changeList, Policy::IntegrityFailure integrityFailurePolicy)
{
AZStd::vector createDependencies;
AZStd::vector updateDependencies;
@@ -364,11 +365,15 @@ namespace TestImpact
{
if (sourceDependency->GetNumCoveringTestTargets())
{
- const AZStd::string msg = AZStd::string::format("The newly-created file %s belongs to a build target yet "
+ const AZStd::string msg = AZStd::string::format("The newly-created file '%s' belongs to a build target yet "
"still has coverage data in the source covering test list implying that a delete CRUD operation has been "
- "missed, thus the integrity of the source covering test list has been compromised", createdFile.c_str());
+ "missed, thus the integrity of the source covering test list has been compromised.", createdFile.c_str());
AZ_Error("File Creation", false, msg.c_str());
- throw DependencyException(msg);
+
+ if (integrityFailurePolicy == Policy::IntegrityFailure::Abort)
+ {
+ throw DependencyException(msg);
+ }
}
if (sourceDependency->GetNumParentTargets())
@@ -418,18 +423,26 @@ namespace TestImpact
{
if (sourceDependency->GetNumCoveringTestTargets())
{
- const AZStd::string msg = AZStd::string::format("The deleted file %s still belongs to a build target and still "
+ const AZStd::string msg = AZStd::string::format("The deleted file '%s' still belongs to a build target and still "
"has coverage data in the source covering test list, implying that the integrity of both the source to target "
- "mappings and the source covering test list has been compromised", deletedFile.c_str());
+ "mappings and the source covering test list has been compromised.", deletedFile.c_str());
AZ_Error("File Delete", false, msg.c_str());
- throw DependencyException(msg);
+
+ if (integrityFailurePolicy == Policy::IntegrityFailure::Abort)
+ {
+ throw DependencyException(msg);
+ }
}
else
{
- const AZStd::string msg = AZStd::string::format("The deleted file %s still belongs to a build target implying "
- "that the integrity of the source to target mappings has been compromised", deletedFile.c_str());
+ const AZStd::string msg = AZStd::string::format("The deleted file '%s' still belongs to a build target implying "
+ "that the integrity of the source to target mappings has been compromised.", deletedFile.c_str());
AZ_Error("File Delete", false, msg.c_str());
- throw DependencyException(msg);
+
+ if (integrityFailurePolicy == Policy::IntegrityFailure::Abort)
+ {
+ throw DependencyException(msg);
+ }
}
}
else
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h
index 35f90930f8..d021851c25 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Dependency/TestImpactDynamicDependencyMap.h
@@ -8,6 +8,7 @@
#pragma once
#include
+#include
#include
#include
@@ -91,8 +92,10 @@ namespace TestImpact
//! Applies the specified change list to the dependency map and resolves the change list to a change dependency list
//! containing the updated source dependencies for each source file in the change list.
//! @param changeList The change list to apply and resolve.
+ //! @param integrityFailurePolicy The policy to use for handling integrity errors in the source dependency map.
//! @returns The change list as resolved to the appropriate source dependencies.
- [[nodiscard]] ChangeDependencyList ApplyAndResoveChangeList(const ChangeList& changeList);
+ [[nodiscard]] ChangeDependencyList ApplyAndResoveChangeList(
+ const ChangeList& changeList, Policy::IntegrityFailure integrityFailurePolicy);
//! Removes the specified test target from all source coverage.
void RemoveTestTargetFromSourceCoverage(const TestTarget* testTarget);
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp
index af6f02fa20..e325463324 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestImpactRuntime.cpp
@@ -205,7 +205,7 @@ namespace TestImpact
AZStd::vector discardedTestTargets;
// Select and prioritize the test targets pertinent to this change list
- const auto changeDependencyList = m_dynamicDependencyMap->ApplyAndResoveChangeList(changeList);
+ const auto changeDependencyList = m_dynamicDependencyMap->ApplyAndResoveChangeList(changeList, m_integrationFailurePolicy);
const auto selectedTestTargets = m_testSelectorAndPrioritizer->SelectTestTargets(changeDependencyList, testPrioritizationPolicy);
// Populate a set with the selected test targets so that we can infer the discarded test target not selected for this change list
diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h
index 6c3d0e0a93..a75c3bce31 100644
--- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h
+++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h
@@ -72,7 +72,7 @@ namespace AWSCore
{
static constexpr const char AWSScriptBehaviorS3Name[] = "AWSScriptBehaviorS3";
static constexpr const char OutputFileIsEmptyErrorMessage[] = "Request validation failed, output file is empty.";
- static constexpr const char OutputFileMissFullPathErrorMessage[] = "Request validation failed, output file miss full path.";
+ static constexpr const char OutputFileFailedToResolveErrorMessage[] = "Request validation failed, cannot resolve the output file path.";
static constexpr const char OutputFileIsDirectoryErrorMessage[] = "Request validation failed, output file is a directory.";
static constexpr const char OutputFileDirectoryNotExistErrorMessage[] = "Request validation failed, output file directory doesn't exist.";
static constexpr const char OutputFileIsReadOnlyErrorMessage[] = "Request validation failed, output file is read-only.";
diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp
index aa397ca97c..f47dda8046 100644
--- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp
+++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp
@@ -6,6 +6,7 @@
*/
#include
+#include
#include
#include
#include
@@ -171,12 +172,16 @@ namespace AWSCore
AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileIsEmptyErrorMessage);
return false;
}
- if (!AzFramework::StringFunc::Path::HasDrive(outFile.c_str()))
+
+ char resolvedPath[AZ_MAX_PATH_LEN] = { 0 };
+ if (!AZ::IO::FileIOBase::GetInstance()->ResolvePath(outFile.c_str(), resolvedPath, AZ_MAX_PATH_LEN))
{
- AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileMissFullPathErrorMessage);
- AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileMissFullPathErrorMessage);
+ AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileFailedToResolveErrorMessage);
+ AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileFailedToResolveErrorMessage);
return false;
}
+ outFile = resolvedPath;
+
if (AZ::IO::FileIOBase::GetInstance()->IsDirectory(outFile.c_str()))
{
AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileIsDirectoryErrorMessage);
diff --git a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp
index cac0a042bc..aca0a1c6d1 100644
--- a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp
+++ b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp
@@ -122,11 +122,11 @@ TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithEmptyOutfileName_InvokeOnEr
AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", "");
}
-TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithOutfileNameMissFullPath_InvokeOnError)
+TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithOutfileFailedToResolve_InvokeOnError)
{
AWSScriptBehaviorS3NotificationBusHandlerMock s3HandlerMock;
EXPECT_CALL(s3HandlerMock, OnGetObjectError(::testing::_)).Times(1);
- AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", "dummyOut.txt");
+ AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", "@dummy@/dummyOut.txt");
}
TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithOutfileNameIsDirectory_InvokeOnError)
diff --git a/Gems/AWSCore/cdk/example/example_resources_stack.py b/Gems/AWSCore/cdk/example/example_resources_stack.py
index 7afbd9bb4c..a200d0857a 100755
--- a/Gems/AWSCore/cdk/example/example_resources_stack.py
+++ b/Gems/AWSCore/cdk/example/example_resources_stack.py
@@ -107,31 +107,31 @@ class ExampleResources(core.Stack):
self._s3_output = core.CfnOutput(
self,
id=f'ExampleBucketOutput',
- description='An example S3 bucket to use with AWSCore ScriptBehaviors',
- export_name=f"ExampleS3Bucket",
- value=self._s3_bucket.bucket_arn)
+ description='An example S3 bucket name to use with AWSCore ScriptBehaviors',
+ export_name=f"{self.stack_name}:ExampleS3Bucket",
+ value=self._s3_bucket.bucket_name)
# Define exports
# Export resource group
self._lambda_output = core.CfnOutput(
self,
id=f'ExampleLambdaOutput',
- description='An example Lambda to use with AWSCore ScriptBehaviors',
- export_name=f"ExampleLambdaFunction",
- value=self._lambda.function_arn)
+ description='An example Lambda name to use with AWSCore ScriptBehaviors',
+ export_name=f"{self.stack_name}::ExampleLambdaFunction",
+ value=self._lambda.function_name)
# Export DynamoDB Table
self._table_output = core.CfnOutput(
self,
id=f'ExampleDynamoTableOutput',
- description='An example DynamoDB Table to use with AWSCore ScriptBehaviors',
- export_name=f"ExampleTable",
- value=self._table.table_arn)
+ description='An example DynamoDB Table name to use with AWSCore ScriptBehaviors',
+ export_name=f"{self.stack_name}:ExampleTable",
+ value=self._table.table_name)
# Export user policy
self._user_policy = core.CfnOutput(
self,
id=f'ExampleUserPolicyOutput',
description='A User policy to invoke example resources',
- export_name=f"ExampleUserPolicy",
+ export_name=f"{self.stack_name}:ExampleUserPolicy",
value=self._policy.managed_policy_arn)
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftActivityUtils.cpp b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftActivityUtils.cpp
new file mode 100644
index 0000000000..c2183c5bf5
--- /dev/null
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftActivityUtils.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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
+
+namespace AWSGameLift
+{
+ namespace AWSGameLiftActivityUtils
+ {
+ void GetGameProperties(
+ const AZStd::unordered_map& sessionProperties,
+ Aws::Vector& outGameProperties,
+ AZStd::string& outGamePropertiesOutput)
+ {
+ for (auto iter = sessionProperties.begin(); iter != sessionProperties.end(); iter++)
+ {
+ Aws::GameLift::Model::GameProperty sessionProperty;
+ sessionProperty.SetKey(iter->first.c_str());
+ sessionProperty.SetValue(iter->second.c_str());
+ outGameProperties.push_back(sessionProperty);
+ outGamePropertiesOutput += AZStd::string::format("{Key=%s,Value=%s},", iter->first.c_str(), iter->second.c_str());
+ }
+ if (!outGamePropertiesOutput.empty())
+ {
+ outGamePropertiesOutput =
+ outGamePropertiesOutput.substr(0, outGamePropertiesOutput.size() - 1); // Trim last comma to fit array format
+ }
+ }
+ } // namespace AWSGameLiftActivityUtils
+} // namespace AWSGameLift
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftActivityUtils.h b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftActivityUtils.h
new file mode 100644
index 0000000000..37adb808dc
--- /dev/null
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftActivityUtils.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace AWSGameLift
+{
+ namespace AWSGameLiftActivityUtils
+ {
+ void GetGameProperties(
+ const AZStd::unordered_map& sessionProperties,
+ Aws::Vector& outGameProperties,
+ AZStd::string& outGamePropertiesOutput);
+ } // namespace AWSGameLiftActivityUtils
+} // namespace AWSGameLift
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionActivity.cpp b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionActivity.cpp
index fdd429e0bb..5846b4be4d 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionActivity.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionActivity.cpp
@@ -5,6 +5,7 @@
*
*/
+#include
#include
#include
@@ -29,13 +30,12 @@ namespace AWSGameLift
{
request.SetIdempotencyToken(createSessionRequest.m_idempotencyToken.c_str());
}
- for (auto iter = createSessionRequest.m_sessionProperties.begin();
- iter != createSessionRequest.m_sessionProperties.end(); iter++)
+ AZStd::string propertiesOutput = "";
+ Aws::Vector properties;
+ AWSGameLiftActivityUtils::GetGameProperties(createSessionRequest.m_sessionProperties, properties, propertiesOutput);
+ if (!properties.empty())
{
- Aws::GameLift::Model::GameProperty sessionProperty;
- sessionProperty.SetKey(iter->first.c_str());
- sessionProperty.SetValue(iter->second.c_str());
- request.AddGameProperties(sessionProperty);
+ request.SetGameProperties(properties);
}
// Required attributes
@@ -49,6 +49,16 @@ namespace AWSGameLift
}
request.SetMaximumPlayerSessionCount(createSessionRequest.m_maxPlayer);
+ AZ_TracePrintf(AWSGameLiftCreateSessionActivityName,
+ "Built CreateGameSessionRequest with CreatorId=%s, Name=%s, IdempotencyToken=%s, GameProperties=%s, AliasId=%s, FleetId=%s and MaximumPlayerSessionCount=%d",
+ request.GetCreatorId().c_str(),
+ request.GetName().c_str(),
+ request.GetIdempotencyToken().c_str(),
+ AZStd::string::format("[%s]", propertiesOutput.c_str()).c_str(),
+ request.GetAliasId().c_str(),
+ request.GetFleetId().c_str(),
+ request.GetMaximumPlayerSessionCount());
+
return request;
}
@@ -61,6 +71,7 @@ namespace AWSGameLift
AZStd::string result = "";
Aws::GameLift::Model::CreateGameSessionRequest request = BuildAWSGameLiftCreateGameSessionRequest(createSessionRequest);
auto createSessionOutcome = gameliftClient.CreateGameSession(request);
+ AZ_TracePrintf(AWSGameLiftCreateSessionActivityName, "CreateGameSession request against Amazon GameLift service is complete");
if (createSessionOutcome.IsSuccess())
{
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionOnQueueActivity.cpp b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionOnQueueActivity.cpp
index d4124cf726..bbaba97a6c 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionOnQueueActivity.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftCreateSessionOnQueueActivity.cpp
@@ -6,6 +6,7 @@
*/
#include
+#include
#include
namespace AWSGameLift
@@ -21,13 +22,12 @@ namespace AWSGameLift
{
request.SetGameSessionName(createSessionOnQueueRequest.m_sessionName.c_str());
}
- for (auto iter = createSessionOnQueueRequest.m_sessionProperties.begin();
- iter != createSessionOnQueueRequest.m_sessionProperties.end(); iter++)
+ AZStd::string propertiesOutput = "";
+ Aws::Vector properties;
+ AWSGameLiftActivityUtils::GetGameProperties(createSessionOnQueueRequest.m_sessionProperties, properties, propertiesOutput);
+ if (!properties.empty())
{
- Aws::GameLift::Model::GameProperty sessionProperty;
- sessionProperty.SetKey(iter->first.c_str());
- sessionProperty.SetValue(iter->second.c_str());
- request.AddGameProperties(sessionProperty);
+ request.SetGameProperties(properties);
}
// Required attributes
@@ -35,6 +35,14 @@ namespace AWSGameLift
request.SetMaximumPlayerSessionCount(createSessionOnQueueRequest.m_maxPlayer);
request.SetPlacementId(createSessionOnQueueRequest.m_placementId.c_str());
+ AZ_TracePrintf(AWSGameLiftCreateSessionOnQueueActivityName,
+ "Built StartGameSessionPlacementRequest with GameSessionName=%s, GameProperties=%s, GameSessionQueueName=%s, MaximumPlayerSessionCount=%d and PlacementId=%s",
+ request.GetGameSessionName().c_str(),
+ AZStd::string::format("[%s]", propertiesOutput.c_str()).c_str(),
+ request.GetGameSessionQueueName().c_str(),
+ request.GetMaximumPlayerSessionCount(),
+ request.GetPlacementId().c_str());
+
return request;
}
@@ -49,6 +57,8 @@ namespace AWSGameLift
Aws::GameLift::Model::StartGameSessionPlacementRequest request =
BuildAWSGameLiftStartGameSessionPlacementRequest(createSessionOnQueueRequest);
auto createSessionOnQueueOutcome = gameliftClient.StartGameSessionPlacement(request);
+ AZ_TracePrintf(AWSGameLiftCreateSessionOnQueueActivityName,
+ "StartGameSessionPlacement request against Amazon GameLift service is complete.");
if (createSessionOnQueueOutcome.IsSuccess())
{
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftJoinSessionActivity.cpp b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftJoinSessionActivity.cpp
index d02691967d..9920bc4f61 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftJoinSessionActivity.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftJoinSessionActivity.cpp
@@ -27,6 +27,13 @@ namespace AWSGameLift
// Required attributes
request.SetPlayerId(joinSessionRequest.m_playerId.c_str());
request.SetGameSessionId(joinSessionRequest.m_sessionId.c_str());
+
+ AZ_TracePrintf(AWSGameLiftJoinSessionActivityName,
+ "Built CreatePlayerSessionRequest with PlayerData=%s, PlayerId=%s and GameSessionId=%s",
+ request.GetPlayerData().c_str(),
+ request.GetPlayerId().c_str(),
+ request.GetGameSessionId().c_str());
+
return request;
}
@@ -40,6 +47,13 @@ namespace AWSGameLift
sessionConnectionConfig.m_ipAddress = createPlayerSessionResult.GetPlayerSession().GetIpAddress().c_str();
sessionConnectionConfig.m_playerSessionId = createPlayerSessionResult.GetPlayerSession().GetPlayerSessionId().c_str();
sessionConnectionConfig.m_port = createPlayerSessionResult.GetPlayerSession().GetPort();
+
+ AZ_TracePrintf(AWSGameLiftJoinSessionActivityName,
+ "Built SessionConnectionConfig with IpAddress=%s, PlayerSessionId=%s and Port=%d",
+ sessionConnectionConfig.m_ipAddress.c_str(),
+ sessionConnectionConfig.m_playerSessionId.c_str(),
+ sessionConnectionConfig.m_port);
+
return sessionConnectionConfig;
}
@@ -54,6 +68,8 @@ namespace AWSGameLift
Aws::GameLift::Model::CreatePlayerSessionRequest request =
BuildAWSGameLiftCreatePlayerSessionRequest(joinSessionRequest);
auto createPlayerSessionOutcome = gameliftClient.CreatePlayerSession(request);
+ AZ_TracePrintf(AWSGameLiftJoinSessionActivityName,
+ "CreatePlayerSession request for player %s against Amazon GameLift service is complete", joinSessionRequest.m_playerId.c_str());
if (!createPlayerSessionOutcome.IsSuccess())
{
@@ -72,11 +88,13 @@ namespace AWSGameLift
auto clientRequestHandler = AZ::Interface::Get();
if (clientRequestHandler)
{
- AZ_TracePrintf(AWSGameLiftJoinSessionActivityName, "Requesting player to connect to game session ...");
-
AzFramework::SessionConnectionConfig sessionConnectionConfig =
BuildSessionConnectionConfig(createPlayerSessionOutcome);
+
+ AZ_TracePrintf(AWSGameLiftJoinSessionActivityName,
+ "Requesting and validating player session %s to connect to game session ...", sessionConnectionConfig.m_playerSessionId.c_str());
result = clientRequestHandler->RequestPlayerJoinSession(sessionConnectionConfig);
+ AZ_TracePrintf(AWSGameLiftJoinSessionActivityName, "Started connection process, and connection validation is in process.");
}
else
{
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftLeaveSessionActivity.cpp b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftLeaveSessionActivity.cpp
index 241f2ac120..024faae1c4 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftLeaveSessionActivity.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftLeaveSessionActivity.cpp
@@ -19,9 +19,9 @@ namespace AWSGameLift
auto clientRequestHandler = AZ::Interface::Get();
if (clientRequestHandler)
{
- AZ_TracePrintf(AWSGameLiftLeaveSessionActivityName, "Requesting to leave the current session...");
-
+ AZ_TracePrintf(AWSGameLiftLeaveSessionActivityName, "Requesting player to leave the current session ...");
clientRequestHandler->RequestPlayerLeaveSession();
+ AZ_TracePrintf(AWSGameLiftLeaveSessionActivityName, "Started disconnect process, and player clean up is in process.");
}
else
{
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftSearchSessionsActivity.cpp b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftSearchSessionsActivity.cpp
index b1b01e66f1..aa5f0e14d9 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftSearchSessionsActivity.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/Activity/AWSGameLiftSearchSessionsActivity.cpp
@@ -35,6 +35,7 @@ namespace AWSGameLift
{
request.SetNextToken(searchSessionsRequest.m_nextToken.c_str());
}
+
// Required attributes
if (!searchSessionsRequest.m_aliasId.empty())
{
@@ -46,6 +47,16 @@ namespace AWSGameLift
}
// TODO: Update the AWS Native SDK to accept the new request parameter.
//request.SetLocation(searchSessionsRequest.m_location.c_str());
+
+ AZ_TracePrintf(AWSGameLiftSearchSessionsActivityName,
+ "Built SearchGameSessionsRequest with FilterExpression=%s, SortExpression=%s, Limit=%d, NextToken=%s, AliasId=%s and FleetId=%s",
+ request.GetFilterExpression().c_str(),
+ request.GetSortExpression().c_str(),
+ request.GetLimit(),
+ request.GetNextToken().c_str(),
+ request.GetAliasId().c_str(),
+ request.GetFleetId().c_str());
+
return request;
}
@@ -58,6 +69,7 @@ namespace AWSGameLift
AzFramework::SearchSessionsResponse response;
Aws::GameLift::Model::SearchGameSessionsRequest request = BuildAWSGameLiftSearchGameSessionsRequest(searchSessionsRequest);
Aws::GameLift::Model::SearchGameSessionsOutcome outcome = gameliftClient.SearchGameSessions(request);
+ AZ_TracePrintf(AWSGameLiftSearchSessionsActivityName, "SearchGameSessions request against Amazon GameLift service is complete");
if (outcome.IsSuccess())
{
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/awsgamelift_client_files.cmake b/Gems/AWSGameLift/Code/AWSGameLiftClient/awsgamelift_client_files.cmake
index ce6c017e8e..5bce8387a4 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftClient/awsgamelift_client_files.cmake
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/awsgamelift_client_files.cmake
@@ -11,6 +11,8 @@ set(FILES
Include/Request/AWSGameLiftJoinSessionRequest.h
Include/Request/AWSGameLiftSearchSessionsRequest.h
Include/Request/IAWSGameLiftRequests.h
+ Source/Activity/AWSGameLiftActivityUtils.cpp
+ Source/Activity/AWSGameLiftActivityUtils.h
Source/Activity/AWSGameLiftCreateSessionActivity.cpp
Source/Activity/AWSGameLiftCreateSessionActivity.h
Source/Activity/AWSGameLiftCreateSessionOnQueueActivity.cpp
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerManager.cpp b/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerManager.cpp
index 3b2fd910bf..72f120d7dc 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerManager.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerManager.cpp
@@ -106,8 +106,10 @@ namespace AWSGameLift
return false;
}
- AZ_TracePrintf(AWSGameLiftServerManagerName, "Initiating Amazon GameLift Server SDK...");
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "Initiating Amazon GameLift Server SDK ...");
Aws::GameLift::Server::InitSDKOutcome initOutcome = m_gameLiftServerSDKWrapper->InitSDK();
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "InitSDK request against Amazon GameLift service is complete.");
+
m_serverSDKInitialized = initOutcome.IsSuccess();
AZ_Error(AWSGameLiftServerManagerName, m_serverSDKInitialized,
@@ -138,8 +140,10 @@ namespace AWSGameLift
return;
}
- AZ_TracePrintf(AWSGameLiftServerManagerName, "Notifying GameLift server process is ending...");
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "Notifying GameLift server process is ending ...");
Aws::GameLift::GenericOutcome processEndingOutcome = m_gameLiftServerSDKWrapper->ProcessEnding();
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "ProcessEnding request against Amazon GameLift service is complete.");
+
bool processEndingIsSuccess = processEndingOutcome.IsSuccess();
AZ_Error(AWSGameLiftServerManagerName, processEndingIsSuccess, AWSGameLiftServerProcessEndingErrorMessage,
@@ -155,7 +159,12 @@ namespace AWSGameLift
return;
}
+ AZ_TracePrintf(AWSGameLiftServerManagerName,
+ "Removing player session %s from Amazon GameLift service ...", playerSessionId.c_str());
Aws::GameLift::GenericOutcome disconnectOutcome = m_gameLiftServerSDKWrapper->RemovePlayerSession(playerSessionId);
+ AZ_TracePrintf(AWSGameLiftServerManagerName,
+ "RemovePlayerSession request for player session %s against Amazon GameLift service is complete.", playerSessionId.c_str());
+
AZ_Error(AWSGameLiftServerManagerName, disconnectOutcome.IsSuccess(), AWSGameLiftServerRemovePlayerSessionErrorMessage,
playerSessionId.c_str(), disconnectOutcome.GetError().GetErrorMessage().c_str());
}
@@ -188,8 +197,9 @@ namespace AWSGameLift
AZStd::bind(&AWSGameLiftServerManager::OnHealthCheck, this), desc.m_port,
Aws::GameLift::Server::LogParameters(logPaths));
- AZ_TracePrintf(AWSGameLiftServerManagerName, "Notifying GameLift server process is ready...");
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "Notifying GameLift server process is ready ...");
auto processReadyOutcome = m_gameLiftServerSDKWrapper->ProcessReady(processReadyParameter);
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "ProcessReady request against Amazon GameLift service is complete.");
if (!processReadyOutcome.IsSuccess())
{
@@ -213,8 +223,9 @@ namespace AWSGameLift
if (createSessionResult)
{
- AZ_TracePrintf(AWSGameLiftServerManagerName, "Activating GameLift game session...");
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "Activating GameLift game session ...");
Aws::GameLift::GenericOutcome activationOutcome = m_gameLiftServerSDKWrapper->ActivateGameSession();
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "ActivateGameSession request against Amazon GameLift service is complete.");
if (activationOutcome.IsSuccess())
{
@@ -240,7 +251,7 @@ namespace AWSGameLift
void AWSGameLiftServerManager::OnProcessTerminate()
{
- AZ_TracePrintf(AWSGameLiftServerManagerName, "GameLift is shutting down server process...");
+ AZ_TracePrintf(AWSGameLiftServerManagerName, "GameLift is shutting down server process ...");
HandleDestroySession();
}
@@ -299,8 +310,11 @@ namespace AWSGameLift
return false;
}
- AZ_TracePrintf(AWSGameLiftServerManagerName, "Attempting to accept player session connection with Amazon GameLift service...");
+ AZ_TracePrintf(AWSGameLiftServerManagerName,
+ "Attempting to accept player session %s connection with Amazon GameLift service ...", playerSessionId.c_str());
auto acceptPlayerSessionOutcome = m_gameLiftServerSDKWrapper->AcceptPlayerSession(playerSessionId.c_str());
+ AZ_TracePrintf(AWSGameLiftServerManagerName,
+ "AcceptPlayerSession request for player session %s against Amazon GameLift service is complete.", playerSessionId.c_str());
if (!acceptPlayerSessionOutcome.IsSuccess())
{
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli
index 292f8a8a22..6e45cf30c8 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ltc.azsli
@@ -80,14 +80,44 @@ float3x3 BuildViewAlignedOrthonormalBasis(in float3 normal, in float3 dirToView)
// xy plane in positive z space.
float IntegrateEdge(float3 v1, float3 v2)
{
+ // This alternate version may work better for platforms where acos() precision is low.
+ /*
+ float x = dot(v1, v2);
+ float y = abs(x);
+
+ float a = 5.42031 + (3.12829 + 0.0902326 * y) * y;
+ float b = 3.45068 + (4.18814 + y) * y;
+ float theta_sinTheta = a / b;
+
+ if (x < 0.0)
+ {
+ theta_sinTheta = PI * rsqrt(saturate(1.0 - x * x)) - theta_sinTheta;
+ }
+
+ float3 u = cross(v1, v2);
+ return theta_sinTheta * u.z;
+ */
+
float cosTheta = dot(v1, v2);
- cosTheta = clamp(cosTheta, -0.9999, 0.9999);
+ float theta = acos(cosTheta);
// calculate 1.0 / sin(theta)
- float invSinTheta = rsqrt(1.0 - cosTheta * cosTheta);
+ float invSinTheta = rsqrt(saturate(1.0 - cosTheta * cosTheta));
- float theta = acos(cosTheta);
- return cross(v1, v2).z * theta * invSinTheta;
+ return cross(v1, v2).z * ((theta > 0.001) ? theta * invSinTheta : 1.0);
+}
+
+// Cheaper version of above which is good enough for diffuse
+float IntegrateEdgeDiffuse(float3 v1, float3 v2)
+{
+ float cosTheta = dot(v1, v2);
+ float absCosTheta = abs(cosTheta);
+ float theta_sinTheta = 1.5708 + (-0.879406 + 0.308609 * absCosTheta) * absCosTheta;
+ if (cosTheta < 0.0)
+ {
+ theta_sinTheta = PI * rsqrt(1.0 - cosTheta * cosTheta) - theta_sinTheta;
+ }
+ return theta_sinTheta * cross(v1, v2).z;
}
// Returns the unnormalized z plane intersection point between pointAboveHorizon and pointBelowHorizon.
@@ -189,42 +219,90 @@ void ClipQuadToHorizon(inout float3 p[5], out int vertexCount)
}
}
-// Takes 4 points (p) from a quad plus a 5th dummy point, rotates them into the space of the normal, then transforms
-// the points by the LTC matrix provided. The points are then clipped to the normal's hemisphere. The number of points
-// after the clip is returned in vertexCount. It's possible for the resulting clipped quad to be a triangle (when 3
-// points are below the horizon), or a pentagon (when one point is below the horizon), or be a regular 4 point quad.
-void LtcClipAndNormalizeQuad(in float3 normal, in float3 dirToView, float3x3 ltcMat, inout float3 p[5], out int vertexCount)
+// Applies the LTC matrix to the clipped points of a quad.
+void ApplyLtcMatrixToQuad(in float3x3 ltcMat, inout float3 p[5], in int vertexCount)
{
- // Rotate ltc matrix
- ltcMat = mul(ltcMat, BuildViewAlignedOrthonormalBasis(normal, dirToView));
-
// Transform points into ltc space
- p[0] = mul(ltcMat, p[0].xyz);
- p[1] = mul(ltcMat, p[1].xyz);
- p[2] = mul(ltcMat, p[2].xyz);
- p[3] = mul(ltcMat, p[3].xyz);
+ p[0] = mul(ltcMat, p[0]);
+ p[1] = mul(ltcMat, p[1]);
+ p[2] = mul(ltcMat, p[2]);
- ClipQuadToHorizon(p, vertexCount);
-
- // visibility check
- if (vertexCount == 0)
+ if (vertexCount > 3)
{
- return;
+ p[3] = mul(ltcMat, p[3]);
}
+ if (vertexCount > 4)
+ {
+ p[4] = mul(ltcMat, p[4]);
+ }
+}
- // project onto sphere
+// Projects the clipped points of a quad onto the sphere.
+void NormalizeQuadPoints(inout float3 p[5], in int vertexCount)
+{
+ // project quad points onto a sphere.
p[0] = normalize(p[0]);
p[1] = normalize(p[1]);
p[2] = normalize(p[2]);
- p[3] = normalize(p[3]);
- p[4] = normalize(p[4]);
+
+ if (vertexCount > 3)
+ {
+ p[3] = normalize(p[3]);
+ }
+ if (vertexCount > 4)
+ {
+ p[4] = normalize(p[4]);
+ }
}
-float IntegrateQuad(in float3 v[5], in float vertexCount, in bool doubleSided)
+// Transforms the 4 points of a quad into the hemisphere of the normal
+void TransformQuadToOrthonormalBasis(in float3 normal, in float3 dirToView, inout float3 p[4])
+{
+ float3x3 orthoNormalBasis = BuildViewAlignedOrthonormalBasis(normal, dirToView);
+
+ // Transform points into orthonormal space
+ p[0] = mul(orthoNormalBasis, p[0]);
+ p[1] = mul(orthoNormalBasis, p[1]);
+ p[2] = mul(orthoNormalBasis, p[2]);
+ p[3] = mul(orthoNormalBasis, p[3]);
+}
+
+// Integrates the edges of a quad for lambertian diffuse contribution.
+float IntegrateQuadDiffuse(in float3 v[5], in float vertexCount, in bool doubleSided)
{
- // Integrate
float sum = 0.0;
+ NormalizeQuadPoints(v, vertexCount);
+
+ // There must be at least 3 points so don't check for the first 2 edges.
+ sum += IntegrateEdgeDiffuse(v[0], v[1]);
+ sum += IntegrateEdgeDiffuse(v[1], v[2]);
+
+ if (vertexCount > 3)
+ {
+ sum += IntegrateEdgeDiffuse(v[2], v[3]);
+ if (vertexCount == 5)
+ {
+ sum += IntegrateEdgeDiffuse(v[3], v[4]);
+ }
+ }
+
+ // Close the polygon
+ sum += IntegrateEdgeDiffuse(v[vertexCount - 1], v[0]);
+
+ // Note: negated due to winding order
+ sum = doubleSided ? abs(sum) : max(0.0, -sum);
+
+ return sum;
+}
+
+// Integrates the edges of a quad for specular contribution.
+float IntegrateQuadSpecular(in float3 v[5], in float vertexCount, in bool doubleSided)
+{
+ float sum = 0.0;
+
+ NormalizeQuadPoints(v, vertexCount);
+
// There must be at least 3 points so don't check for the first 2 edges.
sum += IntegrateEdge(v[0], v[1]);
sum += IntegrateEdge(v[1], v[2]);
@@ -247,26 +325,62 @@ float IntegrateQuad(in float3 v[5], in float vertexCount, in bool doubleSided)
return sum;
}
-float LtcQuadEvaluate(in float3 normal, in float3 dirToView, in float3x3 ltcMat, in float3 p[4], in bool doubleSided)
+// Evaluate linear transform cosine lighting for a 4 point quad.
+// normal - The surface normal
+// dirToView - Normalized direction from the surface to the view
+// ltcMat - The LTC matrix for specular, or identity for diffuse.
+// p[4] - The 4 light positions relative to the surface position.
+// doubleSided - If the quad emits light from both sides
+// diffuse - The output diffuse response for the quad light
+// specular - The output specular response for the quad light
+void LtcQuadEvaluate(
+ in float3 normal,
+ in float3 dirToView,
+ in float3x3 ltcMat,
+ in float3 p[4],
+ in bool doubleSided,
+ out float diffuse,
+ out float specular)
{
+ // Transform the points of the light into the space of the normal's hemisphere.
+ TransformQuadToOrthonormalBasis(normal, dirToView, p);
+
// Initialize quad with dummy point at end in case one corner is clipped (resulting in 5 sided polygon)
float3 v[5] = {p[0], p[1], p[2], p[3], float3(0.0, 0.0, 0.0)};
- int vertexCount = 0;
- LtcClipAndNormalizeQuad(normal, dirToView, ltcMat, v, vertexCount);
+ // Clip the light polygon to the normal hemisphere. This is done before the LTC matrix is applied to prevent
+ // parts of the light below the horizon from impacting the surface. The number of points remaining after
+ // the clip is returned in vertexCount. It's possible for the vertexCount of the resulting clipped quad to be
+ // 0 - all points clipped (no work to do, so return)
+ // 3 - 3 points clipped, leaving only a triangular corner of the quad
+ // 4 - 2 or 0 points clipped, leaving a quad
+ // 5 - 1 point clipped leaving a pentagon.
- if (vertexCount > 0)
+ int vertexCount = 0;
+ ClipQuadToHorizon(v, vertexCount);
+
+ if (vertexCount == 0)
{
- return IntegrateQuad(v, vertexCount, doubleSided);
+ // Entire light is below the horizon.
+ return;
}
- return 0.0;
+
+ // IntegrateQuadDiffuse is a cheap approximation compared to specular.
+ diffuse = IntegrateQuadDiffuse(v, vertexCount, doubleSided);
+
+ ApplyLtcMatrixToQuad(ltcMat, v, vertexCount);
+
+ // IntegrateQuadSpecular uses more accurate integration to handle smooth surfaces correctly.
+ specular = IntegrateQuadSpecular(v, vertexCount, doubleSided);
}
// Checks an edge against the horizon and integrates it.
-// p0 - first point
-// p1 - second point
-// prevClipPoint - the clip point saved from the last time an edge went from above to below the horizon
-// sum - the sum total of all integrations to contribute to.
+// p0 - First point
+// p1 - Second point
+// prevClipPoint - The clip point saved from the last time an edge went from above to below the horizon
+// ltcMat - The ltc lookup matrix for specular
+// diffuse - The current sum total of diffuse contribution to apply additional contribution to
+// specular - The current sum total of specular contribution to apply additional contribution to
//
// Explanation:
// When evaluating edges of a polygon there are four possible states to deal with
@@ -283,28 +397,34 @@ float LtcQuadEvaluate(in float3 normal, in float3 dirToView, in float3x3 ltcMat,
// 4. Both points are below the horizon
// - Do nothing.
-void EvaluatePolyEdge(in float3 p0, in float3 p1, inout float3 prevClipPoint, inout float sum)
+void EvaluatePolyEdge(in float3 p0, in float3 p1, inout float3 prevClipPoint, in float3x3 ltcMat, inout float diffuse, inout float specular)
{
if (p0.z > 0.0)
{
if (p1.z > 0.0)
{
// Both above horizon
- sum += IntegrateEdge(normalize(p0), normalize(p1));
+ diffuse += IntegrateEdgeDiffuse(normalize(p0), normalize(p1));
+ specular += IntegrateEdge(normalize(mul(ltcMat, p0)), normalize(mul(ltcMat, p1)));
}
else
{
// Going from above to below horizon
- prevClipPoint = normalize(ClipEdge(p0, p1));
- sum += IntegrateEdge(normalize(p0), prevClipPoint);
+ prevClipPoint = ClipEdge(p0, p1);
+ diffuse += IntegrateEdgeDiffuse(normalize(p0), normalize(prevClipPoint));
+ specular += IntegrateEdge(normalize(mul(ltcMat, p0)), normalize(mul(ltcMat, prevClipPoint)));
}
}
else if (p1.z > 0.0)
{
// Going from below to above horizon
- float3 clipPoint = normalize(ClipEdge(p1, p0));
- sum += IntegrateEdge(prevClipPoint, clipPoint);
- sum += IntegrateEdge(clipPoint, normalize(p1));
+ float3 clipPoint = ClipEdge(p1, p0);
+ diffuse += IntegrateEdgeDiffuse(normalize(prevClipPoint), normalize(clipPoint));
+ diffuse += IntegrateEdgeDiffuse(normalize(clipPoint), normalize(p1));
+
+ clipPoint = mul(ltcMat, clipPoint);
+ specular += IntegrateEdge(normalize(mul(ltcMat, prevClipPoint)), normalize(clipPoint));
+ specular += IntegrateEdge(normalize(clipPoint), normalize(mul(ltcMat, p1)));
}
}
@@ -316,26 +436,38 @@ void EvaluatePolyEdge(in float3 p0, in float3 p1, inout float3 prevClipPoint, in
// positions - The buffer where the polygon positions are
// startIdx - The index of the first polygon position
// endIdx - The index of the point directly after the last polygon position
-//
+// diffuse - The output diffuse response for the polygon light
+// specular - The output specular response for the polygon light
// The most complicated aspect of this function is clipping the polygon against the horizon of the surface point. See
// EvaluatePolyEdge() above for details on the general concept. However, this function must deal with the case of the
// first point being below the horizon. In that case, it needs to search in reverse from the end for the first point
// above the horizon, and save the intersection point between the above and below points so it can be used in
// EvaluatePolyEdge() later. During this search it also adjusts the end point index as necessary to avoid processing
// those points that are below the horizon.
-float LtcPolygonEvaluate(in float3 pos, in float3 normal, in float3 dirToView, in float3x3 ltcMat, in StructuredBuffer positions, in uint startIdx, in uint endIdx)
+void LtcPolygonEvaluate(
+ in float3 pos,
+ in float3 normal,
+ in float3 dirToView,
+ in float3x3 ltcMat,
+ in StructuredBuffer positions,
+ in uint startIdx,
+ in uint endIdx,
+ out float diffuse,
+ out float specular
+)
{
if (endIdx - startIdx < 3)
{
- return 0.0; // Must have at least 3 points to form a polygon.
+ return; // Must have at least 3 points to form a polygon.
}
// Rotate ltc matrix
- ltcMat = mul(ltcMat, BuildViewAlignedOrthonormalBasis(normal, dirToView));
+ float3x3 orthonormalMat = BuildViewAlignedOrthonormalBasis(normal, dirToView);
// Prepare initial values
- float sum = 0.0; // sum of edge integation
- float3 p0 = mul(ltcMat, positions[startIdx].xyz - pos); // First point in polygon
+ float3 p0 = mul(orthonormalMat, positions[startIdx].xyz - pos); // First point in polygon
+ diffuse = 0.0;
+ specular = 0.0;
float3 prevClipPoint = float3(0.0, 0.0, 0.0); // Used to hold previous clip point when polygon dips below horizon.
float3 closePoint = p0;
@@ -349,10 +481,10 @@ float LtcPolygonEvaluate(in float3 pos, in float3 normal, in float3 dirToView, i
// searching backwards, updating the endIdx along the way to avoid reprocessing those points later
for ( ; endIdx > startIdx + 1; --endIdx)
{
- float3 prevPoint = mul(ltcMat, positions[endIdx - 1].xyz - pos);
- if (prevPoint.z > 0)
+ float3 prevPoint = mul(orthonormalMat, positions[endIdx - 1].xyz - pos);
+ if (prevPoint.z > 0.0)
{
- prevClipPoint = normalize(ClipEdge(prevPoint, p0));
+ prevClipPoint = ClipEdge(prevPoint, p0);
closePoint = prevClipPoint;
break;
}
@@ -362,7 +494,7 @@ float LtcPolygonEvaluate(in float3 pos, in float3 normal, in float3 dirToView, i
// Check if all points below horizon
if (endIdx == startIdx + 1)
{
- return 0.0;
+ return;
}
p0 = firstPoint; // Restore the original p0
@@ -371,13 +503,14 @@ float LtcPolygonEvaluate(in float3 pos, in float3 normal, in float3 dirToView, i
// Evaluate all the points
for (uint curIdx = startIdx + 1; curIdx < endIdx; ++curIdx)
{
- float3 p1 = mul(ltcMat, positions[curIdx].xyz - pos); // Current point in polygon
- EvaluatePolyEdge(p0, p1, prevClipPoint, sum);
+ float3 p1 = mul(orthonormalMat, positions[curIdx].xyz - pos); // Current point in polygon
+ EvaluatePolyEdge(p0, p1, prevClipPoint, ltcMat, diffuse, specular);
p0 = p1;
}
- EvaluatePolyEdge(p0, closePoint, prevClipPoint, sum);
+ EvaluatePolyEdge(p0, closePoint, prevClipPoint, ltcMat, diffuse, specular);
// Note: negated due to winding order
- return -sum;
+ diffuse = -diffuse;
+ specular = -specular;
}
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli
index bbd3c1c9e3..d7313556a2 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/PolygonLight.azsli
@@ -50,26 +50,25 @@ void ApplyPoylgonLight(ViewSrg::PolygonLight light, Surface surface, inout Light
float radiusAttenuation = 1.0 - (falloff * falloff);
radiusAttenuation = radiusAttenuation * radiusAttenuation;
- // Diffuse
- static const float3x3 identityMatrix = float3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
- float diffuse = LtcPolygonEvaluate(surface.position, surface.normal, lightingData.dirToCamera, identityMatrix, ViewSrg::m_polygonLightPoints, startIndex, endIndex);
- diffuse = doubleSided ? abs(diffuse) : max(0.0, diffuse);
-
- // Specular
float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear);
float3x3 ltcMat = LtcMatrix(SceneSrg::m_ltcMatrix, ltcCoords);
- float3 specular = LtcPolygonEvaluate(surface.position, surface.normal, lightingData.dirToCamera, ltcMat, ViewSrg::m_polygonLightPoints, startIndex, endIndex);
+
+ float diffuse = 0.0;
+ float specular = 0.0;
+
+ LtcPolygonEvaluate(surface.position, surface.normal, lightingData.dirToCamera, ltcMat, ViewSrg::m_polygonLightPoints, startIndex, endIndex, diffuse, specular);
+ diffuse = doubleSided ? abs(diffuse) : max(0.0, diffuse);
specular = doubleSided ? abs(specular) : max(0.0, specular);
// Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel)
float2 schlick = SceneSrg::m_ltcAmplification.Sample(PassSrg::LinearSampler, ltcCoords).xy;
- specular *= schlick.x + (1.0 - surface.specularF0) * schlick.y;
+ float3 specularRGB = specular * (schlick.x + (1.0 - surface.specularF0) * schlick.y);
// Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity
float3 intensity = 0.5 * INV_PI * radiusAttenuation * abs(light.m_rgbIntensityNits);
lightingData.diffuseLighting += surface.albedo * diffuse * intensity;
- lightingData.specularLighting += surface.specularF0 * specular * intensity;
+ lightingData.specularLighting += surface.specularF0 * specularRGB * intensity;
}
void ApplyPolygonLights(Surface surface, inout LightingData lightingData)
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli
index 91981e4f4d..29ee97fd6f 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/QuadLight.azsli
@@ -111,24 +111,22 @@ void ApplyQuadLight(ViewSrg::QuadLight light, Surface surface, inout LightingDat
{
float3 p[4] = {p0, p1, p2, p3};
- // Diffuse
- float3x3 identityMatrix = float3x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
- float diffuse = LtcQuadEvaluate(surface.normal, lightingData.dirToCamera, identityMatrix, p, doubleSided);
-
- // Specular
float2 ltcCoords = LtcCoords(dot(surface.normal, lightingData.dirToCamera), surface.roughnessLinear);
float3x3 ltcMat = LtcMatrix(SceneSrg::m_ltcMatrix, ltcCoords);
- float3 specular = LtcQuadEvaluate(surface.normal, lightingData.dirToCamera, ltcMat, p, doubleSided);
+
+ float diffuse = 0.0;
+ float specular = 0.0;
+ LtcQuadEvaluate(surface.normal, lightingData.dirToCamera, ltcMat, p, doubleSided, diffuse, specular);
// Apply BRDF scale terms (BRDF magnitude and Schlick Fresnel)
float2 schlick = SceneSrg::m_ltcAmplification.Sample(PassSrg::LinearSampler, ltcCoords).xy;
- specular *= schlick.x + (1.0 - surface.specularF0) * schlick.y;
+ float3 specularRGB = specular * (schlick.x + (1.0 - surface.specularF0) * schlick.y);
// Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity
float3 intensity = 0.5 * INV_PI * radiusAttenuation * light.m_rgbIntensityNits;
lightingData.diffuseLighting += surface.albedo * diffuse * intensity;
- lightingData.specularLighting += surface.specularF0 * specular * intensity;
+ lightingData.specularLighting += surface.specularF0 * specularRGB * intensity;
}
else
{
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/FrameCaptureBus.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/FrameCaptureBus.h
index e783a03071..53e7de9148 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/FrameCaptureBus.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/FrameCaptureBus.h
@@ -46,14 +46,16 @@ namespace AZ
//! Save a buffer attachment or a image attachment binded to a pass's slot to a data file.
//! @param passHierarchy For finding the pass by using PassHierarchyFilter
//! @param slotName Name of the pass's slot. The attachment bound to this slot will be captured.
+ //! @param option Only valid for an InputOutput attachment. Use PassAttachmentReadbackOption::Input to capture the input state
+ //! and use PassAttachmentReadbackOption::Output to capture the output state
//! @param outputFilename The output file path.
virtual bool CapturePassAttachment(const AZStd::vector& passHierarchy, const AZStd::string& slotName
- , const AZStd::string& outputFilePath) = 0;
+ , const AZStd::string& outputFilePath, RPI::PassAttachmentReadbackOption option) = 0;
//! Similar to CapturePassAttachment. But instead of saving the read back result to a file, it will call the callback function provide
//! in the input when callback is finished
virtual bool CapturePassAttachmentWithCallback(const AZStd::vector& passHierarchy, const AZStd::string& slotName
- , RPI::AttachmentReadback::CallbackFunction callback) = 0;
+ , RPI::AttachmentReadback::CallbackFunction callback, RPI::PassAttachmentReadbackOption option) = 0;
};
using FrameCaptureRequestBus = EBus;
diff --git a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp
index a115bfa6e8..e8e4609ec4 100644
--- a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp
@@ -343,7 +343,7 @@ namespace AZ
}
bool FrameCaptureSystemComponent::CapturePassAttachment(const AZStd::vector& passHierarchy, const AZStd::string& slot,
- const AZStd::string& outputFilePath)
+ const AZStd::string& outputFilePath, RPI::PassAttachmentReadbackOption option)
{
InitReadback();
@@ -376,40 +376,22 @@ namespace AZ
return false;
}
- AZ::RPI::RenderPass* renderPass = azrtti_cast(foundPasses[0]);
- if (renderPass)
+ AZ::RPI::Pass* pass = foundPasses[0];
+ if (pass->ReadbackAttachment(m_readback, Name(slot), option))
{
- Name slotName = Name(slot);
- AZ::RPI::PassAttachment* attachment = nullptr;
- for (auto& binding : renderPass->GetAttachmentBindings())
- {
- if (binding.m_name == slotName)
- {
- attachment = binding.m_attachment.get();
- break;
- }
- }
- if (attachment)
- {
- m_state = State::Pending;
- m_result = FrameCaptureResult::None;
- SystemTickBus::Handler::BusConnect();
- renderPass->ReadbackAttachment(m_readback, attachment);
- }
- else
- {
- AZ_Warning("FrameCaptureSystemComponent", false, "Failed to find attachment bound to pass [%s] slot [%s]",
- renderPass->GetName().GetCStr(), slotName.GetCStr());
- return false;
- }
+ m_state = State::Pending;
+ m_result = FrameCaptureResult::None;
+ SystemTickBus::Handler::BusConnect();
+ return true;
}
- return true;
+ AZ_Warning("FrameCaptureSystemComponent", false, "Failed to readback the attachment bound to pass [%s] slot [%s]", pass->GetName().GetCStr(), slot.c_str());
+ return false;
}
bool FrameCaptureSystemComponent::CapturePassAttachmentWithCallback(const AZStd::vector& passHierarchy, const AZStd::string& slotName
- , RPI::AttachmentReadback::CallbackFunction callback)
+ , RPI::AttachmentReadback::CallbackFunction callback, RPI::PassAttachmentReadbackOption option)
{
- bool result = CapturePassAttachment(passHierarchy, slotName, "");
+ bool result = CapturePassAttachment(passHierarchy, slotName, "", option);
// Append state change to user provided call back
AZ::RPI::AttachmentReadback::CallbackFunction callbackSetState = [&, callback](const AZ::RPI::AttachmentReadback::ReadbackResult& result)
diff --git a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.h b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.h
index 472dd5da74..eb08494699 100644
--- a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.h
+++ b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.h
@@ -36,9 +36,10 @@ namespace AZ
bool CaptureScreenshot(const AZStd::string& filePath) override;
bool CaptureScreenshotForWindow(const AZStd::string& filePath, AzFramework::NativeWindowHandle windowHandle) override;
bool CaptureScreenshotWithPreview(const AZStd::string& outputFilePath) override;
- bool CapturePassAttachment(const AZStd::vector& passHierarchy, const AZStd::string& slotName, const AZStd::string& outputFilePath) override;
+ bool CapturePassAttachment(const AZStd::vector& passHierarchy, const AZStd::string& slotName, const AZStd::string& outputFilePath,
+ RPI::PassAttachmentReadbackOption option) override;
bool CapturePassAttachmentWithCallback(const AZStd::vector& passHierarchy, const AZStd::string& slotName
- , RPI::AttachmentReadback::CallbackFunction callback) override;
+ , RPI::AttachmentReadback::CallbackFunction callback, RPI::PassAttachmentReadbackOption option) override;
private:
void CaptureAttachmentCallback(const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult);
diff --git a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp
index 5faaba136e..63437ebbad 100644
--- a/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/LuxCore/LuxCoreTexturePass.cpp
@@ -64,23 +64,9 @@ namespace AZ
// Set up read back attachment before children prepare
if (m_readback->IsReady())
{
- AZ::RPI::RenderPass* renderPass = azrtti_cast(m_renderTargetPass.get());
- if (renderPass)
+ if (m_renderTargetPass)
{
- RPI::PassAttachment* attachment = nullptr;
- for (auto& binding : renderPass->GetAttachmentBindings())
- {
- if (binding.m_slotType == RPI::PassSlotType::Output)
- {
- attachment = binding.m_attachment.get();
- break;
- }
- }
- if (attachment)
- {
- renderPass->ReadbackAttachment(m_readback, attachment);
- m_attachmentReadbackComplete = true;
- }
+ m_attachmentReadbackComplete = m_renderTargetPass->ReadbackAttachment(m_readback, AZ::Name("RenderTargetOutput"));
}
}
}
diff --git a/Gems/Atom/RHI/Code/Source/RHI/RayTracingPipelineState.cpp b/Gems/Atom/RHI/Code/Source/RHI/RayTracingPipelineState.cpp
index 5e5932456e..480c11b7c9 100644
--- a/Gems/Atom/RHI/Code/Source/RHI/RayTracingPipelineState.cpp
+++ b/Gems/Atom/RHI/Code/Source/RHI/RayTracingPipelineState.cpp
@@ -142,6 +142,8 @@ namespace AZ
void RayTracingPipelineState::Shutdown()
{
+ ShutdownInternal();
+ DeviceObject::Shutdown();
}
}
}
diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp
index 36560868af..52aabdec1d 100644
--- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp
+++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp
@@ -261,7 +261,7 @@ namespace AZ
VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME
} };
- uint32_t optionalExtensionCount = sizeof(optionalExtensions) / sizeof(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME);
+ [[maybe_unused]] uint32_t optionalExtensionCount = sizeof(optionalExtensions) / sizeof(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME);
AZ_Assert(optionalExtensionCount == static_cast(OptionalDeviceExtension::Count), "The order and size must match the enum OptionalDeviceExtensions.");
diff --git a/Gems/Atom/RPI/Code/CMakeLists.txt b/Gems/Atom/RPI/Code/CMakeLists.txt
index 71e5d82e48..d806b8c687 100644
--- a/Gems/Atom/RPI/Code/CMakeLists.txt
+++ b/Gems/Atom/RPI/Code/CMakeLists.txt
@@ -25,6 +25,8 @@ ly_add_target(
../Assets/atom_rpi_asset_files.cmake
${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
${MASKED_OCCLUSION_CULLING_FILES}
+ PLATFORM_INCLUDE_FILES
+ ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common/${PAL_TRAIT_COMPILER_ID}/atom_rpi_public_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PRIVATE
Source
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h
index c6667e660a..736252a8a2 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h
@@ -57,6 +57,7 @@ namespace AZ
class PassTemplate;
struct PassRequest;
struct PassValidationResults;
+ class AttachmentReadback;
using SortedPipelineViewTags = AZStd::set;
using PassesByDrawList = AZStd::map;
@@ -65,7 +66,12 @@ namespace AZ
const uint32_t PassInputBindingCountMax = 16;
const uint32_t PassInputOutputBindingCountMax = PassInputBindingCountMax;
const uint32_t PassOutputBindingCountMax = PassInputBindingCountMax;
-
+
+ enum class PassAttachmentReadbackOption : uint8_t
+ {
+ Input = 0,
+ Output
+ };
//! Atom's base pass class (every pass class in Atom must derive from this class).
//!
@@ -222,6 +228,14 @@ namespace AZ
//! Enables/Disables PipelineStatistics queries for this pass
virtual void SetPipelineStatisticsQueryEnabled(bool enable);
+ //! Readback an attachment attached to the specified slot name
+ //! @param readback The AttachmentReadback object which is used for readback. Its callback function will be called when readback is finished.
+ //! @param slotName The attachment bind to the slot with this slotName is to be readback
+ //! @param option The option is used for choosing input or output state when readback an InputOutput attachment.
+ //! It's ignored if the attachment isn't an InputOutput attachment.
+ //! Return true if the readback request was successful. User may expect the AttachmentReadback's callback function would be called.
+ bool ReadbackAttachment(AZStd::shared_ptr readback, const Name& slotName, PassAttachmentReadbackOption option = PassAttachmentReadbackOption::Output);
+
//! Returns whether the Timestamp queries is enabled/disabled for this pass
bool IsTimestampQueryEnabled() const;
@@ -266,7 +280,6 @@ namespace AZ
// Update output bindings on this pass that are connected to bindings on other passes
void UpdateConnectedOutputBindings();
-
protected:
explicit Pass(const PassDescriptor& descriptor);
@@ -349,6 +362,7 @@ namespace AZ
void FrameEnd();
virtual void FrameEndInternal() { }
+ void UpdateReadbackAttachment(FramePrepareParams params, bool beforeAddScopes);
// --- Protected Members ---
@@ -442,7 +456,10 @@ namespace AZ
// Sort type to be used by the default sort implementation. Passes can also provide
// fully custom sort implementations by overriding the SortDrawList() function.
RHI::DrawListSortType m_drawListSortType = RHI::DrawListSortType::KeyThenDepth;
-
+
+ // For read back attachment
+ AZStd::shared_ptr m_attachmentReadback;
+ PassAttachmentReadbackOption m_readbackOption;
private:
// Return the Timestamp result of this pass
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h
index b13091082b..3d4ab0a573 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/RenderPass.h
@@ -55,10 +55,7 @@ namespace AZ
//! Get MultisampleState of this pass from its output attachments
RHI::MultisampleState GetMultisampleState() const;
-
- //! Capture pass's output and input/output attachments in following frames
- void ReadbackAttachment(AZStd::shared_ptr readback, const PassAttachment* attachment);
-
+
//! Returns a pointer to the Pass ShaderResourceGroup
Data::Instance GetShaderResourceGroup();
@@ -145,9 +142,6 @@ namespace AZ
// Readback the results from the ScopeQueries
void ReadbackScopeQueryResults();
- // For read back attachments
- AZStd::shared_ptr m_attachmentReadback;
-
AZStd::weak_ptr m_attachmentCopy;
// Readback results from the Timestamp queries
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.h
index f855154975..fac9abfe28 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.h
@@ -166,9 +166,6 @@ namespace AZ
AZ::Vector2 m_position = AZ::Vector2(0, 0.6f);
AZ::Vector2 m_size = AZ::Vector2(0.4f, 0.4f);
bool m_keepAspectRatio = true;
-
- // For readback the output image attachment
- AZStd::shared_ptr m_readback;
};
} // namespace RPI
} // namespace AZ
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h
index 0a689f2f74..f96fe92610 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/RenderToTexturePass.h
@@ -60,9 +60,6 @@ namespace AZ
// Name of the template used to create the child pass. Needed for Recreate()
Name m_childTemplateName;
- // For read back output
- AZStd::shared_ptr m_readback;
-
Ptr m_outputAttachment;
// saved settings for this pass
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h
index 6b9559e824..9d1376c840 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SelectorPass.h
@@ -15,7 +15,6 @@
#include
#include
-#include
#include
#include
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h
index e7869d463c..e8aeddf7e7 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/SwapChainPass.h
@@ -15,7 +15,6 @@
#include
#include
-#include
#include
#include
@@ -88,9 +87,6 @@ namespace AZ
// Name of the template used to create the child pass. Needed for Recreate()
Name m_childTemplateName;
-
- // For read back swap chain
- AZStd::shared_ptr m_swapChainReadback;
};
} // namespace RPI
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContext.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContext.h
index 982ef498a0..92e50be75e 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContext.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContext.h
@@ -65,9 +65,15 @@ namespace AZ
ConstViewPtr GetDefaultView() const;
//! Gets the current size of the viewport.
+ //! This value is cached and updated on-demand, so may be efficiently queried.
AzFramework::WindowSize GetViewportSize() const;
- // SceneNotificationBus interface
+ //! Gets the screen DPI scaling factor.
+ //! This value is cached and updated on-demand, so may be efficiently queried.
+ //! \see AzFramework::WindowRequests::GetDpiScaleFactor
+ float GetDpiScalingFactor() const;
+
+ // SceneNotificationBus interface overrides...
//! Ensures our default view remains set when our scene's render pipelines are modified.
void OnRenderPipelineAdded(RenderPipelinePtr pipeline) override;
//! Ensures our default view remains set when our scene's render pipelines are modified.
@@ -75,15 +81,22 @@ namespace AZ
//! OnBeginPrepareRender is forwarded to our RenderTick notification to allow subscribers to do rendering.
void OnBeginPrepareRender() override;
- //WindowNotificationBus interface
- //! Used to fire a notification when our window resizes
+ // WindowNotificationBus interface overrides...
+ //! Used to fire a notification when our window resizes.
void OnWindowResized(uint32_t width, uint32_t height) override;
+ //! Used to fire a notification when our window DPI changes.
+ void OnDpiScaleFactorChanged(float dpiScaleFactor) override;
using SizeChangedEvent = AZ::Event;
//! Notifies consumers when the viewport size has changed.
//! Alternatively, connect to ViewportContextNotificationsBus and listen to ViewportContextNotifications::OnViewportSizeChanged.
void ConnectSizeChangedHandler(SizeChangedEvent::Handler& handler);
+ using ScalarChangedEvent = AZ::Event;
+ //! Notifies consumers when the viewport DPI scaling ratio has changed.
+ //! Alternatively, connect to ViewportContextNotificationsBus and listen to ViewportContextNotifications::OnViewportDpiScalingChanged.
+ void ConnectDpiScalingFactorChangedHandler(ScalarChangedEvent::Handler& handler);
+
using MatrixChangedEvent = AZ::Event;
//! Notifies consumers when the view matrix has changed.
void ConnectViewMatrixChangedHandler(MatrixChangedEvent::Handler& handler);
@@ -106,7 +119,7 @@ namespace AZ
//! Notifies consumers when this ViewportContext is about to be destroyed.
void ConnectAboutToBeDestroyedHandler(ViewportIdEvent::Handler& handler);
- // ViewportRequestBus interface
+ // ViewportRequestBus interface overrides...
//! Gets the current camera's view matrix.
const AZ::Matrix4x4& GetCameraViewMatrix() const override;
//! Sets the current camera's view matrix.
@@ -130,8 +143,10 @@ namespace AZ
WindowContextSharedPtr m_windowContext;
ViewPtr m_defaultView;
AzFramework::WindowSize m_viewportSize;
+ float m_viewportDpiScaleFactor = 1.0f;
SizeChangedEvent m_sizeChangedEvent;
+ ScalarChangedEvent m_dpiScalingFactorChangedEvent;
MatrixChangedEvent m_viewMatrixChangedEvent;
MatrixChangedEvent::Handler m_onViewMatrixChangedHandler;
MatrixChangedEvent m_projectionMatrixChangedEvent;
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h
index da0c850f3d..152c8cf2c1 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h
@@ -105,8 +105,10 @@ namespace AZ
class ViewportContextNotifications
{
public:
- //! Called when the underlying native window size changes for a given viewport context name.
+ //! Called when the underlying native window size changes for a given viewport context.
virtual void OnViewportSizeChanged(AzFramework::WindowSize size){AZ_UNUSED(size);}
+ //! Called when the window DPI scaling changes for a given viewport context.
+ virtual void OnViewportDpiScalingChanged(float dpiScale){AZ_UNUSED(dpiScale);}
//! Called when the active view for a given viewport context name changes.
virtual void OnViewportDefaultViewChanged(AZ::RPI::ViewPtr view){AZ_UNUSED(view);}
//! Called when the viewport is to be rendered.
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextManager.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextManager.h
index 008565d178..e50525cff0 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextManager.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextManager.h
@@ -51,6 +51,7 @@ namespace AZ
{
AZStd::weak_ptr context;
ViewportContext::SizeChangedEvent::Handler sizeChangedHandler;
+ ViewportContext::ScalarChangedEvent::Handler dpiScalingChangedHandler;
};
// ViewportContextManager is a singleton owned solely by RPISystem, which is tagged as a friend
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelKdTree.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelKdTree.h
index cd3f1968bf..fc915bcd07 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelKdTree.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelKdTree.h
@@ -67,7 +67,8 @@ namespace AZ
void ConstructMeshList(const ModelAsset* model, const AZ::Transform& matParent);
static const int s_MinimumVertexSizeInLeafNode = 3 * 10;
-
+ // Stop splitting the tree if more than 10% of the triangles are straddling the split axis
+ static constexpr float s_MaximumSplitAxisStraddlingTriangles = 1.1;
AZStd::unique_ptr m_pRootNode;
struct MeshData
diff --git a/Gems/Atom/RPI/Code/Source/Platform/Common/Clang/atom_rpi_public_clang.cmake b/Gems/Atom/RPI/Code/Source/Platform/Common/Clang/atom_rpi_public_clang.cmake
new file mode 100644
index 0000000000..88309e590c
--- /dev/null
+++ b/Gems/Atom/RPI/Code/Source/Platform/Common/Clang/atom_rpi_public_clang.cmake
@@ -0,0 +1,18 @@
+#
+# 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
+#
+#
+
+ly_add_source_properties(
+ SOURCES External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX2.cpp
+ PROPERTY COMPILE_OPTIONS
+ VALUES -mavx2 -mfma -msse4.1
+)
+
+ly_add_source_properties(
+ SOURCES External/MaskedOcclusionCulling/MaskedOcclusionCulling.cpp
+ PROPERTY COMPILE_OPTIONS
+ VALUES -mno-avx
+)
diff --git a/Gems/Atom/RPI/Code/Source/Platform/Common/MSVC/atom_rpi_public_msvc.cmake b/Gems/Atom/RPI/Code/Source/Platform/Common/MSVC/atom_rpi_public_msvc.cmake
new file mode 100644
index 0000000000..50cfc8a179
--- /dev/null
+++ b/Gems/Atom/RPI/Code/Source/Platform/Common/MSVC/atom_rpi_public_msvc.cmake
@@ -0,0 +1,19 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+ly_add_source_properties(
+ SOURCES External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX2.cpp
+ PROPERTY COMPILE_OPTIONS
+ VALUES /arch:AVX2 /W3
+)
+ly_add_source_properties(
+ SOURCES
+ External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX512.cpp
+ External/MaskedOcclusionCulling/MaskedOcclusionCulling.cpp
+ PROPERTY COMPILE_OPTIONS
+ VALUES /W3
+)
diff --git a/Gems/Atom/RPI/Code/Source/Platform/Windows/PAL_windows.cmake b/Gems/Atom/RPI/Code/Source/Platform/Windows/PAL_windows.cmake
index 896f505d05..a9e3cf10f9 100644
--- a/Gems/Atom/RPI/Code/Source/Platform/Windows/PAL_windows.cmake
+++ b/Gems/Atom/RPI/Code/Source/Platform/Windows/PAL_windows.cmake
@@ -7,16 +7,3 @@
set (PAL_TRAIT_BUILD_ATOM_RPI_ASSETS_SUPPORTED TRUE)
set (PAL_TRAIT_BUILD_ATOM_RPI_MASKED_OCCLUSION_CULLING_SUPPORTED TRUE)
-
-ly_add_source_properties(
- SOURCES External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX2.cpp
- PROPERTY COMPILE_OPTIONS
- VALUES /arch:AVX2 /W3
-)
-ly_add_source_properties(
- SOURCES
- External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX512.cpp
- External/MaskedOcclusionCulling/MaskedOcclusionCulling.cpp
- PROPERTY COMPILE_OPTIONS
- VALUES /W3
-)
\ No newline at end of file
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp
index 9d3a776b80..dfe470c3f8 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -36,8 +37,7 @@
namespace AZ
{
namespace RPI
- {
-
+ {
// --- Constructors ---
Pass::Pass(const PassDescriptor& descriptor)
@@ -1285,9 +1285,15 @@ namespace AZ
CreateTransientAttachments(params.m_frameGraphBuilder->GetAttachmentDatabase());
ImportAttachments(params.m_frameGraphBuilder->GetAttachmentDatabase());
+ // readback attachment with input state
+ UpdateReadbackAttachment(params, true);
+
// FrameBeginInternal needs to be the last function be called in FrameBegin because its implementation expects
// all the attachments are imported to database (for example, ImageAttachmentPreview)
FrameBeginInternal(params);
+
+ // readback attachment with output state
+ UpdateReadbackAttachment(params, false);
UpdateConnectedOutputBindings();
}
@@ -1426,6 +1432,57 @@ namespace AZ
m_flags.m_pipelineStatisticsQueryEnabled = enable;
}
+ bool Pass::ReadbackAttachment(AZStd::shared_ptr readback, const Name& slotName, PassAttachmentReadbackOption option)
+ {
+ // Return false if it's already readback
+ if (m_attachmentReadback)
+ {
+ AZ_Warning("Pass", false, "ReadbackAttachment: skip readback pass [%s] slot [%s]because there is an another active readback", m_name.GetCStr(), slotName.GetCStr());
+ return false;
+ }
+ uint32_t bindingIndex = 0;
+ for (auto& binding : m_attachmentBindings)
+ {
+ if (slotName == binding.m_name)
+ {
+ RHI::AttachmentType type = binding.m_attachment->GetAttachmentType();
+ if (type == RHI::AttachmentType::Buffer || type == RHI::AttachmentType::Image)
+ {
+ RHI::AttachmentId attachmentId = binding.m_attachment->GetAttachmentId();
+
+ // Append slot index and pass name so the read back's name won't be same as the attachment used in other passes.
+ AZStd::string readbackName = AZStd::string::format("%s_%d_%s", attachmentId.GetCStr(),
+ bindingIndex, GetName().GetCStr());
+ if (readback->ReadPassAttachment(binding.m_attachment.get(), AZ::Name(readbackName)))
+ {
+ m_readbackOption = PassAttachmentReadbackOption::Output;
+ // The m_readbackOption is only meaningful if the attachment is used for InputOutput.
+ if (binding.m_slotType == PassSlotType::InputOutput)
+ {
+ m_readbackOption = option;
+ }
+ m_attachmentReadback = readback;
+ return true;
+ }
+ return false;
+ }
+ }
+ bindingIndex++;
+ }
+ AZ_Warning("Pass", false, "ReadbackAttachment: failed to find slot [%s] from pass [%s]", slotName.GetCStr(), m_name.GetCStr());
+ return false;
+ }
+
+ void Pass::UpdateReadbackAttachment(FramePrepareParams params, bool beforeAddScopes)
+ {
+ if (beforeAddScopes == (m_readbackOption == PassAttachmentReadbackOption::Input) && m_attachmentReadback)
+ {
+ // Read the attachment for one frame. The reference can be released afterwards
+ m_attachmentReadback->FrameBegin(params);
+ m_attachmentReadback = nullptr;
+ }
+ }
+
bool Pass::IsTimestampQueryEnabled() const
{
return m_flags.m_timestampQueryEnabled;
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
index f82d4bd9ef..96649573b2 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
@@ -189,14 +189,8 @@ namespace AZ
{
SetScopeId(RHI::ScopeId(GetPathName()));
}
- params.m_frameGraphBuilder->ImportScopeProducer(*this);
- // Read the attachment for one frame. The reference can be released afterwards
- if (m_attachmentReadback)
- {
- m_attachmentReadback->FrameBegin(params);
- m_attachmentReadback = nullptr;
- }
+ params.m_frameGraphBuilder->ImportScopeProducer(*this);
// Read back the ScopeQueries submitted from previous frames
ReadbackScopeQueryResults();
@@ -415,31 +409,6 @@ namespace AZ
m_flags.m_hasPipelineViewTag = !viewTag.IsEmpty();
}
- void RenderPass::ReadbackAttachment(AZStd::shared_ptr readback, const PassAttachment* attachment)
- {
- m_attachmentReadback = readback;
-
- uint32_t bindingIndex = 0;
- for (auto& binding : m_attachmentBindings)
- {
- if (attachment == binding.m_attachment)
- {
- RHI::AttachmentType type = binding.m_attachment->GetAttachmentType();
- if (type == RHI::AttachmentType::Buffer || type == RHI::AttachmentType::Image)
- {
- RHI::AttachmentId attachmentId = binding.m_attachment->GetAttachmentId();
-
- // Append slot index and pass name so the read back's name won't be same as the attachment used in other passes.
- AZStd::string readbackName = AZStd::string::format("%s_%d_%s", attachmentId.GetCStr(),
- bindingIndex, GetName().GetCStr());
- m_attachmentReadback->ReadPassAttachment(binding.m_attachment.get(), AZ::Name(readbackName));
- return;
- }
- }
- bindingIndex++;
- }
- }
-
TimestampResult RenderPass::GetTimestampResultInternal() const
{
return m_timestampResult;
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp
index 0241d6ec25..5ee2c0a440 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/ImageAttachmentPreviewPass.cpp
@@ -333,22 +333,16 @@ namespace AZ
m_passSrg->Compile();
m_passSrgChanged = false;
}
-
- // Read preview output
- if (m_readback)
- {
- m_readback->FrameBegin(params);
- m_readback = nullptr;
- }
}
bool ImageAttachmentPreviewPass::ReadbackOutput(AZStd::shared_ptr readback)
{
if (m_outputColorAttachment)
{
- m_readback = readback;
+ m_readbackOption = PassAttachmentReadbackOption::Output;
+ m_attachmentReadback = readback;
AZStd::string readbackName = AZStd::string::format("%s_%s", m_outputColorAttachment->GetAttachmentId().GetCStr(), GetName().GetCStr());
- return m_readback->ReadPassAttachment(m_outputColorAttachment.get(), AZ::Name(readbackName));
+ return m_attachmentReadback->ReadPassAttachment(m_outputColorAttachment.get(), AZ::Name(readbackName));
}
return false;
}
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp
index 8b4c9b8aab..c532a1324f 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/RenderToTexturePass.cpp
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
#include
#include
@@ -77,17 +78,6 @@ namespace AZ
params.m_viewportState = m_viewport;
Base::FrameBeginInternal(params);
-
- // for read back output
- if (m_readback)
- {
- m_readback->FrameBegin(params);
- if (m_readback->IsFinished())
- {
- // Done reading. Remove the reference
- m_readback = nullptr;
- }
- }
}
void RenderToTexturePass::ResizeOutput(uint32_t width, uint32_t height)
@@ -118,9 +108,10 @@ namespace AZ
{
if (m_outputAttachment)
{
- m_readback = readback;
+ m_readbackOption = PassAttachmentReadbackOption::Output;
+ m_attachmentReadback = readback;
AZStd::string readbackName = AZStd::string::format("%s_%s", m_outputAttachment->GetAttachmentId().GetCStr(), GetName().GetCStr());
- m_readback->ReadPassAttachment(m_outputAttachment.get(), AZ::Name(readbackName));
+ m_attachmentReadback->ReadPassAttachment(m_outputAttachment.get(), AZ::Name(readbackName));
}
}
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp
index 7a3bf3a011..62649cd0b2 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/SwapChainPass.cpp
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
#include
#include
@@ -134,13 +135,6 @@ namespace AZ
attachmentDatabase.ImportSwapChain(m_windowContext->GetSwapChainAttachmentId(), m_windowContext->GetSwapChain());
ParentPass::FrameBeginInternal(params);
-
- // Read swap chain for one frame. The reference can be released afterwards
- if (m_swapChainReadback)
- {
- m_swapChainReadback->FrameBegin(params);
- m_swapChainReadback = nullptr;
- }
}
void SwapChainPass::OnWindowResized([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
@@ -152,9 +146,11 @@ namespace AZ
{
if (m_swapChainAttachment)
{
- m_swapChainReadback = readback;
+ m_readbackOption = PassAttachmentReadbackOption::Output;
+ m_attachmentReadback = readback;
+
AZStd::string readbackName = AZStd::string::format("%s_%s", m_swapChainAttachment->GetAttachmentId().GetCStr(), GetName().GetCStr());
- m_swapChainReadback->ReadPassAttachment(m_swapChainAttachment.get(), AZ::Name(readbackName));
+ m_attachmentReadback->ReadPassAttachment(m_swapChainAttachment.get(), AZ::Name(readbackName));
}
}
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp
index 23d5805c12..eacdbe0293 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp
@@ -28,6 +28,10 @@ namespace AZ
m_viewportSize,
nativeWindow,
&AzFramework::WindowRequestBus::Events::GetClientAreaSize);
+ AzFramework::WindowRequestBus::EventResult(
+ m_viewportDpiScaleFactor,
+ nativeWindow,
+ &AzFramework::WindowRequestBus::Events::GetDpiScaleFactor);
AzFramework::WindowNotificationBus::Handler::BusConnect(nativeWindow);
AzFramework::ViewportRequestBus::Handler::BusConnect(id);
@@ -148,11 +152,21 @@ namespace AZ
return m_viewportSize;
}
+ float ViewportContext::GetDpiScalingFactor() const
+ {
+ return m_viewportDpiScaleFactor;
+ }
+
void ViewportContext::ConnectSizeChangedHandler(SizeChangedEvent::Handler& handler)
{
handler.Connect(m_sizeChangedEvent);
}
+ void ViewportContext::ConnectDpiScalingFactorChangedHandler(ScalarChangedEvent::Handler& handler)
+ {
+ handler.Connect(m_dpiScalingFactorChangedEvent);
+ }
+
void ViewportContext::ConnectViewMatrixChangedHandler(MatrixChangedEvent::Handler& handler)
{
handler.Connect(m_viewMatrixChangedEvent);
@@ -289,5 +303,11 @@ namespace AZ
m_sizeChangedEvent.Signal(m_viewportSize);
}
}
+
+ void ViewportContext::OnDpiScaleFactorChanged(float dpiScaleFactor)
+ {
+ m_viewportDpiScaleFactor = dpiScaleFactor;
+ m_dpiScalingFactorChangedEvent.Signal(dpiScaleFactor);
+ }
} // namespace RPI
} // namespace AZ
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContextManager.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContextManager.cpp
index 552304557f..606b5e5b8c 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContextManager.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContextManager.cpp
@@ -55,16 +55,28 @@ namespace AZ
auto onSizeChanged = [this, viewportId](AzFramework::WindowSize size)
{
// Ensure we emit OnViewportSizeChanged with the correct name.
- auto viewportContext = this->GetViewportContextById(viewportId);
+ auto viewportContext = GetViewportContextById(viewportId);
if (viewportContext)
{
ViewportContextNotificationBus::Event(viewportContext->GetName(), &ViewportContextNotificationBus::Events::OnViewportSizeChanged, size);
}
ViewportContextIdNotificationBus::Event(viewportId, &ViewportContextIdNotificationBus::Events::OnViewportSizeChanged, size);
};
+ auto onDpiScalingChanged = [this, viewportId](float dpiScalingFactor)
+ {
+ // Ensure we emit OnViewportDpiScalingChanged with the correct name.
+ auto viewportContext = GetViewportContextById(viewportId);
+ if (viewportContext)
+ {
+ ViewportContextNotificationBus::Event(viewportContext->GetName(), &ViewportContextNotificationBus::Events::OnViewportDpiScalingChanged, dpiScalingFactor);
+ }
+ ViewportContextIdNotificationBus::Event(viewportId, &ViewportContextIdNotificationBus::Events::OnViewportDpiScalingChanged, dpiScalingFactor);
+ };
viewportContext->m_name = contextName;
viewportData.sizeChangedHandler = ViewportContext::SizeChangedEvent::Handler(onSizeChanged);
+ viewportData.dpiScalingChangedHandler = ViewportContext::ScalarChangedEvent::Handler(onDpiScalingChanged);
viewportContext->ConnectSizeChangedHandler(viewportData.sizeChangedHandler);
+ viewportContext->ConnectDpiScalingFactorChangedHandler(viewportData.dpiScalingChangedHandler);
ViewPtrStack& associatedViews = GetOrCreateViewStackForContext(contextName);
viewportContext->SetDefaultView(associatedViews.back());
onSizeChanged(viewportContext->GetViewportSize());
@@ -176,6 +188,7 @@ namespace AZ
UpdateViewForContext(newContextName);
// Ensure anyone listening on per-name viewport size updates gets notified.
ViewportContextNotificationBus::Event(newContextName, &ViewportContextNotificationBus::Events::OnViewportSizeChanged, viewportContext->GetViewportSize());
+ ViewportContextNotificationBus::Event(newContextName, &ViewportContextNotificationBus::Events::OnViewportDpiScalingChanged, viewportContext->GetDpiScalingFactor());
}
void ViewportContextManager::EnumerateViewportContexts(AZStd::function visitorFunction)
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp
index 54ec002893..ace4df5c0b 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelKdTree.cpp
@@ -84,7 +84,11 @@ namespace AZ
// If either the top or bottom contain all the input indices, the triangles are too close to cut any
// further and the split failed
- return indices.size() != outInfo.m_aboveIndices.size() && indices.size() != outInfo.m_belowIndices.size();
+ // Additionally, if too many triangles straddle the split-axis,
+ // the triangles are too close and the split failed
+ // [ATOM-15944] - Use a more sophisticated method to terminate KdTree generation
+ return indices.size() != outInfo.m_aboveIndices.size() && indices.size() != outInfo.m_belowIndices.size()
+ && aznumeric_cast(outInfo.m_aboveIndices.size() + outInfo.m_belowIndices.size()) / aznumeric_cast(indices.size()) < s_MaximumSplitAxisStraddlingTriangles;
}
bool ModelKdTree::Build(const ModelAsset* model)
diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
index 50378c15bd..d8171a83a1 100644
--- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
+++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
@@ -120,6 +120,7 @@ namespace AtomToolsFramework
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
+ float GetDpiScaleFactor() const override;
protected:
// AzFramework::InputChannelEventListener ...
diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
index 9fcd93f069..6ab96bbebb 100644
--- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
+++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
@@ -491,4 +491,9 @@ namespace AtomToolsFramework
{
// The RenderViewportWidget does not currently support full screen.
}
+
+ float RenderViewportWidget::GetDpiScaleFactor() const
+ {
+ return aznumeric_cast(devicePixelRatioF());
+ }
} //namespace AtomToolsFramework
diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl
index daeb797c42..e349685fd3 100644
--- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl
+++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl
@@ -25,17 +25,15 @@ namespace AZ
{
// NOTE: Fix build error in case AZStd::thread_id is not of an arithmetic type, and instead a pointer
template::value>::type* = nullptr>
- void TextThreadId(ThreadId threadId)
+ AZStd::string TextThreadId(ThreadId threadId)
{
- const AZStd::string threadIdText = AZStd::string::format("Thread: %p", threadId);
- ImGui::Text(threadIdText.c_str());
+ return AZStd::string::format("Thread: %p", threadId);
}
template::value>::type* = nullptr>
- void TextThreadId(ThreadId threadId)
+ AZStd::string TextThreadId(ThreadId threadId)
{
- const AZStd::string threadIdText = AZStd::string::format("Thread: %zu", static_cast(threadId));
- ImGui::Text(threadIdText.c_str());
+ return AZStd::string::format("Thread: %zu", static_cast(threadId));
}
inline float TicksToMs(AZStd::sys_time_t ticks)
{
@@ -108,7 +106,7 @@ namespace AZ
for (ThreadRegionEntry& entry : entries)
{
- CpuProfilerImGuiHelper::TextThreadId(entry.m_threadId.m_id);
+ ImGui::Text(CpuProfilerImGuiHelper::TextThreadId(entry.m_threadId.m_id).c_str());
const AZStd::sys_time_t elapsed = entry.m_endTick - entry.m_startTick;
ShowTimeInMs(elapsed);
@@ -610,7 +608,7 @@ namespace AZ
{
auto [wx, wy] = ImGui::GetWindowPos();
wy -= ImGui::GetScrollY();
- const AZStd::string threadIdText = AZStd::string::format("Thread %zu", static_cast(threadId.m_id));
+ const AZStd::string threadIdText = CpuProfilerImGuiHelper::TextThreadId(threadId.m_id);
ImGui::GetWindowDrawList()->AddText({ wx + 10, wy + baseRow * RowHeight + 5 }, IM_COL32_WHITE, threadIdText.c_str());
}
diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.h b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.h
index e735852926..d907e7e7eb 100644
--- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.h
+++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.h
@@ -32,11 +32,14 @@ namespace AZ
void ReadbackCallback(const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult);
+ void DrawPassAttachments(AZ::RPI::Pass* pass);
+
bool m_previewAttachment = false;
bool m_showAttachments = false;
AZ::RPI::Pass* m_selectedPass = nullptr;
AZ::RHI::AttachmentId m_attachmentId;
+ AZ::Name m_slotName;
bool m_selectedChanged = false;
AZStd::shared_ptr m_readback;
diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.inl
index cd53131933..d31674754e 100644
--- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.inl
+++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiPassTree.inl
@@ -76,6 +76,7 @@ namespace AZ::Render
{
m_selectedChanged = true;
m_attachmentId = AZ::RHI::AttachmentId{};
+ m_slotName = AZ::Name{};
}
}
@@ -88,13 +89,12 @@ namespace AZ::Render
m_readback->SetCallback(AZStd::bind(&ImGuiPassTree::ReadbackCallback, this, AZStd::placeholders::_1));
}
- if (m_selectedPass && !m_attachmentId.IsEmpty())
+ if (m_selectedPass && !m_slotName.IsEmpty())
{
- AZ::RPI::RenderPass* renderPass = azrtti_cast(m_selectedPass);
- if (renderPass)
+ bool readbackResult = m_selectedPass->ReadbackAttachment(m_readback, m_slotName);
+ if (!readbackResult)
{
- AZ::RPI::PassAttachment* attachment = FindPassAttachment(renderPass, m_attachmentId);
- renderPass->ReadbackAttachment(m_readback, attachment);
+ AZ_Error("ImGuiPassTree", false, "Failed to readback attachment from pass [%s] slot [%s]", m_selectedPass->GetName().GetCStr(), m_slotName.GetCStr());
}
}
}
@@ -144,6 +144,77 @@ namespace AZ::Render
}
ImGui::End();
}
+
+ inline void ImGuiPassTree::DrawPassAttachments(AZ::RPI::Pass* pass)
+ {
+ for (const auto& binding : pass->GetAttachmentBindings())
+ {
+ // Binding info: [slot type] [slot name]
+ AZStd::string label = AZStd::string::format("[%s] [%s]", AZ::RPI::ToString(binding.m_slotType),
+ binding.m_name.GetCStr());
+
+ // Append attachment info if the attachment exists
+ if (binding.m_attachment)
+ {
+ AZ::RHI::AttachmentType type = binding.m_attachment->GetAttachmentType();
+
+ // Append attachment info: [attachment type] attachment name
+ label += AZStd::string::format(" [%s] %s",
+ AZ::RHI::ToString(type),
+ binding.m_attachment->m_name.GetCStr());
+
+ if (type == AZ::RHI::AttachmentType::Image)
+ {
+ // Append image info: [format] [size] [msaa]
+ AZ::RHI::ImageDescriptor descriptor;
+ if (binding.m_attachment->m_importedResource)
+ {
+ AZ::RPI::Image* image = static_cast(binding.m_attachment->m_importedResource.get());
+ descriptor = image->GetRHIImage()->GetDescriptor();
+ }
+ else
+ {
+ descriptor = binding.m_attachment->m_descriptor.m_image;
+ }
+ auto format = descriptor.m_format;
+ auto size = descriptor.m_size;
+ label += AZStd::string::format(" [%s] [%dx%d]", AZ::RHI::ToString(format), size.m_width, size.m_height);
+
+ if (descriptor.m_multisampleState.m_samples > 1)
+ {
+ if (descriptor.m_multisampleState.m_customPositionsCount > 0)
+ {
+ label += AZStd::string::format(" [MSAA_Custom_%dx]", descriptor.m_multisampleState.m_samples);
+ }
+ else
+ {
+ label += AZStd::string::format(" [MSAA_%dx]", descriptor.m_multisampleState.m_samples);
+ }
+ }
+ }
+ else if (type == AZ::RHI::AttachmentType::Buffer)
+ {
+ // Append buffer info: [size]
+ auto size = binding.m_attachment->m_descriptor.m_buffer.m_byteCount;
+ label += AZStd::string::format(" [%llu]", size);
+ }
+
+ if (Scriptable_ImGui::Selectable(label.c_str(), m_attachmentId == binding.m_attachment->GetAttachmentId()))
+ {
+ m_selectedPass = pass;
+ m_attachmentId = binding.m_attachment->GetAttachmentId();
+ m_slotName = binding.m_name;
+ m_selectedChanged = true;
+ }
+ }
+ else
+ {
+ // Only draw text (not selectable) if there is no attachment binded to the slot.
+ ImGui::Text(label.c_str());
+ }
+ }
+
+ }
inline void ImGuiPassTree::DrawTreeView(AZ::RPI::Pass* pass)
{
@@ -164,6 +235,7 @@ namespace AZ::Render
{
m_selectedPass = pass;
m_attachmentId = AZ::RHI::AttachmentId{};
+ m_slotName = AZ::Name{};
m_selectedChanged = true;
}
}
@@ -179,76 +251,13 @@ namespace AZ::Render
{
m_selectedPass = pass;
m_attachmentId = AZ::RHI::AttachmentId{};
+ m_slotName = AZ::Name{};
m_selectedChanged = true;
}
if (nodeOpen)
{
- for (const auto& binding : pass->GetAttachmentBindings())
- {
- // Binding info: [slot type] [slot name]
- AZStd::string label = AZStd::string::format("[%s] [%s]", AZ::RPI::ToString(binding.m_slotType),
- binding.m_name.GetCStr());
-
- // Append attachment info if the attachment exists
- if (binding.m_attachment)
- {
- AZ::RHI::AttachmentType type = binding.m_attachment->GetAttachmentType();
-
- // Append attachment info: [attachment type] attachment name
- label += AZStd::string::format(" [%s] %s",
- AZ::RHI::ToString(type),
- binding.m_attachment->m_name.GetCStr());
-
- if (type == AZ::RHI::AttachmentType::Image)
- {
- // Append image info: [format] [size] [msaa]
- AZ::RHI::ImageDescriptor descriptor;
- if (binding.m_attachment->m_importedResource)
- {
- AZ::RPI::Image* image = static_cast(binding.m_attachment->m_importedResource.get());
- descriptor = image->GetRHIImage()->GetDescriptor();
- }
- else
- {
- descriptor = binding.m_attachment->m_descriptor.m_image;
- }
- auto format = descriptor.m_format;
- auto size = descriptor.m_size;
- label += AZStd::string::format(" [%s] [%dx%d]", AZ::RHI::ToString(format), size.m_width, size.m_height);
-
- if (descriptor.m_multisampleState.m_samples > 1)
- {
- if (descriptor.m_multisampleState.m_customPositionsCount > 0)
- {
- label += AZStd::string::format(" [MSAA_Custom_%dx]", descriptor.m_multisampleState.m_samples);
- }
- else
- {
- label += AZStd::string::format(" [MSAA_%dx]", descriptor.m_multisampleState.m_samples);
- }
- }
- }
- else if (type == AZ::RHI::AttachmentType::Buffer)
- {
- // Append buffer info: [size]
- auto size = binding.m_attachment->m_descriptor.m_buffer.m_byteCount;
- label += AZStd::string::format(" [%llu]", size);
- }
-
- if (Scriptable_ImGui::Selectable(label.c_str(), m_attachmentId == binding.m_attachment->GetAttachmentId()))
- {
- m_selectedPass = pass;
- m_attachmentId = binding.m_attachment->GetAttachmentId();
- m_selectedChanged = true;
- }
- }
- else
- {
- // Only draw text (not selectable) if there is no attachment binded to the slot.
- ImGui::Text(label.c_str());
- }
- }
+ DrawPassAttachments(pass);
Scriptable_ImGui::TreePop();
}
@@ -266,11 +275,13 @@ namespace AZ::Render
{
m_selectedPass = pass;
m_attachmentId = AZ::RHI::AttachmentId{};
+ m_slotName = AZ::Name{};
m_selectedChanged = true;
}
if (nodeOpen)
{
+ DrawPassAttachments(pass);
for (const auto& child : asParent->GetChildren())
{
DrawTreeView(child.get());
@@ -354,6 +365,7 @@ namespace AZ::Render
m_selectedPass = nullptr;
m_attachmentId = AZ::RHI::AttachmentId{};
+ m_slotName = AZ::Name{};
m_selectedChanged = false;
m_readback = nullptr;
m_previewPass = nullptr;
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h
index 9fe3f2c25b..9e6c38a939 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont.h
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include