diff --git a/Assets/Editor/Editor.tip b/Assets/Editor/Editor.tip deleted file mode 100644 index 969e9d5ab5..0000000000 --- a/Assets/Editor/Editor.tip +++ /dev/null @@ -1,34 +0,0 @@ -CryEngine tips of the day - -You can toggle snap to grid by pressing G. -Ctrl+Shift+Clicking somewhere with an object selected quickly moves the object to that position when in move mode. -Pressing M will open the material editor. -Show and Hide helpers is bound to Shift + Space by default. -Enable AI/Physics is bound to Ctrl + P by default. -You can save a viewport location by pressing Ctrl + F1 through f12 and go to that position using Shift + F1 through F12. -You can link objects together by using the link command on the top menu of the editor. -Pressing 1 through 5 on the keyboard will cycle through brush operations such as move or scale. -You can simply bind keyboard shortcuts to editor functions by going to Tools --> Customize Keyboard. -Pressing H will hide the selected objects, Ctrl-H will unhide all hidden objects. -Pressing F will freeze the selected objects, Ctrl-F will unfreeze all frozen objects. -Pressing F3 will toggle wireframe view. -Camera/terrain collision can be toggled using Q. -You can restart the Editor by pressing the restart button on your PC. -Pressing Ctrl-C with an object selected will clone that object. -Toggle the console by pressing the tilde (~) key. -You can dock windows by dragging them onto the blue helpers that appear when you grab a window by the titlebar. -You can select materials by clicking on the dropper icon in the material editor and then clicking on the material you wish to select. -You can right click on the previewer in the material editor and change the model to different shapes and background colors. -Materials can be saved in the local level folder for re-distribution. -Always keep your level free of errors and immidiately fix errors reported by the error report screen when you load your level. -You must always export to engine before you can run it in pure game mode. (File --> Export to engine) -You must re-triangulate AI before playing your level in game mode. (AI --> Generate all navigation) -You must always re-generate surface textures after you finish painting the terrain. (File --> Regenerate surface textures) -Press Ctrl-G or F12 to go into the Game mode, ESC to return to Editing mode. -Quickly rebuild a level (without regenerating the ground texture) by pressing Ctrl-E. -Hold down the third mouse button and drag to move the camera up and down. -Missing objects are represented by a bright yellow sphere. -Hold Alt + Middle Mouse button to rotate around an object. -Select multiple objects by holding Ctrl. -You can place multiple instances of vegetation by holding Shift and clicking on the terrain. -A number of useful commands can be found in Tools --> User commands. This can also be dragged and docked to the main window. \ No newline at end of file diff --git a/Assets/Editor/Translation/scriptcanvas_en_us.ts b/Assets/Editor/Translation/scriptcanvas_en_us.ts index a7d29e2dbc..5cafabaf60 100644 --- a/Assets/Editor/Translation/scriptcanvas_en_us.ts +++ b/Assets/Editor/Translation/scriptcanvas_en_us.ts @@ -14679,6 +14679,25 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro + + Method: NetBindComponent + + NETBINDCOMPONENT_ISNETENTITYROLEAUTHORITY_TOOLTIP + Returns true if this network entity is an authoritative proxy on a server (full authority); otherwise false. + + + NETBINDCOMPONENT_ISNETENTITYROLEAUTONOMOUS_TOOLTIP + Returns true if this network entity is an autonomous proxy on a client (can execute local prediction) or if this network entity is an authoritative proxy on a server but has autonomous privileges (ie: a host who is also a player); otherwise false. + + + NETBINDCOMPONENT_ISNETENTITYROLECLIENT_TOOLTIP + Returns true if this network entity is a simulated proxy on a client; otherwise false. + + + NETBINDCOMPONENT_ISNETENTITYROLESERVER_TOOLTIP + Returns true if this network entity is a simulated proxy on a server (ie: a different server may own this entity, but the entity has been replicated to this server; otherwise false. + + Method: Math diff --git a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt index f463210cb0..0146aa3981 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt @@ -21,6 +21,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/${PAL_PLATFORM_NAME}/ + TIMEOUT 3000 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor 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 04be31759d..511d9b3ecd 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 @@ -18,11 +18,12 @@ import typing from datetime import datetime 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_utils import aws_utils from AWS.common.aws_credentials import aws_credentials -from AWS.Windows.resource_mappings.resource_mappings import resource_mappings -from AWS.Windows.cdk.cdk import cdk from .aws_metrics_utils import aws_metrics_utils AWS_METRICS_FEATURE_NAME = 'AWSMetrics' @@ -32,7 +33,7 @@ logger = logging.getLogger(__name__) def setup(launcher: ly_test_tools.launchers.Launcher, - cdk: cdk, + cdk: Cdk, asset_processor: asset_processor, resource_mappings: resource_mappings, context_variable: str = '') -> typing.Tuple[ly_test_tools.log.log_monitor.LogMonitor, str, str]: @@ -116,18 +117,18 @@ def remove_file(file_path: str) -> None: @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']) -class TestAWSMetrics_Windows(object): - def test_AWSMetrics_RealTimeAnalytics_MetricsSentToCloudWatch(self, - level: str, - launcher: ly_test_tools.launchers.Launcher, - asset_processor: pytest.fixture, - workspace: pytest.fixture, - aws_utils: aws_utils, - aws_credentials: aws_credentials, - resource_mappings: resource_mappings, - cdk: cdk, - aws_metrics_utils: aws_metrics_utils, - ): +class TestAWSMetricsWindows(object): + def test_realtime_analytics_metrics_sent_to_cloudwatch(self, + level: str, + launcher: ly_test_tools.launchers.Launcher, + asset_processor: pytest.fixture, + workspace: pytest.fixture, + aws_utils: pytest.fixture, + aws_credentials: aws_credentials, + resource_mappings: pytest.fixture, + cdk: pytest.fixture, + aws_metrics_utils: aws_metrics_utils, + ): """ Tests that the submitted metrics are sent to CloudWatch for real-time analytics. """ @@ -148,7 +149,7 @@ class TestAWSMetrics_Windows(object): 'AWS/Lambda', 'Invocations', [{'Name': 'FunctionName', - 'Value': f'{stack_name}-AnalyticsProcessingLambda'}], + 'Value': f'{stack_name}-AnalyticsProcessingLambdaName'}], start_time) logger.info('Operational health metrics sent to CloudWatch.') @@ -162,14 +163,14 @@ class TestAWSMetrics_Windows(object): # Stop the Kinesis Data Analytics application. aws_metrics_utils.stop_kinesis_data_analytics_application(analytics_application_name) - def test_AWSMetrics_UnauthorizedUser_RequestRejected(self, - level: str, - launcher: ly_test_tools.launchers.Launcher, - cdk: cdk, - aws_credentials: aws_credentials, - asset_processor: pytest.fixture, - resource_mappings: resource_mappings, - workspace: pytest.fixture): + def test_unauthorized_user_request_rejected(self, + level: str, + launcher: ly_test_tools.launchers.Launcher, + cdk: pytest.fixture, + aws_credentials: aws_credentials, + asset_processor: pytest.fixture, + resource_mappings: pytest.fixture, + workspace: pytest.fixture): """ Tests that unauthorized users cannot send metrics events to the AWS backed backend. """ @@ -187,14 +188,14 @@ class TestAWSMetrics_Windows(object): assert result, 'Metrics events are sent successfully by unauthorized user' logger.info('Unauthorized user is rejected to send metrics.') - def test_AWSMetrics_BatchAnalytics_MetricsDeliveredToS3(self, + def test_batch_analytics_metrics_delivered_to_s3(self, level: str, launcher: ly_test_tools.launchers.Launcher, - cdk: cdk, + cdk: pytest.fixture, aws_credentials: aws_credentials, asset_processor: pytest.fixture, - resource_mappings: resource_mappings, - aws_utils: aws_utils, + resource_mappings: pytest.fixture, + aws_utils: pytest.fixture, aws_metrics_utils: aws_metrics_utils, workspace: pytest.fixture): """ @@ -234,4 +235,3 @@ class TestAWSMetrics_Windows(object): time.sleep(60) # Empty the S3 bucket. S3 buckets can only be deleted successfully when it doesn't contain any object. aws_metrics_utils.empty_s3_bucket(analytics_bucket_name) - diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk_utils.py similarity index 59% rename from AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py rename to AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk_utils.py index 9254c3d4eb..172885ad60 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk_utils.py @@ -12,6 +12,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import os import pytest import boto3 +import uuid +import logging +import subprocess +import botocore import ly_test_tools.environment.process_utils as process_utils from typing import List @@ -19,22 +23,71 @@ from typing import List BOOTSTRAP_STACK_NAME = 'CDKToolkit' BOOTSTRAP_STAGING_BUCKET_LOGIC_ID = 'StagingBucket' +logger = logging.getLogger(__name__) + + class Cdk: """ Cdk class that provides methods to run cdk application commands. Expects system to have NodeJS, AWS CLI and CDK installed globally and have their paths setup as env variables. """ - def __init__(self, cdk_path: str, project: str, account_id: str, - workspace: pytest.fixture, session: boto3.session.Session): + def __init__(self): + self._cdk_env = '' + self._stacks = [] + self._cdk_path = os.path.dirname(os.path.realpath(__file__)) + self._session = '' + + cdk_npm_latest_version_cmd = ['npm', 'view', 'aws-cdk', 'version'] + + output = process_utils.check_output( + cdk_npm_latest_version_cmd, + cwd=self._cdk_path, + shell=True) + cdk_npm_latest_version = output.split()[0] + + cdk_version_cmd = ['cdk', 'version'] + output = process_utils.check_output( + cdk_version_cmd, + cwd=self._cdk_path, + shell=True) + cdk_version = output.split()[0] + logger.info(f'Current CDK version {cdk_version}') + + if cdk_version != cdk_npm_latest_version: + try: + logger.info(f'Updating CDK to latest') + # uninstall and reinstall cdk in case npm has been updated. + output = process_utils.check_output( + 'npm uninstall -g aws-cdk', + cwd=self._cdk_path, + shell=True) + + logger.info(f'Uninstall CDK output: {output}') + + output = process_utils.check_output( + 'npm install -g aws-cdk@latest', + cwd=self._cdk_path, + shell=True) + + logger.info(f'Install CDK output: {output}') + except subprocess.CalledProcessError as error: + logger.warning(f'Failed reinstalling latest CDK on npm' + f'\nError:{error.stderr}') + + def setup(self, cdk_path: str, project: str, account_id: str, + workspace: pytest.fixture, session: boto3.session.Session, bootstrap_required: bool): """ :param cdk_path: Path where cdk app.py is stored. :param project: Project name used for cdk project name env variable. :param account_id: AWS account id to use with cdk application. :param workspace: ly_test_tools workspace fixture. + :param workspace: bootstrap_required deploys bootstrap stack. """ + self._cdk_env = os.environ.copy() - self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project + unique_id = uuid.uuid4().hex[-4:] + self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project[:4] + unique_id if len(project) > 4 else project + unique_id self._cdk_env['O3DE_AWS_DEPLOY_REGION'] = session.region_name self._cdk_env['O3DE_AWS_DEPLOY_ACCOUNT'] = account_id self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH'] @@ -43,27 +96,37 @@ class Cdk: self._cdk_env['AWS_ACCESS_KEY_ID'] = credentials.access_key self._cdk_env['AWS_SECRET_ACCESS_KEY'] = credentials.secret_key self._cdk_env['AWS_SESSION_TOKEN'] = credentials.token - self._stacks = [] self._cdk_path = cdk_path + self._session = session + output = process_utils.check_output( 'python -m pip install -r requirements.txt', cwd=self._cdk_path, env=self._cdk_env, shell=True) + logger.info(f'Installing cdk python dependencies: {output}') + + if bootstrap_required: + self.bootstrap() + def bootstrap(self) -> None: """ Deploy the bootstrap stack. """ - bootstrap_cmd = ['cdk', 'bootstrap', - f'aws://{self._cdk_env["O3DE_AWS_DEPLOY_ACCOUNT"]}/{self._cdk_env["O3DE_AWS_DEPLOY_REGION"]}'] - - process_utils.check_call( - bootstrap_cmd, - cwd=self._cdk_path, - env=self._cdk_env, - shell=True) + try: + bootstrap_cmd = ['cdk', 'bootstrap', + f'aws://{self._cdk_env["O3DE_AWS_DEPLOY_ACCOUNT"]}/{self._cdk_env["O3DE_AWS_DEPLOY_REGION"]}'] + + process_utils.check_call( + bootstrap_cmd, + cwd=self._cdk_path, + env=self._cdk_env, + shell=True) + except botocore.exceptions.ClientError as clientError: + logger.warning(f'Failed creating Bootstrap stack {BOOTSTRAP_STACK_NAME} not found. ' + f'\nError:{clientError["Error"]["Message"]}') def list(self) -> List[str]: """ @@ -131,83 +194,51 @@ class Cdk: """ Destroys the cdk application. """ - destroy_cdk_application_cmd = ['cdk', 'destroy', '-f'] - process_utils.check_output( - destroy_cdk_application_cmd, - cwd=self._cdk_path, - env=self._cdk_env, - shell=True) + + logger.info(f'CDK Path {self._cdk_path}') + destroy_cdk_application_cmd = ['cdk', 'destroy', '--all', '-f'] + + try: + process_utils.check_output( + destroy_cdk_application_cmd, + cwd=self._cdk_path, + env=self._cdk_env, + shell=True) + + except subprocess.CalledProcessError as e: + logger.error(e.output) + raise e self._stacks = [] - self._cdk_path = '' - @staticmethod - def remove_bootstrap_stack(aws_utils: pytest.fixture) -> None: + def remove_bootstrap_stack(self) -> None: """ Remove the CDK bootstrap stack. :param aws_utils: aws_utils fixture. """ # Check if the bootstrap stack exists. - response = aws_utils.client('cloudformation').describe_stacks( + response = self._session.client('cloudformation').describe_stacks( StackName=BOOTSTRAP_STACK_NAME ) stacks = response.get('Stacks', []) - if not stacks: + if not stacks or len(stacks) is 0: return # Clear the bootstrap staging bucket before deleting the bootstrap stack. - response = aws_utils.client('cloudformation').describe_stack_resource( + response = self._session.client('cloudformation').describe_stack_resource( StackName=BOOTSTRAP_STACK_NAME, LogicalResourceId=BOOTSTRAP_STAGING_BUCKET_LOGIC_ID ) staging_bucket_name = response.get('StackResourceDetail', {}).get('PhysicalResourceId', '') if staging_bucket_name: - s3 = aws_utils.resource('s3') + s3 = self._session.resource('s3') bucket = s3.Bucket(staging_bucket_name) for key in bucket.objects.all(): key.delete() # Delete the bootstrap stack. - aws_utils.client('cloudformation').delete_stack( - StackName=BOOTSTRAP_STACK_NAME - ) - - -@pytest.fixture(scope='function') -def cdk( - request: pytest.fixture, - project: str, - feature_name: str, - workspace: pytest.fixture, - aws_utils: pytest.fixture, - bootstrap_required: bool = True, - destroy_stacks_on_teardown: bool = True) -> Cdk: - """ - Fixture for setting up a Cdk - :param request: _pytest.fixtures.SubRequest class that handles getting - a pytest fixture from a pytest function/fixture. - :param project: Project name used for cdk project name env variable. - :param feature_name: Feature gem name to expect cdk folder in. - :param workspace: ly_test_tools workspace fixture. - :param aws_utils: aws_utils fixture. - :param bootstrap_required: Whether the bootstrap stack needs to be created to - provision resources the AWS CDK needs to perform the deployment. - :param destroy_stacks_on_teardown: option to control calling destroy ot the end of test. - :return Cdk class object. - """ - - cdk_path = f'{workspace.paths.engine_root()}/Gems/{feature_name}/cdk' - cdk_obj = Cdk(cdk_path, project, aws_utils.assume_account_id(), workspace, aws_utils.assume_session()) - - if bootstrap_required: - cdk_obj.bootstrap() - - def teardown(): - if destroy_stacks_on_teardown: - cdk_obj.destroy() - cdk_obj.remove_bootstrap_stack(aws_utils) - - request.addfinalizer(teardown) - - return cdk_obj + # Should not need to delete the stack if S3 bucket can be cleaned. + # self._session.client('cloudformation').delete_stack( + # StackName=BOOTSTRAP_STACK_NAME + # ) diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py index 7b9c549f6c..f8aa5b85eb 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py @@ -12,9 +12,10 @@ import os import logging import ly_test_tools.log.log_monitor +# fixture imports from AWS.Windows.resource_mappings.resource_mappings import resource_mappings -from AWS.Windows.cdk.cdk import cdk -from AWS.common.aws_utils import aws_utils +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 AWS_PROJECT_NAME = 'AWS-AutomationTest' @@ -75,5 +76,5 @@ class TestAWSClientAuthAnonymousCredentials(object): expected_lines=['(Script) - Success anonymous credentials'], unexpected_lines=['(Script) - Fail anonymous credentials'], halt_on_unexpected=True, - ) + ) assert result, 'Anonymous credentials fetched successfully.' diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py index 89b859dd0f..28b17fdeee 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py @@ -12,9 +12,10 @@ import os import logging import ly_test_tools.log.log_monitor +# fixture imports from AWS.Windows.resource_mappings.resource_mappings import resource_mappings -from AWS.Windows.cdk.cdk import cdk -from AWS.common.aws_utils import aws_utils +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 AWS_PROJECT_NAME = 'AWS-AutomationTest' diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py index ff33f58d1d..fc3c5095e3 100644 --- a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py @@ -8,11 +8,12 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. """ import boto3 -import pytest import logging logger = logging.getLogger(__name__) -logging.getLogger('boto').setLevel(logging.CRITICAL) +logging.getLogger('boto3').setLevel(logging.WARNING) +logging.getLogger('botocore').setLevel(logging.WARNING) +logging.getLogger('nose').setLevel(logging.WARNING) class AwsUtils: @@ -63,28 +64,3 @@ class AwsUtils: clears stored session """ self._assume_session = None - - -@pytest.fixture(scope='function') -def aws_utils( - request: pytest.fixture, - assume_role_arn: str, - session_name: str, - region_name: str): - """ - Fixture for AWS util functions - :param request: _pytest.fixtures.SubRequest class that handles getting - a pytest fixture from a pytest function/fixture. - :param assume_role_arn: Role used to fetch temporary aws credentials, configure service clients with obtained credentials. - :param session_name: Session name to set. - :param region_name: AWS account region to set for session. - :return AWSUtils class object. - """ - aws_utils_obj = AwsUtils(assume_role_arn, session_name, region_name) - - def teardown(): - aws_utils_obj.destroy() - - request.addfinalizer(teardown) - - return aws_utils_obj diff --git a/AutomatedTesting/Gem/PythonTests/AWS/conftest.py b/AutomatedTesting/Gem/PythonTests/AWS/conftest.py new file mode 100644 index 0000000000..47f9b5cefe --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/conftest.py @@ -0,0 +1,87 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" +import pytest +import logging +from AWS.common.aws_utils import AwsUtils +from AWS.Windows.cdk.cdk_utils import Cdk + +logger = logging.getLogger(__name__) + + +@pytest.fixture(scope='function') +def aws_utils( + request: pytest.fixture, + assume_role_arn: str, + session_name: str, + region_name: str): + """ + Fixture for AWS util functions + :param request: _pytest.fixtures.SubRequest class that handles getting + a pytest fixture from a pytest function/fixture. + :param assume_role_arn: Role used to fetch temporary aws credentials, configure service clients with obtained credentials. + :param session_name: Session name to set. + :param region_name: AWS account region to set for session. + :return AWSUtils class object. + """ + + aws_utils_obj = AwsUtils(assume_role_arn, session_name, region_name) + + def teardown(): + aws_utils_obj.destroy() + + request.addfinalizer(teardown) + + return aws_utils_obj + +# Set global pytest variable for cdk to avoid recreating instance +pytest.cdk_obj = None + + +@pytest.fixture(scope='function') +def cdk( + request: pytest.fixture, + project: str, + feature_name: str, + workspace: pytest.fixture, + aws_utils: pytest.fixture, + bootstrap_required: bool = True, + destroy_stacks_on_teardown: bool = True) -> Cdk: + """ + Fixture for setting up a Cdk + :param request: _pytest.fixtures.SubRequest class that handles getting + a pytest fixture from a pytest function/fixture. + :param project: Project name used for cdk project name env variable. + :param feature_name: Feature gem name to expect cdk folder in. + :param workspace: ly_test_tools workspace fixture. + :param aws_utils: aws_utils fixture. + :param bootstrap_required: Whether the bootstrap stack needs to be created to + provision resources the AWS CDK needs to perform the deployment. + :param destroy_stacks_on_teardown: option to control calling destroy ot the end of test. + :return Cdk class object. + """ + + cdk_path = f'{workspace.paths.engine_root()}/Gems/{feature_name}/cdk' + logger.info(f'CDK Path {cdk_path}') + + if pytest.cdk_obj is None: + pytest.cdk_obj = Cdk() + + pytest.cdk_obj.setup(cdk_path, project, aws_utils.assume_account_id(), workspace, aws_utils.assume_session(), + bootstrap_required) + def teardown(): + if destroy_stacks_on_teardown: + pytest.cdk_obj.destroy() + # Enable after https://github.com/aws/aws-cdk/issues/986 is fixed. + # Until then clean the bootstrap bucket manually. + # cdk_obj.remove_bootstrap_stack() + + request.addfinalizer(teardown) + + return pytest.cdk_obj diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 8142691464..c6ed6c7538 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -60,5 +60,4 @@ add_subdirectory(streaming) add_subdirectory(smoke) ## AWS ## -# Enable when AWS Gems work on Linux and Android. -# add_subdirectory(AWS) +add_subdirectory(AWS) diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py index 5d4218efd0..c195672760 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py @@ -79,8 +79,6 @@ class TestBasicEditorWorkflows(EditorTestHelper): grp_box = new_level_dlg.findChild(QtWidgets.QGroupBox, "STATIC_GROUP1") level_name = grp_box.findChild(QtWidgets.QLineEdit, "LEVEL") level_name.setText(self.args["level"]) - level_folders = grp_box.findChild(QtWidgets.QComboBox, "LEVEL_FOLDERS") - level_folders.setCurrentText("Levels/") button_box = new_level_dlg.findChild(QtWidgets.QDialogButtonBox, "buttonBox") button_box.button(QtWidgets.QDialogButtonBox.Ok).click() diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly new file mode 100644 index 0000000000..af8a7f5c8e --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0f4d4e0155feaa76c80a14128000a0fd9570ab76e79f4847eaef9006324a4d2 +size 9084 diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas new file mode 100644 index 0000000000..a2bbdfce39 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas @@ -0,0 +1,2358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml new file mode 100644 index 0000000000..d4e3d33551 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml @@ -0,0 +1 @@ + diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml new file mode 100644 index 0000000000..d827d4da29 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml @@ -0,0 +1 @@ + diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml new file mode 100644 index 0000000000..56c3f1efd4 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/level.pak b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak new file mode 100644 index 0000000000..8da6f7f7d6 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da041115014f11696d5878d5c21247c17b8d694fa9674e30692259261a7223a2 +size 3792 diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuth/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/Levels/AWS/ClientAuthPasswordSignIn/ClientAuthPasswordSignIn.ly b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/ClientAuthPasswordSignIn.ly new file mode 100644 index 0000000000..24fe4f2482 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/ClientAuthPasswordSignIn.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43b1a23b62fe2ffa05545ac99524f40b6fff49d6e35925b9d6138c00d8082e86 +size 9073 diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/PasswordSignIn.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/PasswordSignIn.scriptcanvas new file mode 100644 index 0000000000..ffc3064084 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/PasswordSignIn.scriptcanvas @@ -0,0 +1,6642 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/filelist.xml new file mode 100644 index 0000000000..f3e20f9b63 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/level.pak b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/level.pak new file mode 100644 index 0000000000..49349b01e1 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a58292341785cb260dc0ccf346259e35e2817ee48fc401a21ab528f6afb97b52 +size 3551 diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/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/Levels/AWS/ClientAuthPasswordSignUp/ClientAuthPasswordSignUp.ly b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/ClientAuthPasswordSignUp.ly new file mode 100644 index 0000000000..3500584d99 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/ClientAuthPasswordSignUp.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3d5121b26608b02747e245071ccff29ac57358cb6349ec9495a7a003ac12467 +size 8942 diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/PasswordSignUp.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/PasswordSignUp.scriptcanvas new file mode 100644 index 0000000000..632d27d5b0 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/PasswordSignUp.scriptcanvas @@ -0,0 +1,4408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/filelist.xml new file mode 100644 index 0000000000..a9b73a9fb3 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/level.pak b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/level.pak new file mode 100644 index 0000000000..85d3c59f9b --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:605391d415b828b100bada11d108099520c0b6a020f17588887b610475805d90 +size 3546 diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/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/Levels/AWS/Metrics/Metrics.ly b/AutomatedTesting/Levels/AWS/Metrics/Metrics.ly new file mode 100644 index 0000000000..12998e89be --- /dev/null +++ b/AutomatedTesting/Levels/AWS/Metrics/Metrics.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:023992998ab5a1d64b38dacd1d5e1a9dc930ff704289c0656ed6eaba6951d660 +size 9066 diff --git a/AutomatedTesting/Levels/AWS/Metrics/Script/Metrics.lua b/AutomatedTesting/Levels/AWS/Metrics/Script/Metrics.lua new file mode 100644 index 0000000000..42484ff4e5 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/Metrics/Script/Metrics.lua @@ -0,0 +1,79 @@ +---------------------------------------------------------------------------------------------------- +-- +-- All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +-- its licensors. +-- +-- For complete copyright and license terms please see the LICENSE at the root of this +-- distribution (the "License"). All use of this software is governed by the License, +-- or, if provided, by the license below or the license accompanying this file. Do not +-- remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- +-- +---------------------------------------------------------------------------------------------------- +local metrics = { +} + +function metrics:OnActivate() + self.tickTime = 0 + self.numSubmittedMetricsEvents = 0 + + self.tickBusHandler = TickBus.Connect(self,self.entityId) + self.metricsNotificationHandler = AWSMetricsNotificationBus.Connect(self, self.entityId) + + LyShineLua.ShowMouseCursor(true) +end + +function metrics:OnSendMetricsSuccess(requestId) + Debug.Log("Metrics is sent successfully.") +end + +function metrics:OnSendMetricsFailure(requestId, errorMessage) + Debug.Log("Failed to send metrics.") +end + +function metrics:OnDeactivate() + AWSMetricsRequestBus.Broadcast.FlushMetrics() + Debug.Log("Stop generating new test events and flushed the buffered metrics.") + + self.tickBusHandler:Disconnect() + self.metricsNotificationHandler:Disconnect() +end + +function metrics:OnTick(deltaTime, timePoint) + self.tickTime = self.tickTime + deltaTime + + if self.tickTime > 2.0 then + defaultAttribute = AWSMetrics_MetricsAttribute() + defaultAttribute:SetName("event_name") + defaultAttribute:SetStrValue("login") + + customAttribute = AWSMetrics_MetricsAttribute() + customAttribute:SetName("custom_attribute") + customAttribute:SetStrValue("value") + + attributeList = AWSMetrics_AttributesSubmissionList() + attributeList.attributes:push_back(defaultAttribute) + attributeList.attributes:push_back(customAttribute) + + + if self.numSubmittedMetricsEvents % 2 == 0 then + if AWSMetricsRequestBus.Broadcast.SubmitMetrics(attributeList.attributes, 0, "lua", false) then + Debug.Log("Submitted metrics without buffer.") + else + Debug.Log("Failed to Submit metrics without buffer.") + end + else + if AWSMetricsRequestBus.Broadcast.SubmitMetrics(attributeList.attributes, 0, "lua", true) then + Debug.Log("Submitted metrics with buffer.") + else + Debug.Log("Failed to Submit metrics with buffer.") + end + end + + self.numSubmittedMetricsEvents = self.numSubmittedMetricsEvents + 1 + self.tickTime = 0 + end +end + +return metrics diff --git a/AutomatedTesting/Levels/AWS/Metrics/filelist.xml b/AutomatedTesting/Levels/AWS/Metrics/filelist.xml new file mode 100644 index 0000000000..3539102346 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/Metrics/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/AWS/Metrics/level.pak b/AutomatedTesting/Levels/AWS/Metrics/level.pak new file mode 100644 index 0000000000..fd1f5ac6ad --- /dev/null +++ b/AutomatedTesting/Levels/AWS/Metrics/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7c0c07b13bb64db344b94d5712e1e802e607a9dee506768b34481f4a76d8505 +size 3593 diff --git a/AutomatedTesting/Levels/AWS/Metrics/tags.txt b/AutomatedTesting/Levels/AWS/Metrics/tags.txt new file mode 100644 index 0000000000..0d6c1880e7 --- /dev/null +++ b/AutomatedTesting/Levels/AWS/Metrics/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/Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.h b/Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.h index 48115b53af..f49b3ff6e5 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.h @@ -57,7 +57,13 @@ namespace AZ //! Determines if a component can be created from the asset type //! This will be called before attempting to create a component from an asset (drag&drop, etc) //! You can use this to filter by subIds or do your own validation here if needed - virtual bool CanCreateComponent(const AZ::Data::AssetId& /*assetId*/) const { return true; } + virtual bool CanCreateComponent([[maybe_unused]] const AZ::Data::AssetId& assetId) const { return true; } + + //! Determines if other products conflict with the given one when multiple are generated from a source asset. + //! This will be called before attempting to create a component from an asset (drag&drop, etc) + //! You can use this to filter by conflicting product types or in case you want to skip for UX reasons. + //! @param[in] productAssetTypes Asset types of all generated products, including the one for our given type in this bus. + virtual bool HasConflictingProducts([[maybe_unused]] const AZStd::vector& productAssetTypes) const { return false; } }; using AssetTypeInfoBus = AZ::EBus; diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index 4931c203cf..a46d8ad9d4 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h @@ -1206,7 +1206,7 @@ namespace JsonSerializationTests if (this->m_features.m_enableInitializationTest) { auto instance = this->m_description.CreateDefaultInstance(); - typename TypeParam::Type compare; + AZStd::remove_cvref_t compare; if (!this->m_description.AreEqual(*instance, compare)) { auto serializer = this->m_description.CreateSerializer(); diff --git a/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm index 3eba9831b4..8b911c90e9 100644 --- a/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm +++ b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm @@ -75,6 +75,8 @@ namespace AzFramework // Add a fullscreen button in the upper right of the title bar. [m_nativeWindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + m_nativeWindow.tabbingMode = NSWindowTabbingModeDisallowed; + // Make the window active [m_nativeWindow makeKeyAndOrderFront:nil]; m_nativeWindow.title = m_windowTitle; diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h index 4ef8ca44d4..6b8c599bd8 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h @@ -44,6 +44,11 @@ namespace AzNetworking //! @class IConnection //! @brief interface class for network connections. + //! + //! IConnection provides a pure-virtual interface for all network connection types. IConnections provide access to + //! a ConnectionMetrics object which provides a variety of metrics on the connection itself such as data rate, RTT and + //! packet statistics. + class IConnection { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h index af9e26c765..219ae2b005 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionListener.h @@ -22,6 +22,12 @@ namespace AzNetworking { //! @class IConnectionListener //! @brief interface class for application layer dealing with connection level events. + //! + //! IConnectionListener defines an abstract interface that the user of AzNetworking is expected to implement to react and + //! handle all IConnection related events, including the handling of any received IPacket derived packets. The AzNetworking + //! user should derive a handler class from IConnectionListener, and provide an instance of that handler to any + //! INetworkInterface the user instantiates. The lifetime of the IConnectionListener must outlive the lifetime of the + //! INetworkInterface. class IConnectionListener { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h index 5b53efd951..c86f78e8be 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnectionSet.h @@ -18,6 +18,11 @@ namespace AzNetworking { //! @class IConnectionSet //! @brief interface class for managing a set of connections. + //! + //! IConnectionSet defines a simple interface for working with an abstract set of IConnections bound to an + //! INetworkInterface. Generally users of AzNetworking will not have reason to interact directly with the IConnectionSet, + //! as its interface is completely wrapped by INetworkInterface. + class IConnectionSet { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h index 47bc7adf4e..abd38a392b 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h @@ -23,10 +23,10 @@ namespace AzNetworking //! Collection of compression related error codes enum class CompressorError { - Ok, ///< No error, operation finished successfully - InsufficientBuffer, ///< Buffer size is insufficient for the operation to complete, increase the size and try again - CorruptData, ///< Malformed or hacked packet, potentially security issue - Uninitialized ///< Compressor or supplied buffers are uninitialized + Ok, //!< No error, operation finished successfully + InsufficientBuffer, //!< Buffer size is insufficient for the operation to complete, increase the size and try again + CorruptData, //!< Malformed or hacked packet, potentially security issue + Uninitialized //!< Compressor or supplied buffers are uninitialized }; //! Unique identifier of a given compressor @@ -34,6 +34,12 @@ namespace AzNetworking //! @class ICompressor //! @brief Packet data compressor interface. + //! + //! ICompressor is an abstract compression interface meant for user provided GEMs to implement (such as the [Multiplayer + //! Compression Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression)). + //! Compression is supported for both TCP and UDP connections. Instantiation of a compressor is controlled by the + //! `net_UdpCompressor` or `net_TcpCompressor` cvar for their respective protocols. + class ICompressor { public: @@ -87,8 +93,16 @@ namespace AzNetworking ) = 0; }; - //! Abstract factory to instantiate compressors. - //! Used by the network interface to create a compressor + //! @class ICompressorFactory + //! @brief Abstract factory to instantiate compressors. + //! + //! ICompressorFactory is an abstract compression interface meant for user provided GEMs to implement. ICompressorFactory + //! implementations can be registered to classes implementing INetworking. Registered factories can then be used to create + //! ICompressor implementations on demand. The [Multiplayer Compression + //! Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression) is an example of an ICompressorFactory + //! for an LZ4 Compressor. In it, MultiplayerCompressionSystemComponent registers its ICompressorFactory with + //! NetworkingSystemComponent, which is an implementation of INetworking. Registered factories are keyed by their AZ Name + //! which is accessed through the factory's GetFactoryName method. class ICompressorFactory { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h index e674640053..b0f383c710 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworkInterface.h @@ -22,7 +22,16 @@ namespace AzNetworking { //! @class INetworkInterface - //! @brief pure virtual network interface class to abstract client/server and tcp/udp concerns from application code. + //! @brief Network interface class to abstract client/server and protocol concerns from application code. + //! + //! INetworkInterface provides an abstract API capable of receiving and opening IConnection objects, sending IPacket objects with optional + //! reliability, and determining the delivery status of packets that have been sent unreliably (delivery of reliable packets + //! is guaranteed as long as the associated connection remains open). INetworkInterface must be provided an + //! IConnectionListener instance that outlives the INetworkInterface itself. The INetworkInterface also creates and manages + //! the IConnectionSet, which tracks all open connections bound to the interface. INetworkInterface also provides GetMetrics + //! functions which can be used to fetch a struct detailing a variety of metrics relating to send and receive rates for both + //! packets and bytes in addition to the effect of features on those rates (such as packet size reduction due to compression.) + class INetworkInterface { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h index fb6d217b80..fea3b70c79 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h @@ -23,6 +23,17 @@ namespace AzNetworking //! @class INetworking //! @brief The interface for creating and working with network interfaces. + //! + //! INetworking is an Az::Interface that provides applications access to higher level networking abstractions. + //! AzNetworking::INetworking can be used to instantiate new INetworkInterfaces that can be configured to operate over + //! either TCP or UDP, enable or disable encryption, and be assigned a trust level. + //! + //! INetworking is also responsible for registering ICompressorFactory implementations. This allows a developer to have + //! access to multiple ICompressorFactory implementations by name. The [MultiplayerCompressor + //! Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression) is an example of this using the + //! [LZ4](https://wikipedia.org/wiki/LZ4_%28compression_algorithm%29) algorithm. + //! + class INetworking { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h index d62318ec36..81c79f9e3a 100644 --- a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h +++ b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacket.h @@ -24,6 +24,15 @@ namespace AzNetworking //! @class IPacket //! @brief Base class for all packets. + //! + //! IPacket defines an abstract interface that all packets transmitted using AzNetworking must conform to. While there are + //! a number of core packets used internally by AzNetworking, it is fully possible for end-users to define their own custom + //! packets using this interface. PacketType should be distinct, and should be greater than + //! AzNetworking::CorePackets::MAX. The Serialize method allows the IPacket to be used by an + //! ISerializer to move data between hosts safely and efficiently. + //! + //! For more information on the packet format and best practices for extending the packet system, read + //! [Networking Packets](http://docs.o3de.org/docs/user-guide/networking/packets) on the O3DE documentation site. class IPacket { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h index 750b24befb..f51a959415 100644 --- a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h +++ b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h @@ -28,6 +28,19 @@ namespace AzNetworking //! @class IPacketHeader //! @brief A packet header that lets us deduce packet type for any incoming packet. + //! + //! IPacketHeader defines an abstract interface for a descriptor of all AzNetworking::IPacket sent through AzNetworking. The + //! PacketHeader is used to identify and describe the contents of a Packet so that transport logic can identify what + //! additional processing steps need to be taken (if any) and what type of Packet is being inspected. + //! + //! The PacketFlags portion of the header represents the first byte of the header. While it can be encrypted it is + //! otherwise not exposed to additional processing (such as an AzNetworking::ICompressor). PacketFlags are a bitfield use to provide up + //! front information about the state of the packet. Currently there is only one flag to indicate if the Packet is + //! compressed or not. + //! + //! The remainder of the header contains the PacketType and the PacketId. While the PacketFlags byte is exempt from most + //! additional forms of processing, the remainder of the header is not. + class IPacketHeader { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h b/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h index d083c7fc0e..999a229f65 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h +++ b/Code/Framework/AzNetworking/AzNetworking/Serialization/ISerializer.h @@ -27,6 +27,18 @@ namespace AzNetworking //! @class ISerializer //! @brief Interface class for all serializers to derive from. + //! + //! ISerializer defines an abstract interface for visiting an object hierarchy and performing operations upon that hierarchy, + //! typically reading from or writing data to the object hierarchy for reasons of persistence or network transmission. + //! + //! While the most common types of serializers are provided by the AzNetworking framework, users can implement custom + //! serializers and perform complex operations on any serializable structures. A few types native to AzNetworking, many of which + //! relate to packets, demonstrate this. + //! + //! Provided serializers include NetworkInputSerializer for writing an object model into a bytestream, NetworkOutputSerializer + //! for writing to an object model, TrackChangesSerializer which is used to efficiently serialize objects without incurring significant + //! copy or comparison overhead, and HashSerializer which can be used to generate a hash of all visited data which is important for + //! automated desync detection. class ISerializer { public: diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h index f2d65eeb63..ab9d743b63 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.h @@ -25,6 +25,44 @@ namespace AzNetworking //! @class TcpNetworkInterface //! @brief This class implements a TCP network interface. + //! + //! TcpNetworkInterface is an implementation of AzNetworking::INetworkInterface. + //! Unlike UDP, TCP implements a variety of transport features such as congestion + //! avoidance, flow control, and reliability. These features are valuable, but TCP + //! offers minimal configuration of them. This is why UdpNetworkInterface offers + //! similar features, but with greater flexibility in configuration. If your project doesn't + //! require the low latency of UDP, consider using TCP. + //! + //! ## Packet structure + //! + //! * Flags - A bitfield a receiving endpoint can quickly inspect to learn about configuration of a packet + //! * Header - Details the type of packet and other information related to reliability + //! * Payload - The actual serialized content of the packet + //! + //! For more information, read [Networking Packets](http://docs.o3de.org/docs/user-guide/networking/packets) in the O3DE documentation. + //! + //! ## Reliability + //! + //! TCP packets can only be sent reliably. This is a feature of TCP itself. + //! + //! ## Fragmentation + //! + //! TCP implements fragmentation under the hood. Consumers of TCP packets will never + //! need to worry about reconstructing the contents over multiple transmissions. + //! + //! ## Compression + //! + //! Compression here refers to content insensitive compression using libraries like + //! LZ4. If enabled, the target payload is run through the compressor and replaces + //! the original payload if it's in fact smaller. To tell if compression is enabled + //! on a given packet, we operate on a bit in the packet's Flags. The Sender writes + //! this bit while the Receiver checks it to see if a packet needs to be + //! decompressed. + //! + //! ## Encryption + //! + //! AzNetworking uses the [OpenSSL](https://www.openssl.org/) library to implement TLS encryption. If enabled, + //! the O3DE network layer handles the OpenSSL handshake under the hood using provided certificates. class TcpNetworkInterface final : public INetworkInterface { diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h index dda15c421a..9d44212ea7 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.h @@ -27,12 +27,58 @@ namespace AzNetworking class IConnectionListener; class ICompressor; - // 20 byte IPv4 header + 8 byte UDP header - static const uint32_t UdpPacketHeaderSize = 20 + 8; - static const uint32_t DtlsPacketHeaderSize = 13; // DTLS1_RT_HEADER_LENGTH + static const uint32_t UdpPacketHeaderSize = 20 + 8; //!< 20 byte IPv4 header + 8 byte UDP header + static const uint32_t DtlsPacketHeaderSize = 13; //!< DTLS1_RT_HEADER_LENGTH //! @class UdpNetworkInterface //! @brief This class implements a UDP network interface. + //! + //! UdpNetworkInterface is an implementation of AzNetworking::INetworkInterface. Since UDP is a very bare bones protocol, + //! the Open 3D Engine implementation has to provide significantly more than its TCP counterpart (since TCP implements a + //! significant number of reliability features.) + //! + //! When sent through UDP, a packet can have additional actions performed on it depending on which features are enabled and + //! configured. Each feature listed in this description is in the order a packet will see them on Send. + //! + //! ### Packet structure + //! + //! The general structure of a UDP packet is: + //! + //! * Flags - A bitfield a receiving endpoint can quickly inspect to learn about configuration of a packet + //! * Header - Details the type of packet and other information related to reliability + //! * Payload - The actual serialized content of the packet + //! + //! For more information, read [Networking Packets](http://docs.o3de.org/docs/user-guide/networking/packets) in the O3DE documentation. + //! + //! ### Reliability + //! + //! UDP packets can be sent reliably or unreliably. Reliably sent packets are registered for tracking first. This causes the + //! reliable packet to be resent if a timeout on the packet is reached. Once the packet is acknowledged, the packet is + //! unregistered. + //! + //! ### Fragmentation + //! + //! If the raw packet size exceeds the configured maximum transmission unit (MTU) then the packet is broken into + //! multiple reliable fragments to avoid fragmentation at the routing level. Fragments are always reliable so the original + //! packet can be reconstructed. Operations that alter the payload generally follow this step so that they can be + //! separately applied to the Fragments in addition to not being applied to both the original and Fragments. + //! + //! ### Compression + //! + //! Compression here refers to content insensitive compression using libraries like LZ4. If enabled, the target payload is + //! run through the compressor and replaces the original payload if it's in fact smaller. To tell if compression is enabled + //! on a given packet, we operate on a bit in the packet's Flags. The Sender writes this bit while the Receiver checks it to + //! see if a packet needs to be decompressed. + //! + //! O3DE could potentially move from over MTU to under with compression, and the UDP interface doesn't check for this. Detecting a change + //! that would reduce the number of fragmented packets would require pre-emptively compressing payloads to tell if that change happened, + //! which could potentially lead to a lot of unnecessary calls to the compressor. + //! + //! ### Encryption + //! + //! AzNetworking uses the [OpenSSL](https://www.openssl.org/) library to implement Datagram Layer Transport Security (DTLS) encryption + //! on UDP traffic. Encryption operates as described in [O3DE Networking Encryption](http://docs.o3de.org/docs/user-guide/networking/encryption) + //! on the documentation website. Once both endpoints have completed their handshake, all traffic is expected to be fully encrypted. class UdpNetworkInterface final : public INetworkInterface { diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Images/Menu/helpers.svg b/Code/Framework/AzQtComponents/AzQtComponents/Images/Menu/helpers.svg new file mode 100644 index 0000000000..e782a7066a --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Images/Menu/helpers.svg @@ -0,0 +1,24 @@ + + + Helpers Icon + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Images/Menu/menu.svg b/Code/Framework/AzQtComponents/AzQtComponents/Images/Menu/menu.svg new file mode 100644 index 0000000000..e97da32e09 --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Images/Menu/menu.svg @@ -0,0 +1,11 @@ + + + Buttons / Dropdown button with Icon / no arrow + + + + + + + + \ No newline at end of file diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Images/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Images/resources.qrc index cc66558367..74610dca90 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Images/resources.qrc +++ b/Code/Framework/AzQtComponents/AzQtComponents/Images/resources.qrc @@ -28,5 +28,7 @@ Menu/script_canvas_editor.svg Menu/trackview_editor.svg Menu/ui_editor.svg + Menu/menu.svg + Menu/helpers.svg diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 336b56653b..1172fc7162 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -524,8 +524,6 @@ namespace AzToolsFramework rootSpawnableIndex = m_playInEditorData.m_assets.size(); } - LoadReferencedAssets(product.GetReferencedAssets()); - AZ::Data::AssetInfo info; info.m_assetId = product.GetAsset().GetId(); info.m_assetType = product.GetAssetType(); @@ -534,6 +532,19 @@ namespace AzToolsFramework AZ::Data::AssetCatalogRequestBus::Broadcast( &AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, info.m_assetId, info); m_playInEditorData.m_assets.emplace_back(product.ReleaseAsset().release(), AZ::Data::AssetLoadBehavior::Default); + + // Ensure the product asset is registered with the AssetManager + // Hold on to the returned asset to keep ref count alive until we assign it the latest data + AZ::Data::Asset asset = + AZ::Data::AssetManager::Instance().FindOrCreateAsset(info.m_assetId, info.m_assetType, AZ::Data::AssetLoadBehavior::Default); + + // Update the asset registered in the AssetManager with the data of our product from the Prefab Processor + AZ::Data::AssetManager::Instance().AssignAssetData(m_playInEditorData.m_assets.back()); + } + + for (auto& product : context.GetProcessedObjects()) + { + LoadReferencedAssets(product.GetReferencedAssets()); } // make sure that PRE_NOTIFY assets get their notify before we activate, so that we can preserve the order of diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp index e5179f4229..123b31ff61 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.cpp @@ -326,6 +326,16 @@ namespace AzToolsFramework return *(m_nestedInstances[newInstanceAlias] = std::move(instance)); } + void Instance::DetachNestedInstances(const AZStd::function)>& callback) + { + for (auto&& [instanceAlias, instance] : m_nestedInstances) + { + instance->m_parent = nullptr; + callback(AZStd::move(instance)); + } + m_nestedInstances.clear(); + } + AZStd::unique_ptr Instance::DetachNestedInstance(const InstanceAlias& instanceAlias) { AZStd::unique_ptr removedNestedInstance; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h index 9d3ae31796..9fba839e1e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/Instance.h @@ -103,6 +103,7 @@ namespace AzToolsFramework Instance& AddInstance(AZStd::unique_ptr instance); Instance& AddInstance(AZStd::unique_ptr instance, InstanceAlias instanceAlias); AZStd::unique_ptr DetachNestedInstance(const InstanceAlias& instanceAlias); + void DetachNestedInstances(const AZStd::function)>& callback); /** * Gets the aliases for the entities in the Instance DOM. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp index 44dff93cb5..54baeb3f66 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp @@ -151,6 +151,10 @@ namespace AzToolsFramework return InvalidTemplateId; } + // Add or replace the Source parameter in the dom + PrefabDomPath sourcePath = PrefabDomPath((AZStd::string("/") + PrefabDomUtils::SourceName).c_str()); + sourcePath.Set(readPrefabFileResult.GetValue(), relativePath.Native().c_str()); + // Create new Template with the Prefab DOM. TemplateId newTemplateId = m_prefabSystemComponentInterface->AddTemplate(relativePath, readPrefabFileResult.TakeValue()); if (newTemplateId == InvalidTemplateId) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 189cb9d161..9038bfc173 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -922,8 +922,8 @@ namespace AzToolsFramework return AZ::Failure(AZStd::string("Failed to duplicate : Couldn't get a valid owning instance for the common root entity of the entities provided.")); } - // If the first entity id is a container entity id, then we need to mark its parent as the common owning instance because you - // cannot duplicate an instance from itself. + // If the first entity id is a container entity id, then we need to mark its parent as the common owning instance + // This is because containers, despite representing the nested instance in the parent, are owned by the child. if (commonOwningInstance->get().GetContainerEntityId() == firstEntityIdToDuplicate) { commonOwningInstance = commonOwningInstance->get().GetParentInstance(); @@ -967,17 +967,18 @@ namespace AzToolsFramework // Duplicate any nested entities and instances as requested AZStd::unordered_map newInstanceAliasToOldInstanceMap; + AZStd::unordered_map duplicateEntityAliasMap; DuplicateNestedEntitiesInInstance(commonOwningInstance->get(), - entities, instanceDomAfter, duplicatedEntityAndInstanceIds); - DuplicateNestedInstancesInInstance(commonOwningInstance->get(), - instances, instanceDomAfter, duplicatedEntityAndInstanceIds, - newInstanceAliasToOldInstanceMap); + entities, instanceDomAfter, duplicatedEntityAndInstanceIds, duplicateEntityAliasMap); PrefabUndoInstance* command = aznew PrefabUndoInstance("Entity/Instance duplication"); command->SetParent(undoBatch.GetUndoBatch()); command->Capture(instanceDomBefore, instanceDomAfter, commonOwningInstance->get().GetTemplateId()); command->Redo(); + DuplicateNestedInstancesInInstance(commonOwningInstance->get(), + instances, instanceDomAfter, duplicatedEntityAndInstanceIds, newInstanceAliasToOldInstanceMap); + // Create links for our duplicated instances (if any were duplicated) for (auto [newInstanceAlias, oldInstance] : newInstanceAliasToOldInstanceMap) { @@ -995,8 +996,35 @@ namespace AzToolsFramework PrefabDom linkPatchesCopy; linkPatchesCopy.CopyFrom(linkPatches->get(), linkPatchesCopy.GetAllocator()); - m_prefabSystemComponentInterface->CreateLink( - commonOwningInstance->get().GetTemplateId(), oldInstance->GetTemplateId(), newInstanceAlias, linkPatchesCopy); + // If the instance was duplicated as part of an ancestor's nested hierarchy, the container's parent patch + // will need to be refreshed to point to the new duplicated parent entity + auto oldInstanceContainerEntityId = oldInstance->GetContainerEntityId(); + AZ_Assert(oldInstanceContainerEntityId.IsValid(), "Instance returned invalid Container Entity Id"); + + AZ::EntityId previousParentEntityId; + AZ::TransformBus::EventResult(previousParentEntityId, oldInstanceContainerEntityId, &AZ::TransformBus::Events::GetParentId); + + if (previousParentEntityId.IsValid() && AZStd::find(duplicatedEntityAndInstanceIds.begin(), duplicatedEntityAndInstanceIds.end(), previousParentEntityId)) + { + auto oldParentAlias = commonOwningInstance->get().GetEntityAlias(previousParentEntityId); + if (oldParentAlias.has_value() && duplicateEntityAliasMap.contains(oldParentAlias->get())) + { + // Get the dom into a QString for search/replace purposes + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + linkPatchesCopy.Accept(writer); + + QString linkPatchesString(buffer.GetString()); + + ReplaceOldAliases(linkPatchesString, oldParentAlias->get(), duplicateEntityAliasMap[oldParentAlias->get()]); + + linkPatchesCopy.Parse(linkPatchesString.toUtf8().constData()); + } + } + + PrefabUndoHelpers::CreateLink( + oldInstance->GetTemplateId(), commonOwningInstance->get().GetTemplateId(), + AZStd::move(linkPatchesCopy), newInstanceAlias, undoBatch.GetUndoBatch()); } // Select the duplicated entities/instances @@ -1211,25 +1239,23 @@ namespace AzToolsFramework const auto instanceTemplateId = instancePtr->GetTemplateId(); auto parentContainerEntityId = parentInstance.GetContainerEntityId(); - instancePtr->GetNestedInstances( - [&](AZStd::unique_ptr& nestedInstancePtr) - { - //get previous link patch - auto linkRef = m_prefabSystemComponentInterface->FindLink(nestedInstancePtr->GetLinkId()); - PrefabDomValueReference linkPatches = linkRef->get().GetLinkPatches(); - AZ_Assert( - linkPatches.has_value(), "Unable to get patches on link with id '%llu' during prefab creation.", - nestedInstancePtr->GetLinkId()); - PrefabDom linkPatchesCopy; - linkPatchesCopy.CopyFrom(linkPatches->get(), linkPatchesCopy.GetAllocator()); - - RemoveLink(nestedInstancePtr, instanceTemplateId, undoBatch.GetUndoBatch()); + instancePtr->DetachNestedInstances( + [&](AZStd::unique_ptr detachedNestedInstance) + { + PrefabDom& nestedInstanceTemplateDom = + m_prefabSystemComponentInterface->FindTemplateDom(detachedNestedInstance->GetTemplateId()); - UpdateLinkPatchesWithNewEntityAliases(linkPatchesCopy, oldEntityAliases, parentInstance); + Instance& nestedInstanceUnderNewParent = parentInstance.AddInstance(AZStd::move(detachedNestedInstance)); + + PrefabDom nestedInstanceDomUnderNewParent; + m_instanceToTemplateInterface->GenerateDomForInstance( + nestedInstanceDomUnderNewParent, nestedInstanceUnderNewParent); + PrefabDom reparentPatch; + m_instanceToTemplateInterface->GeneratePatch( + reparentPatch, nestedInstanceTemplateDom, nestedInstanceDomUnderNewParent); - CreateLink(*nestedInstancePtr, parentTemplateId, undoBatch.GetUndoBatch(), - AZStd::move(linkPatchesCopy), true); + CreateLink(nestedInstanceUnderNewParent, parentTemplateId, undoBatch.GetUndoBatch(), AZStd::move(reparentPatch), true); }); } @@ -1509,14 +1535,13 @@ namespace AzToolsFramework void PrefabPublicHandler::DuplicateNestedEntitiesInInstance(Instance& commonOwningInstance, const AZStd::vector& entities, PrefabDom& domToAddDuplicatedEntitiesUnder, - EntityIdList& duplicatedEntityIds) + EntityIdList& duplicatedEntityIds, AZStd::unordered_map& oldAliasToNewAliasMap) { if (entities.empty()) { return; } - AZStd::unordered_map oldAliasToNewAliasMap; AZStd::unordered_map aliasToEntityDomMap; for (AZ::Entity* entity : entities) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 65e1391722..fc5906c80e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -87,7 +87,7 @@ namespace AzToolsFramework */ void DuplicateNestedEntitiesInInstance(Instance& commonOwningInstance, const AZStd::vector& entities, PrefabDom& domToAddDuplicatedEntitiesUnder, - EntityIdList& duplicatedEntityIds); + EntityIdList& duplicatedEntityIds, AZStd::unordered_map& oldAliasToNewAliasMap); /** * Duplicate a list of instances owned by a common owning instance by directly * copying/modifying their entries in the instance DOM diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp index 0511ee1f13..592fc309d5 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Template/Template.cpp @@ -207,6 +207,10 @@ namespace AzToolsFramework instanceValue->CopyFrom(linkDom, m_prefabDom.GetAllocator()); } + // Remove Source parameter from the dom. It will be added on file load, and should not be stored to disk. + PrefabDomPath sourcePath = PrefabDomPath((AZStd::string("/") + PrefabDomUtils::SourceName).c_str()); + sourcePath.Erase(output); + return true; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp index f72de82f36..4cd18cbc91 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -57,6 +58,13 @@ namespace AzToolsFramework ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly); } } + + if (auto behaviorContext = azrtti_cast(context)) + { + behaviorContext->ConstantProperty("EditorNonUniformScaleComponentTypeId", BehaviorConstant(EditorNonUniformScaleComponent::RTTI_Type())) + ->Attribute(AZ::Script::Attributes::Module, "editor") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation); + } } void EditorNonUniformScaleComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h index d202735522..b4d0342c44 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h @@ -214,7 +214,11 @@ namespace AzToolsFramework class ViewportSettingNotifications { public: - virtual void OnGridSnappingChanged(bool enabled) = 0; + virtual void OnGridSnappingChanged([[maybe_unused]] bool enabled) {} + virtual void OnDrawHelpersChanged([[maybe_unused]] bool enabled) {} + + protected: + ViewportSettingNotifications() = default; }; using ViewportSettingsNotificationBus = AZ::EBus; diff --git a/Code/Sandbox/Editor/AzAssetBrowser/AzAssetBrowserRequestHandler.cpp b/Code/Sandbox/Editor/AzAssetBrowser/AzAssetBrowserRequestHandler.cpp index e0ba106875..ce29b81a5c 100644 --- a/Code/Sandbox/Editor/AzAssetBrowser/AzAssetBrowserRequestHandler.cpp +++ b/Code/Sandbox/Editor/AzAssetBrowser/AzAssetBrowserRequestHandler.cpp @@ -56,7 +56,8 @@ namespace AzAssetBrowserRequestHandlerPrivate using namespace AzToolsFramework; using namespace AzToolsFramework::AssetBrowser; // return true ONLY if we can handle the drop request in the viewport. - bool CanSpawnEntityForProduct(const ProductAssetBrowserEntry* product) + bool CanSpawnEntityForProduct(const ProductAssetBrowserEntry* product, + AZStd::optional> optionalProductAssetTypes = AZStd::nullopt) { if (!product) { @@ -70,7 +71,6 @@ namespace AzAssetBrowserRequestHandlerPrivate bool canCreateComponent = false; AZ::AssetTypeInfoBus::EventResult(canCreateComponent, product->GetAssetType(), &AZ::AssetTypeInfo::CanCreateComponent, product->GetAssetId()); - if (!canCreateComponent) { return false; @@ -78,16 +78,25 @@ namespace AzAssetBrowserRequestHandlerPrivate AZ::Uuid componentTypeId = AZ::Uuid::CreateNull(); AZ::AssetTypeInfoBus::EventResult(componentTypeId, product->GetAssetType(), &AZ::AssetTypeInfo::GetComponentTypeId); - - if (!componentTypeId.IsNull()) + if (componentTypeId.IsNull()) { // we have a component type that handles this asset. - return true; + return false; + } + + if (optionalProductAssetTypes.has_value()) + { + bool hasConflictingProducts = false; + AZ::AssetTypeInfoBus::EventResult(hasConflictingProducts, product->GetAssetType(), &AZ::AssetTypeInfo::HasConflictingProducts, optionalProductAssetTypes.value()); + if (hasConflictingProducts) + { + return false; + } } // additional operations can be added here. - return false; + return true; } void SpawnEntityAtPoint(const ProductAssetBrowserEntry* product, AzQtComponents::ViewportDragContext* viewportDragContext, EntityIdList& spawnList, AzFramework::SliceInstantiationTicket& spawnTicket) @@ -511,9 +520,16 @@ void AzAssetBrowserRequestHandler::Drop(QDropEvent* event, AzQtComponents::DragA } // Handle products + AZStd::vector productAssetTypes; + productAssetTypes.reserve(products.size()); + for (const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* entry : products) + { + productAssetTypes.emplace_back(entry->GetAssetType()); + } + for (const ProductAssetBrowserEntry* product : products) { - if (CanSpawnEntityForProduct(product)) + if (CanSpawnEntityForProduct(product, productAssetTypes)) { SpawnEntityAtPoint(product, viewportDragContext, spawnedEntities, spawnTicket); } diff --git a/Code/Sandbox/Editor/CMakeLists.txt b/Code/Sandbox/Editor/CMakeLists.txt index 51620c6e37..6a5fb7c6c8 100644 --- a/Code/Sandbox/Editor/CMakeLists.txt +++ b/Code/Sandbox/Editor/CMakeLists.txt @@ -128,6 +128,7 @@ ly_add_target( Legacy::EditorCore RUNTIME_DEPENDENCIES Gem::AtomViewportDisplayInfo + Legacy::EditorCommon ) ly_add_source_properties( SOURCES CryEdit.cpp diff --git a/Code/Sandbox/Editor/EditorVersion.rc b/Code/Sandbox/Editor/EditorVersion.rc index a2c159907c..1527bda8cc 100644 --- a/Code/Sandbox/Editor/EditorVersion.rc +++ b/Code/Sandbox/Editor/EditorVersion.rc @@ -33,13 +33,13 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileDescription", "Lumberyard Editor" + VALUE "CompanyName", "Open 3D Foundation" + VALUE "FileDescription", "O3DE Editor" VALUE "FileVersion", "0.1.0.1" VALUE "InternalName", "Editor" VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." VALUE "OriginalFilename", "Editor.exe" - VALUE "ProductName", "Lumberyard Editor" + VALUE "ProductName", "O3DE Editor" VALUE "ProductVersion", "0.1.0.1" END END diff --git a/Code/Sandbox/Editor/Util/ImageHDR.cpp b/Code/Sandbox/Editor/Util/ImageHDR.cpp deleted file mode 100644 index d0cd5ab055..0000000000 --- a/Code/Sandbox/Editor/Util/ImageHDR.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "EditorDefs.h" - -#include "ImageHDR.h" - -// Editor -#include "Util/Image.h" - -// We need globals because of the callbacks (they don't allow us to pass state) -static CryMutex globalFileMutex; -static size_t globalFileBufferOffset = 0; -static size_t globalFileBufferSize = 0; - -static char* fgets(char* _Buf, [[maybe_unused]] int _MaxCount, CCryFile* _File) -{ - while (globalFileBufferOffset < globalFileBufferSize) - { - char chr; - - _File->ReadRaw(&chr, 1); - globalFileBufferOffset++; - - *_Buf++ = chr; - if (chr == '\n') - { - break; - } - } - - *_Buf = '\0'; - return _Buf; -} - -static size_t fread(void* _DstBuf, size_t _ElementSize, size_t _Count, CCryFile* _File) -{ - size_t cpy = min(_ElementSize * _Count, globalFileBufferSize - globalFileBufferOffset); - - _File->ReadRaw(_DstBuf, cpy); - globalFileBufferOffset += cpy; - - return cpy; -} - -/* THIS CODE CARRIES NO GUARANTEE OF USABILITY OR FITNESS FOR ANY PURPOSE. - * WHILE THE AUTHORS HAVE TRIED TO ENSURE THE PROGRAM WORKS CORRECTLY, - * IT IS STRICTLY USE AT YOUR OWN RISK. */ - -/* utility for reading and writing Ward's rgbe image format. - See rgbe.txt file for more details. -*/ - -#include - -typedef struct -{ - int valid; /* indicate which fields are valid */ - char programtype[16]; /* listed at beginning of file to identify it - * after "#?". defaults to "RGBE" */ - float gamma; /* image has already been gamma corrected with - * given gamma. defaults to 1.0 (no correction) */ - float exposure; /* a value of 1.0 in an image corresponds to - * watts/steradian/m^2. - * defaults to 1.0 */ - char instructions[512]; -} rgbe_header_info; - -/* flags indicating which fields in an rgbe_header_info are valid */ -#define RGBE_VALID_PROGRAMTYPE 0x01 -#define RGBE_VALID_GAMMA 0x02 -#define RGBE_VALID_EXPOSURE 0x04 -#define RGBE_VALID_INSTRUCTIONS 0x08 - -/* return codes for rgbe routines */ -#define RGBE_RETURN_SUCCESS 0 -#define RGBE_RETURN_FAILURE -1 - -/* read or write headers */ -/* you may set rgbe_header_info to null if you want to */ -int RGBE_ReadHeader(CCryFile* fp, uint32* width, uint32* height, rgbe_header_info* info); - -/* read or write pixels */ -/* can read or write pixels in chunks of any size including single pixels*/ -int RGBE_ReadPixels(CCryFile* fp, float* data, int numpixels); - -/* read or write run length encoded files */ -/* must be called to read or write whole scanlines */ -int RGBE_ReadPixels_RLE(CCryFile* fp, float* data, uint32 scanline_width, - uint32 num_scanlines); - -/* THIS CODE CARRIES NO GUARANTEE OF USABILITY OR FITNESS FOR ANY PURPOSE. - * WHILE THE AUTHORS HAVE TRIED TO ENSURE THE PROGRAM WORKS CORRECTLY, - * IT IS STRICTLY USE AT YOUR OWN RISK. */ - -#include -#include -#include - -/* This file contains code to read and write four byte rgbe file format - developed by Greg Ward. It handles the conversions between rgbe and - pixels consisting of floats. The data is assumed to be an array of floats. - By default there are three floats per pixel in the order red, green, blue. - (RGBE_DATA_??? values control this.) Only the mimimal header reading and - writing is implemented. Each routine does error checking and will return - a status value as defined below. This code is intended as a skeleton so - feel free to modify it to suit your needs. - - (Place notice here if you modified the code.) - posted to http://www.graphics.cornell.edu/~bjw/ - written by Bruce Walter (bjw@graphics.cornell.edu) 5/26/95 - based on code written by Greg Ward -*/ - -#ifndef INLINE -#ifdef _CPLUSPLUS -/* define if your compiler understands inline commands */ -#define INLINE inline -#else -#define INLINE -#endif -#endif - -/* offsets to red, green, and blue components in a data (float) pixel */ -#define RGBE_DATA_RED 0 -#define RGBE_DATA_GREEN 1 -#define RGBE_DATA_BLUE 2 -#define RGBE_DATA_ALPHA 3 -/* number of floats per pixel */ -#define RGBE_DATA_SIZE 4 - -enum rgbe_error_codes -{ - rgbe_read_error, - rgbe_write_error, - rgbe_format_error, - rgbe_memory_error, -}; - -/* default error routine. change this to change error handling */ -static int rgbe_error(int rgbe_error_code, const char* msg) -{ - switch (rgbe_error_code) - { - case rgbe_read_error: - CLogFile::FormatLine("RGBE read error"); - break; - case rgbe_write_error: - CLogFile::FormatLine("RGBE write error"); - break; - case rgbe_format_error: - CLogFile::FormatLine("RGBE bad file format: %s\n", msg); - break; - default: - case rgbe_memory_error: - CLogFile::FormatLine("RGBE error: %s\n", msg); - } - return RGBE_RETURN_FAILURE; -} - -/* standard conversion from rgbe to float pixels */ -/* note: Ward uses ldexp(col+0.5,exp-(128+8)). However we wanted pixels */ -/* in the range [0,1] to map back into the range [0,1]. */ -static INLINE void -rgbe2type(char* red, char* green, char* blue, unsigned char rgbe[4]) -{ - float f; - - if (rgbe[3]) /*nonzero pixel*/ - { - f = ldexp(1.0f, rgbe[3] - (int)(128 + 8)) * 255.0f; - *red = (unsigned char) max(0.0f, min(rgbe[0] * f, 255.0f)); - *green = (unsigned char) max(0.0f, min(rgbe[1] * f, 255.0f)); - *blue = (unsigned char) max(0.0f, min(rgbe[2] * f, 255.0f)); - } - else - { - *red = *green = *blue = 0; - } -} - -/* minimal header reading. modify if you want to parse more information */ -int RGBE_ReadHeader(CCryFile* fp, uint32* width, uint32* height, rgbe_header_info* info) -{ - char buf[512]; - int found_format; - float tempf; - int i; - - found_format = 0; - if (info) - { - info->valid = 0; - info->programtype[0] = 0; - info->gamma = info->exposure = 1.0; - } - if (fgets(buf, sizeof(buf) / sizeof(buf[0]), fp) == NULL) - { - return rgbe_error(rgbe_read_error, NULL); - } - if ((buf[0] != '#') || (buf[1] != '?')) - { - /* if you want to require the magic token then uncomment the next line */ - /*return rgbe_error(rgbe_format_error,"bad initial token"); */ - } - else if (info) - { - info->valid |= RGBE_VALID_PROGRAMTYPE; - for (i = 0; i < sizeof(info->programtype) - 1; i++) - { - if ((buf[i + 2] == 0) || isspace(buf[i + 2])) - { - break; - } - info->programtype[i] = buf[i + 2]; - } - info->programtype[i] = 0; - if (fgets(buf, sizeof(buf) / sizeof(buf[0]), fp) == 0) - { - return rgbe_error(rgbe_read_error, NULL); - } - } - for (;; ) - { - if ((buf[0] == 0) || (buf[0] == '\n')) - { - return rgbe_error(rgbe_format_error, "no FORMAT specifier found"); - } - else if (strcmp(buf, "FORMAT=32-bit_rle_rgbe\n") == 0) - { - break; /* format found so break out of loop */ - } - else if (info && (azsscanf(buf, "GAMMA=%g", &tempf) == 1)) - { - info->gamma = tempf; - info->valid |= RGBE_VALID_GAMMA; - } - else if (info && (azsscanf(buf, "EXPOSURE=%g", &tempf) == 1)) - { - info->exposure = tempf; - info->valid |= RGBE_VALID_EXPOSURE; - } - else if (info && (!strncmp(buf, "INSTRUCTIONS=", 13))) - { - info->valid |= RGBE_VALID_INSTRUCTIONS; - for (i = 0; i < sizeof(info->instructions) - 1; i++) - { - if ((buf[i + 13] == 0) || isspace(buf[i + 13])) - { - break; - } - info->instructions[i] = buf[i + 13]; - } - } - if (fgets(buf, sizeof(buf) / sizeof(buf[0]), fp) == 0) - { - return rgbe_error(rgbe_read_error, NULL); - } - } - if (fgets(buf, sizeof(buf) / sizeof(buf[0]), fp) == 0) - { - return rgbe_error(rgbe_read_error, NULL); - } - if (strcmp(buf, "\n") != 0) - { - return rgbe_error(rgbe_format_error, - "missing blank line after FORMAT specifier"); - } - if (fgets(buf, sizeof(buf) / sizeof(buf[0]), fp) == 0) - { - return rgbe_error(rgbe_read_error, NULL); - } - if (azsscanf(buf, "-Y %d +X %d", height, width) < 2) - { - return rgbe_error(rgbe_format_error, "missing image size specifier"); - } - return RGBE_RETURN_SUCCESS; -} - -/* simple read routine. will not correctly handle run length encoding */ -int RGBE_ReadPixels(CCryFile* fp, char* data, int numpixels) -{ - unsigned char rgbe[4]; - - while (numpixels-- > 0) - { - if (fread(rgbe, sizeof(rgbe), 1, fp) < 1) - { - return rgbe_error(rgbe_read_error, NULL); - } - rgbe2type(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], - &data[RGBE_DATA_BLUE], rgbe); - data[RGBE_DATA_ALPHA] = 0.0f; - data += RGBE_DATA_SIZE; - } - return RGBE_RETURN_SUCCESS; -} - -int RGBE_ReadPixels_RLE(CCryFile* fp, char* data, uint32 scanline_width, - uint32 num_scanlines) -{ - unsigned char rgbe[4], * scanline_buffer, * ptr, * ptr_end; - int i, count; - unsigned char buf[2]; - - if ((scanline_width < 8) || (scanline_width > 0x7fff)) - { - /* run length encoding is not allowed so read flat*/ - return RGBE_ReadPixels(fp, data, scanline_width * num_scanlines); - } - scanline_buffer = NULL; - /* read in each successive scanline */ - while (num_scanlines > 0) - { - if (fread(rgbe, sizeof(rgbe), 1, fp) < 1) - { - free(scanline_buffer); - return rgbe_error(rgbe_read_error, NULL); - } - if ((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) - { - /* this file is not run length encoded */ - rgbe2type(&data[0], &data[1], &data[2], rgbe); - data += RGBE_DATA_SIZE; - free(scanline_buffer); - return RGBE_ReadPixels(fp, data, scanline_width * num_scanlines - 1); - } - if ((((int)rgbe[2]) << 8 | rgbe[3]) != scanline_width) - { - free(scanline_buffer); - return rgbe_error(rgbe_format_error, "wrong scanline width"); - } - if (scanline_buffer == NULL) - { - scanline_buffer = (unsigned char*) - malloc(sizeof(unsigned char) * 4 * scanline_width); - } - if (scanline_buffer == NULL) - { - return rgbe_error(rgbe_memory_error, "unable to allocate buffer space"); - } - - ptr = &scanline_buffer[0]; - /* read each of the four channels for the scanline into the buffer */ - for (i = 0; i < 4; i++) - { - ptr_end = &scanline_buffer[(i + 1) * scanline_width]; - while (ptr < ptr_end) - { - if (fread(buf, sizeof(buf[0]) * 2, 1, fp) < 1) - { - free(scanline_buffer); - return rgbe_error(rgbe_read_error, NULL); - } - if (buf[0] > 128) - { - /* a run of the same value */ - count = buf[0] - 128; - if ((count == 0) || (count > ptr_end - ptr)) - { - free(scanline_buffer); - return rgbe_error(rgbe_format_error, "bad scanline data"); - } - while (count-- > 0) - { - *ptr++ = buf[1]; - } - } - else - { - /* a non-run */ - count = buf[0]; - if ((count == 0) || (count > ptr_end - ptr)) - { - free(scanline_buffer); - return rgbe_error(rgbe_format_error, "bad scanline data"); - } - *ptr++ = buf[1]; - if (--count > 0) - { - if (fread(ptr, sizeof(*ptr) * count, 1, fp) < 1) - { - free(scanline_buffer); - return rgbe_error(rgbe_read_error, NULL); - } - ptr += count; - } - } - } - } - /* now convert data from buffer into floats */ - for (i = 0; i < scanline_width; i++) - { - rgbe[0] = scanline_buffer[i]; - rgbe[1] = scanline_buffer[i + scanline_width]; - rgbe[2] = scanline_buffer[i + 2 * scanline_width]; - rgbe[3] = scanline_buffer[i + 3 * scanline_width]; - rgbe2type(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], - &data[RGBE_DATA_BLUE], rgbe); - data[RGBE_DATA_ALPHA] = 0.0f; - data += RGBE_DATA_SIZE; - } - num_scanlines--; - } - free(scanline_buffer); - return RGBE_RETURN_SUCCESS; -} - -/////////////////////////////////////////////////////////////////////////////////// - -bool CImageHDR::Load(const QString& fileName, CImageEx& outImage) -{ - CCryFile file; - if (!file.Open(fileName.toUtf8().data(), "rb")) - { - CLogFile::FormatLine("File not found %s", fileName.toUtf8().data()); - return false; - } - - // We use some global variables in callbacks, so we must - // prevent multithread access to the data - CryAutoLock tifAutoLock(globalFileMutex); - - globalFileBufferSize = file.GetLength(); - globalFileBufferOffset = 0; - - bool bRet = false; - uint32 dwWidth, dwHeight; - rgbe_header_info info; - - if (RGBE_RETURN_SUCCESS == RGBE_ReadHeader(&file, &dwWidth, &dwHeight, &info)) - { - if (outImage.Allocate(dwWidth, dwHeight)) - { - char* pDst = (char*)outImage.GetData(); - - if (RGBE_RETURN_SUCCESS == RGBE_ReadPixels_RLE(&file, (char*)pDst, dwWidth, dwHeight)) - { - bRet = true; - } - } - } - - if (!bRet) - { - outImage.Detach(); - } - - return bRet; -} diff --git a/Code/Sandbox/Editor/Util/ImageHDR.h b/Code/Sandbox/Editor/Util/ImageHDR.h deleted file mode 100644 index 18e7e36b84..0000000000 --- a/Code/Sandbox/Editor/Util/ImageHDR.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -class CImageEx; - -class CImageHDR -{ -public: - bool Load(const QString& fileName, CImageEx& outImage); -}; diff --git a/Code/Sandbox/Editor/Util/ImageUtil.cpp b/Code/Sandbox/Editor/Util/ImageUtil.cpp index 874d74e9bb..74f07471d2 100644 --- a/Code/Sandbox/Editor/Util/ImageUtil.cpp +++ b/Code/Sandbox/Editor/Util/ImageUtil.cpp @@ -21,7 +21,6 @@ // Editor #include "Util/ImageGif.h" #include "Util/ImageTIF.h" -#include "Util/ImageHDR.h" ////////////////////////////////////////////////////////////////////////// bool CImageUtil::Save(const QString& strFileName, CImageEx& inImage) @@ -275,10 +274,6 @@ bool CImageUtil::LoadImage(const QString& fileName, CImageEx& image, bool* pQual { return CImageUtil::Load(fileName, image); } - else if (azstricmp(ext, ".hdr") == 0) - { - return CImageHDR().Load(fileName, image); - } else { return CImageUtil::Load(fileName, image); diff --git a/Code/Sandbox/Editor/ViewportTitleDlg.cpp b/Code/Sandbox/Editor/ViewportTitleDlg.cpp index 2c4b29773d..87469e6984 100644 --- a/Code/Sandbox/Editor/ViewportTitleDlg.cpp +++ b/Code/Sandbox/Editor/ViewportTitleDlg.cpp @@ -45,6 +45,7 @@ #include #include +#include AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING #include "ui_ViewportTitleDlg.h" @@ -57,13 +58,16 @@ inline namespace Helpers { void ToggleHelpers() { - GetIEditor()->GetDisplaySettings()->DisplayHelpers(!GetIEditor()->GetDisplaySettings()->IsDisplayHelpers()); + const bool newValue = !GetIEditor()->GetDisplaySettings()->IsDisplayHelpers(); + GetIEditor()->GetDisplaySettings()->DisplayHelpers(newValue); GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate); - if (GetIEditor()->GetDisplaySettings()->IsDisplayHelpers() == false) + if (newValue == false) { GetIEditor()->GetObjectManager()->SendEvent(EVENT_HIDE_HELPER); } + AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Broadcast( + &AzToolsFramework::ViewportInteraction::ViewportSettingNotifications::OnDrawHelpersChanged, newValue); } bool IsHelpersShown() @@ -126,6 +130,7 @@ CViewportTitleDlg::CViewportTitleDlg(QWidget* pParent) SetupCameraDropdownMenu(); SetupResolutionDropdownMenu(); SetupViewportInformationMenu(); + SetupHelpersButton(); SetupOverflowMenu(); Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequest, gSettings.bMuteAudio ? m_oMuteAudioRequest : m_oUnmuteAudioRequest); @@ -208,15 +213,16 @@ void CViewportTitleDlg::SetupViewportInformationMenu() } +void CViewportTitleDlg::SetupHelpersButton() +{ + connect(m_ui->m_helpers, &QToolButton::clicked, this, &CViewportTitleDlg::OnToggleHelpers); + m_ui->m_helpers->setChecked(Helpers::IsHelpersShown()); +} + void CViewportTitleDlg::SetupOverflowMenu() { // Setup the overflow menu QMenu* overFlowMenu = new QMenu(this); - m_debugHelpersAction = new QAction("Debug Helpers", overFlowMenu); - m_debugHelpersAction->setCheckable(true); - m_debugHelpersAction->setChecked(Helpers::IsHelpersShown()); - connect(m_debugHelpersAction, &QAction::triggered, this, &CViewportTitleDlg::OnToggleHelpers); - overFlowMenu->addAction(m_debugHelpersAction); m_audioMuteAction = new QAction("Mute Audio", overFlowMenu); connect(m_audioMuteAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedMuteAudio); @@ -330,7 +336,7 @@ void CViewportTitleDlg::OnMaximize() void CViewportTitleDlg::OnToggleHelpers() { Helpers::ToggleHelpers(); - m_debugHelpersAction->setChecked(Helpers::IsHelpersShown()); + m_ui->m_helpers->setChecked(Helpers::IsHelpersShown()); } void CViewportTitleDlg::SetNoViewportInfo() @@ -756,7 +762,7 @@ void CViewportTitleDlg::OnEditorNotifyEvent(EEditorNotifyEvent event) switch (event) { case eNotify_OnDisplayRenderUpdate: - m_debugHelpersAction->setChecked(Helpers::IsHelpersShown()); + m_ui->m_helpers->setChecked(Helpers::IsHelpersShown()); break; case eNotify_OnBeginGameMode: case eNotify_OnEndGameMode: diff --git a/Code/Sandbox/Editor/ViewportTitleDlg.h b/Code/Sandbox/Editor/ViewportTitleDlg.h index 7978277ce0..47622ff481 100644 --- a/Code/Sandbox/Editor/ViewportTitleDlg.h +++ b/Code/Sandbox/Editor/ViewportTitleDlg.h @@ -102,6 +102,7 @@ protected: void SetupResolutionDropdownMenu(); void SetupViewportInformationMenu(); void SetupOverflowMenu(); + void SetupHelpersButton(); QString m_title; @@ -172,7 +173,6 @@ protected: QAction* m_normalInformationAction = nullptr; QAction* m_fullInformationAction = nullptr; QAction* m_compactInformationAction = nullptr; - QAction* m_debugHelpersAction = nullptr; QAction* m_audioMuteAction = nullptr; QAction* m_enableVRAction = nullptr; QAction* m_enableGridSnappingAction = nullptr; diff --git a/Code/Sandbox/Editor/ViewportTitleDlg.ui b/Code/Sandbox/Editor/ViewportTitleDlg.ui index 2d547bfa99..7d8e9d50d4 100644 --- a/Code/Sandbox/Editor/ViewportTitleDlg.ui +++ b/Code/Sandbox/Editor/ViewportTitleDlg.ui @@ -81,6 +81,18 @@ + + + + + :/Menu/helpers.svg:/Menu/helpers.svg + + + + true + + + @@ -94,7 +106,7 @@ - :/stylesheet/img/UI20/menu-centered.svg:/stylesheet/img/UI20/menu-centered.svg + :/Menu/menu.svg:/Menu/menu.svg diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index 07333cf6d5..71d521b810 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -737,8 +737,6 @@ set(FILES Util/GeometryUtil.cpp Util/GuidUtil.cpp Util/GuidUtil.h - Util/ImageHDR.cpp - Util/ImageHDR.h Util/IObservable.h Util/IndexedFiles.cpp Util/IndexedFiles.h diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp index 25b58ab544..b81d013b87 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp @@ -255,7 +255,6 @@ namespace AZ { return AZStd::make_pair(animation, anim); } - Events::ProcessingResult AssImpAnimationImporter::ImportAnimation(AssImpSceneNodeAppendedContext& context) { AZ_TraceContext("Importer", "Animation"); @@ -447,7 +446,22 @@ namespace AZ return combinedAnimationResult.GetResult(); } - decltype(boneAnimations) parentFillerAnimations; + + AZStd::unordered_set boneList; + + for (int meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) + { + aiMesh* mesh = scene->mMeshes[meshIndex]; + + for (int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) + { + aiBone* bone = mesh->mBones[boneIndex]; + + boneList.insert(bone->mName.C_Str()); + } + } + + decltype(boneAnimations) fillerAnimations; // Go through all the animations and make sure we create animations for bones who's parents don't have an animation for (auto&& anim : boneAnimations) @@ -459,8 +473,8 @@ namespace AZ { if (!IsPivotNode(parent->mName)) { - if (boneAnimations.find(parent->mName.C_Str()) == boneAnimations.end() && - parentFillerAnimations.find(parent->mName.C_Str()) == parentFillerAnimations.end()) + if (!boneAnimations.contains(parent->mName.C_Str()) && + !fillerAnimations.contains(parent->mName.C_Str())) { // Create 1 key for each type that just copies the current transform ConsolidatedNodeAnim emptyAnimation; @@ -472,7 +486,7 @@ namespace AZ globalTransform.Decompose(scale, rotation, position); emptyAnimation.mNumRotationKeys = emptyAnimation.mNumPositionKeys = emptyAnimation.mNumScalingKeys = 1; - + emptyAnimation.m_ownedPositionKeys.emplace_back(0, position); emptyAnimation.mPositionKeys = emptyAnimation.m_ownedPositionKeys.data(); @@ -481,9 +495,9 @@ namespace AZ emptyAnimation.m_ownedScalingKeys.emplace_back(0, scale); emptyAnimation.mScalingKeys = emptyAnimation.m_ownedScalingKeys.data(); - - parentFillerAnimations.insert( - AZStd::make_pair(parent->mName.C_Str(), AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); + + fillerAnimations.insert(AZStd::make_pair( + parent->mName.C_Str(), AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); } } @@ -491,7 +505,7 @@ namespace AZ } } - boneAnimations.insert(AZStd::make_move_iterator(parentFillerAnimations.begin()), AZStd::make_move_iterator(parentFillerAnimations.end())); + boneAnimations.insert(AZStd::make_move_iterator(fillerAnimations.begin()), AZStd::make_move_iterator(fillerAnimations.end())); auto animItr = boneAnimations.equal_range(currentNode->mName.C_Str()); diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 5b43941715..e726547c98 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -98,6 +98,20 @@ namespace AZ } } + aiMatrix4x4 CalculateWorldTransform(const aiNode* currentNode) + { + aiMatrix4x4 transform = {}; + const aiNode* iteratingNode = currentNode; + + while (iteratingNode) + { + transform = iteratingNode->mTransformation * transform; + iteratingNode = iteratingNode->mParent; + } + + return transform; + } + Events::ProcessingResult AssImpBoneImporter::ImportBone(AssImpNodeEncounteredContext& context) { AZ_TraceContext("Importer", "Bone"); @@ -111,12 +125,7 @@ namespace AZ } bool isBone = false; - - if (NodeParentIsOfType(context.m_scene.GetGraph(), context.m_currentGraphPosition, DataTypes::IBoneData::TYPEINFO_Uuid())) - { - isBone = true; - } - else + { AZStd::unordered_map mainBoneList; AZStd::unordered_map boneLookup; @@ -170,15 +179,8 @@ namespace AZ { createdBoneData = AZStd::make_shared(); } - - aiMatrix4x4 transform = currentNode->mTransformation; - const aiNode* parent = currentNode->mParent; - while (parent) - { - transform = parent->mTransformation * transform; - parent = parent->mParent; - } + aiMatrix4x4 transform = CalculateWorldTransform(currentNode); SceneAPI::DataTypes::MatrixType globalTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(transform); diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h index bc4bdd474e..86069cdd9e 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h @@ -31,7 +31,7 @@ namespace AZ ~AssImpBoneImporter() override = default; static void Reflect(ReflectContext* context); - + Events::ProcessingResult ImportBone(AssImpNodeEncounteredContext& context); }; } // namespace FbxSceneBuilder diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp index bcc007e3a7..f7a85a161b 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp @@ -46,8 +46,9 @@ namespace AZ serializeContext->Class()->Version(1); } } - - void GetAllBones(const aiScene* scene, AZStd::unordered_map& boneLookup) + + void GetAllBones( + const aiScene* scene, AZStd::unordered_multimap& boneLookup) { for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { @@ -57,7 +58,7 @@ namespace AZ { const aiBone* bone = mesh->mBones[boneIndex]; - boneLookup[bone->mName.C_Str()] = bone; + boneLookup.emplace(bone->mName.C_Str(), bone); } } } @@ -73,41 +74,53 @@ namespace AZ return Events::ProcessingResult::Ignored; } - AZStd::unordered_map boneLookup; + AZStd::unordered_multimap boneLookup; GetAllBones(scene, boneLookup); auto boneIterator = boneLookup.find(currentNode->mName.C_Str()); const bool isBone = boneIterator != boneLookup.end(); - - aiMatrix4x4 combinedTransform; + + DataTypes::MatrixType localTransform; if (isBone) { - auto parentNode = currentNode->mParent; - - aiMatrix4x4 offsetMatrix = boneIterator->second->mOffsetMatrix; - aiMatrix4x4 parentOffset {}; + AZStd::vector offsets, inverseOffsets; + auto iteratingNode = currentNode; - auto parentBoneIterator = boneLookup.find(parentNode->mName.C_Str()); - - if (parentNode && parentBoneIterator != boneLookup.end()) + while (iteratingNode && boneLookup.count(iteratingNode->mName.C_Str())) { - const auto& parentBone = parentBoneIterator->second; + AZStd::string name = iteratingNode->mName.C_Str(); - parentOffset = parentBone->mOffsetMatrix; - } + auto range = boneLookup.equal_range(name); - auto inverseOffset = offsetMatrix; - inverseOffset.Inverse(); + if (range.first != range.second) + { + // There can be multiple offsetMatrices for a given bone, we're only interested in grabbing the first one + auto boneFirstOffsetMatrix = range.first->second->mOffsetMatrix; + auto azMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(boneFirstOffsetMatrix); + offsets.push_back(azMat); + inverseOffsets.push_back(azMat.GetInverseFull()); + } - combinedTransform = parentOffset * inverseOffset; + iteratingNode = iteratingNode->mParent; + } + + localTransform = + offsets.at(AZ::GetMin(offsets.size()-1, static_cast(1))) // parent bone offset, or if there is no parent, then current node offset + * inverseOffsets.at(inverseOffsets.size() - 1) // Inverse of root bone offset + * offsets.at(offsets.size() - 1) // Root bone offset + * inverseOffsets.at(0); // Inverse of current node offset } else { - combinedTransform = GetConcatenatedLocalTransform(currentNode); + localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(GetConcatenatedLocalTransform(currentNode)); } - DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform); + // Don't bother adding a node with the identity matrix + if (localTransform == DataTypes::MatrixType::Identity()) + { + return Events::ProcessingResult::Ignored; + } context.m_sourceSceneSystem.SwapTransformForUpAxis(localTransform); context.m_sourceSceneSystem.ConvertUnit(localTransform); diff --git a/Code/Tools/Standalone/Source/LUA/LUAEditorMainWindow.cpp b/Code/Tools/Standalone/Source/LUA/LUAEditorMainWindow.cpp index a08e6f4d7f..aa668921d7 100644 --- a/Code/Tools/Standalone/Source/LUA/LUAEditorMainWindow.cpp +++ b/Code/Tools/Standalone/Source/LUA/LUAEditorMainWindow.cpp @@ -1765,16 +1765,8 @@ namespace LUAEditor return false; } - //name has the full path in it, we need to convert it to an asset name - AZStd::string projectRoot, databaseRoot, databasePath, databaseFile, fileExtension; - if (!AzFramework::StringFunc::AssetDatabasePath::Split(name.toUtf8().data(), &projectRoot, &databaseRoot, &databasePath, &databaseFile, &fileExtension)) - { - AZ_Warning("LUAEditorMainWindow", false, AZStd::string::format("Path is invalid: '%s'", name.toUtf8().data()).c_str()); - return false; - } - AzFramework::StringFunc::Path::Split(name.toUtf8().data(), nullptr, &m_lastOpenFilePath); - AzFramework::StringFunc::AssetDatabasePath::Join(databasePath.c_str(), databaseFile.c_str(), newAssetName); + newAssetName = name.toUtf8().data(); return true; } diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index 4ade4b5e54..62c98b3ed4 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -144,6 +144,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) FILES_CMAKE awscore_editor_tests_files.cmake ${pal_editor_include_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake + Tests/Editor/Platform/${PAL_PLATFORM_NAME}/awscore_editor_tests_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PRIVATE Include/Private diff --git a/Gems/AWSCore/Code/Tests/AWSCoreEditorSystemComponentTest.cpp b/Gems/AWSCore/Code/Tests/Editor/AWSCoreEditorSystemComponentTest.cpp similarity index 100% rename from Gems/AWSCore/Code/Tests/AWSCoreEditorSystemComponentTest.cpp rename to Gems/AWSCore/Code/Tests/Editor/AWSCoreEditorSystemComponentTest.cpp diff --git a/Gems/AWSCore/Code/Tests/Editor/Platform/Linux/awscore_editor_tests_linux_files.cmake b/Gems/AWSCore/Code/Tests/Editor/Platform/Linux/awscore_editor_tests_linux_files.cmake new file mode 100644 index 0000000000..089a138cd0 --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/Platform/Linux/awscore_editor_tests_linux_files.cmake @@ -0,0 +1,13 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES +) diff --git a/Gems/AWSCore/Code/Tests/Editor/Platform/Mac/awscore_editor_tests_mac_files.cmake b/Gems/AWSCore/Code/Tests/Editor/Platform/Mac/awscore_editor_tests_mac_files.cmake new file mode 100644 index 0000000000..089a138cd0 --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/Platform/Mac/awscore_editor_tests_mac_files.cmake @@ -0,0 +1,13 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES +) diff --git a/Gems/AWSCore/Code/Tests/Editor/Platform/Windows/awscore_editor_tests_windows_files.cmake b/Gems/AWSCore/Code/Tests/Editor/Platform/Windows/awscore_editor_tests_windows_files.cmake new file mode 100644 index 0000000000..2ed7531e96 --- /dev/null +++ b/Gems/AWSCore/Code/Tests/Editor/Platform/Windows/awscore_editor_tests_windows_files.cmake @@ -0,0 +1,22 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(FILES + ../../AWSCoreEditorSystemComponentTest.cpp + ../../Attribution/AWSCoreAttributionManagerTest.cpp + ../../Attribution/AWSCoreAttributionMetricTest.cpp + ../../Attribution/AWSCoreAttributionSystemComponentTest.cpp + ../../Attribution/AWSAttributionServiceApiTest.cpp + ../../UI/AWSCoreEditorMenuTest.cpp + ../../UI/AWSCoreEditorUIFixture.h + ../../UI/AWSCoreResourceMappingToolActionTest.cpp + ../../AWSCoreEditorManagerTest.cpp +) diff --git a/Gems/AWSCore/Code/awscore_editor_tests_files.cmake b/Gems/AWSCore/Code/awscore_editor_tests_files.cmake index bba830d5d1..ef1d38fdeb 100644 --- a/Gems/AWSCore/Code/awscore_editor_tests_files.cmake +++ b/Gems/AWSCore/Code/awscore_editor_tests_files.cmake @@ -10,14 +10,5 @@ # set(FILES - Tests/AWSCoreEditorSystemComponentTest.cpp - Tests/Editor/Attribution/AWSCoreAttributionManagerTest.cpp - Tests/Editor/Attribution/AWSCoreAttributionMetricTest.cpp - Tests/Editor/Attribution/AWSCoreAttributionSystemComponentTest.cpp - Tests/Editor/Attribution/AWSAttributionServiceApiTest.cpp - Tests/Editor/UI/AWSCoreEditorMenuTest.cpp - Tests/Editor/UI/AWSCoreEditorUIFixture.h - Tests/Editor/UI/AWSCoreResourceMappingToolActionTest.cpp - Tests/Editor/AWSCoreEditorManagerTest.cpp Tests/Editor/AWSCoreEditorTest.cpp ) diff --git a/Gems/AWSCore/cdk/example/example_resources_stack.py b/Gems/AWSCore/cdk/example/example_resources_stack.py index 42afdd6d9e..7fa48160de 100755 --- a/Gems/AWSCore/cdk/example/example_resources_stack.py +++ b/Gems/AWSCore/cdk/example/example_resources_stack.py @@ -11,10 +11,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import os from aws_cdk import ( - aws_lambda as _lambda, - aws_s3 as _s3, + aws_lambda as lambda_, + aws_s3 as s3, aws_s3_deployment as s3_deployment, - aws_dynamodb as _dynamo, + aws_dynamodb as dynamo, core ) @@ -39,7 +39,7 @@ class ExampleResources(core.Stack): self._feature_name = feature_name self._policy = AuthPolicy(context=self).generate_admin_policy(stack=self) - self._s3 = self.__create_s3_bucket() + self._s3_bucket = self.__create_s3_bucket() self._lambda = self.__create_example_lambda() self._table = self.__create_dynamodb_table() @@ -49,8 +49,8 @@ class ExampleResources(core.Stack): self.__grant_access(props=props_) def __grant_access(self, props: CoreStackProperties): - self._s3.grant_read(props.user_group) - self._s3.grant_read(props.admin_group) + self._s3_bucket.grant_read(props.user_group) + self._s3_bucket.grant_read(props.admin_group) self._lambda.grant_invoke(props.user_group) self._lambda.grant_invoke(props.admin_group) @@ -58,42 +58,50 @@ class ExampleResources(core.Stack): self._table.grant_read_data(props.user_group) self._table.grant_read_data(props.admin_group) - def __create_s3_bucket(self) -> _s3.Bucket: - # create s3 bucket - - # create s3 bucket - s3 = _s3.Bucket(self, f'{self._project_name}-{self._feature_name}-Example-S3bucket') + def __create_s3_bucket(self) -> s3.Bucket: + # Create a sample S3 bucket following S3 best practices + # # See https://docs.aws.amazon.com/AmazonS3/latest/dev/security-best-practices.html + # 1. Block all public access to the bucket + # 2. Use SSE-S3 encryption. Explore encryption at rest options via + # https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html + example_bucket = s3.Bucket( + self, + f'{self._project_name}-{self._feature_name}-Example-S3bucket', + block_public_access=s3.BlockPublicAccess.BLOCK_ALL, + encryption=s3.BucketEncryption.S3_MANAGED + ) s3_deployment.BucketDeployment( self, f'{self._project_name}-{self._feature_name}-S3bucket-Deployment', - destination_bucket=s3, + destination_bucket=example_bucket, sources=[ s3_deployment.Source.asset('example/s3_content') ], retain_on_delete=False ) + return example_bucket - return s3 - - def __create_example_lambda(self) -> _lambda.Function: + def __create_example_lambda(self) -> lambda_.Function: # create lambda function - function = _lambda.Function(self, - f'{self._project_name}-{self._feature_name}-Lambda-Function', - runtime=_lambda.Runtime.PYTHON_3_8, - handler="lambda-handler.main", - code=_lambda.Code.asset(os.path.join(os.path.dirname(__file__), 'lambda'))) + function = lambda_.Function( + self, + f'{self._project_name}-{self._feature_name}-Lambda-Function', + runtime=lambda_.Runtime.PYTHON_3_8, + handler="lambda-handler.main", + code=lambda_.Code.asset(os.path.join(os.path.dirname(__file__), 'lambda')) + ) return function - def __create_dynamodb_table(self) -> _dynamo.Table: + def __create_dynamodb_table(self) -> dynamo.Table: # create dynamo table # NB: CDK does not support seeding data, see simple table_seeder.py - demo_table = _dynamo.Table( + demo_table = dynamo.Table( self, f'{self._project_name}-{self._feature_name}-Table', - partition_key=_dynamo.Attribute( + partition_key=dynamo.Attribute( name="id", - type=_dynamo.AttributeType.STRING + type=dynamo.AttributeType.STRING ) ) return demo_table @@ -106,7 +114,7 @@ class ExampleResources(core.Stack): id=f'ExampleBucketOutput', description='An example S3 bucket to use with AWSCore ScriptBehaviors', export_name=f"ExampleS3Bucket", - value=self._s3.bucket_arn) + value=self._s3_bucket.bucket_arn) # Define exports # Export resource group diff --git a/Gems/AWSMetrics/cdk/aws_metrics/real_time_data_processing.py b/Gems/AWSMetrics/cdk/aws_metrics/real_time_data_processing.py index a0b6ec31f6..8716b83b79 100755 --- a/Gems/AWSMetrics/cdk/aws_metrics/real_time_data_processing.py +++ b/Gems/AWSMetrics/cdk/aws_metrics/real_time_data_processing.py @@ -182,7 +182,7 @@ class RealTimeDataProcessing: """ Generate the analytics processing lambda to send processed data to CloudWatch for visualization. """ - analytics_processing_function_name = f'{self._stack.stack_name}-AnalyticsProcessingLambda' + analytics_processing_function_name = f'{self._stack.stack_name}-AnalyticsProcessingLambdaName' self._analytics_processing_lambda_role = self._create_analytics_processing_lambda_role( analytics_processing_function_name ) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype index ff0c4c59da..c635f94d56 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype @@ -1015,7 +1015,7 @@ { "id": "pdo", "displayName": "Pixel Depth Offset", - "description": "Whether to enable the pixel depth offset feature.", + "description": "Enable PDO to offset the original pixel depths. This will affect any shaders using depth, for example, when receiving shadows.", "type": "Bool", "defaultValue": false, "connection": { diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR.materialtype index c07eac3d47..d9a21e7662 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR.materialtype +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR.materialtype @@ -417,7 +417,7 @@ { "id": "pdo", "displayName": "Pixel Depth Offset", - "description": "Whether to enable the pixel depth offset feature.", + "description": "Enable PDO to offset the original pixel depths. This will affect any shaders using depth, for example, when receiving shadows.", "type": "Bool", "defaultValue": false, "connection": { diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype index 2d94f66edf..fd2c74dae0 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype @@ -956,7 +956,7 @@ { "id": "pdo", "displayName": "Pixel Depth Offset", - "description": "Whether to enable the pixel depth offset feature.", + "description": "Enable PDO to offset the original pixel depths. This will affect any shaders using depth, for example, when receiving shadows.", "type": "Bool", "defaultValue": false, "connection": { diff --git a/Gems/Atom/Feature/Common/Assets/Passes/ReflectionCopyFrameBuffer.pass b/Gems/Atom/Feature/Common/Assets/Passes/ReflectionCopyFrameBuffer.pass index ac7ea3754c..ee83e60621 100644 --- a/Gems/Atom/Feature/Common/Assets/Passes/ReflectionCopyFrameBuffer.pass +++ b/Gems/Atom/Feature/Common/Assets/Passes/ReflectionCopyFrameBuffer.pass @@ -21,7 +21,7 @@ "SlotType": "Output", "ScopeAttachmentUsage": "RenderTarget", "LoadStoreAction": { - "LoadAction": "Load" + "LoadAction": "DontCare" } } ], diff --git a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/SkyBox/SceneSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/SkyBox/SceneSrg.azsli index 9a2c996d04..0a54fdfab0 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/SkyBox/SceneSrg.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderResourceGroups/SkyBox/SceneSrg.azsli @@ -40,6 +40,11 @@ partial ShaderResourceGroup SceneSrg ConstantBuffer m_physicalSkyData; bool m_physicalSky; + float m_fogTopHeight; + float m_fogBottomHeight; + float4 m_fogColor; + bool m_fogEnable; + TextureCube m_skyboxCubemap; float4x4 m_cubemapRotationMatrix; float m_cubemapExposure; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl index 1bebb2ec47..3c09fc077c 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl @@ -152,6 +152,18 @@ PSOutput MainPS(VSOutput input) float3 srgbColor = Z * HosekWilkie(cosGamma, gamma, cosTheta) * SceneSrg::m_physicalSkyData.m_physicalSkyAndSunIntensity.x; color = TransformColor(srgbColor, ColorSpaceId::LinearSRGB, ColorSpaceId::ACEScg); } + } + + if (SceneSrg::m_fogEnable) + { + if (input.m_cubemapCoord.z >= 0.0 && input.m_cubemapCoord.z <= SceneSrg::m_fogTopHeight) + { + color = lerp(SceneSrg::m_fogColor.rgb, color, input.m_cubemapCoord.z > 0.0 ? input.m_cubemapCoord.z/SceneSrg::m_fogTopHeight : 0.0); + } + else if (input.m_cubemapCoord.z < 0.0 && input.m_cubemapCoord.z >= -SceneSrg::m_fogBottomHeight) + { + color = SceneSrg::m_fogColor.rgb; + } } } else diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h index 9679850023..2b632a3f6a 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace AZ { @@ -49,8 +50,9 @@ namespace AZ AZ_RTTI(AZ::Render::SkyBoxFeatureProcessorInterface, "{71061869-1190-4451-A337-E9CFF16441B4}"); virtual void Enable(bool enable) = 0; - virtual bool IsEnable() = 0; + virtual bool IsEnabled() = 0; virtual void SetSkyboxMode(SkyBoxMode mode) = 0; + virtual void SetFogSettings(const SkyBoxFogSettings& fogSettings) = 0; // HDRiSkyBox virtual void SetCubemap(Data::Instance cubemap) = 0; @@ -64,6 +66,13 @@ namespace AZ virtual void SetSkyIntensity(float intensity, PhotometricUnit type) = 0; virtual void SetSunIntensity(float intensity, PhotometricUnit type) = 0; virtual void SetSunRadiusFactor(float factor) = 0; + + // Fog Settings + virtual void SetFogEnabled(bool enable) = 0; + virtual bool IsFogEnabled() = 0; + virtual void SetFogColor(const AZ::Color &color) = 0; + virtual void SetFogTopHeight(float topHeight) = 0; + virtual void SetFogBottomHeight(float bottomHeight) = 0; }; } } diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFogBus.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFogBus.h new file mode 100644 index 0000000000..b89ef2e33b --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFogBus.h @@ -0,0 +1,46 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include +#include + +namespace AZ +{ + namespace Render + { + // EBus to get and set fog settings rendered with the sky + class SkyBoxFogRequests + : public ComponentBus + { + public: + AZ_RTTI(AZ::Render::SkyBoxFogRequests, "{4D477566-54B1-49EC-B8FE-4264EA228482}"); + + static const EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single; + virtual ~SkyBoxFogRequests() {} + + virtual void SetEnabled(bool enable) = 0; + virtual bool IsEnabled() const = 0; + virtual void SetColor(const AZ::Color& color) = 0; + virtual const AZ::Color& GetColor() const = 0; + // Set and Get the height upwards from the horizon + virtual void SetTopHeight(float topHeight) = 0; + virtual float GetTopHeight() const = 0; + // Set and Get the height downwards from the horizon + virtual void SetBottomHeight(float bottomHeight) = 0; + virtual float GetBottomHeight() const = 0; + }; + + typedef AZ::EBus SkyBoxFogRequestBus; + } +} diff --git a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp index 1866da63e5..05d79cd6c3 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CommonSystemComponent.cpp @@ -70,7 +70,7 @@ #include #include #include - +#include #include #include @@ -117,6 +117,7 @@ namespace AZ TransformServiceFeatureProcessor::Reflect(context); ProjectedShadowFeatureProcessor::Reflect(context); SkyBoxFeatureProcessor::Reflect(context); + SkyBoxFogSettings::Reflect(context); UseTextureFunctor::Reflect(context); DrawListFunctor::Reflect(context); SubsurfaceTransmissionParameterFunctor::Reflect(context); diff --git a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentSerializer.cpp b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentSerializer.cpp index a895c04b95..551b561200 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentSerializer.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Material/MaterialAssignmentSerializer.cpp @@ -173,7 +173,7 @@ namespace AZ { if (inputPropertyValue.IsObject() && inputPropertyValue.HasMember("Value") && inputPropertyValue.HasMember("$type")) { - // Requiring explicit type info to differentiate be=tween colors versus vectors and numeric types + // Requiring explicit type info to differentiate between colors versus vectors and numeric types const AZ::Uuid baseTypeId = azrtti_typeid(); AZ::Uuid typeId = AZ::Uuid::CreateNull(); result.Combine(LoadTypeId(typeId, inputPropertyValue, context, &baseTypeId)); @@ -198,7 +198,7 @@ namespace AZ { outputPropertyValue.SetObject(); - // Storing explicit type info to differentiate be=tween colors versus vectors and numeric types + // Storing explicit type info to differentiate between colors versus vectors and numeric types rapidjson::Value typeValue; result.Combine(StoreTypeId(typeValue, azrtti_typeid(), context)); outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator()); diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.cpp index cb57d2519d..2d4b6ee85f 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.cpp @@ -47,6 +47,9 @@ namespace AZ m_updateSrg = true; } + params.m_viewportState = RHI::Viewport(0, static_cast(m_imageSize.m_width), 0, static_cast(m_imageSize.m_height)); + params.m_scissorState = RHI::Scissor(0, 0, m_imageSize.m_width, m_imageSize.m_height); + FullscreenTrianglePass::FrameBeginInternal(params); } diff --git a/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.cpp index 4a3586a799..8fd45f3083 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.cpp @@ -89,6 +89,10 @@ namespace AZ m_cubemapIndex.Reset(); m_cubemapRotationMatrixIndex.Reset(); m_cubemapExposureIndex.Reset(); + m_fogEnableIndex.Reset(); + m_fogColorIndex.Reset(); + m_fogTopHeightIndex.Reset(); + m_fogBottomHeightIndex.Reset(); if (m_buffer) { @@ -160,6 +164,14 @@ namespace AZ m_mapBuffer = false; } + m_sceneSrg->SetConstant(m_fogEnableIndex, m_fogSettings.m_enable); + if (m_fogSettings.m_enable) + { + m_sceneSrg->SetConstant(m_fogTopHeightIndex, m_fogSettings.m_topHeight); + m_sceneSrg->SetConstant(m_fogBottomHeightIndex, m_fogSettings.m_bottomHeight); + m_sceneSrg->SetConstant(m_fogColorIndex, m_fogSettings.m_color); + } + m_sceneSrg->SetConstant(m_physicalSkyIndex, true); break; } @@ -213,7 +225,7 @@ namespace AZ m_enable = enable; } - bool SkyBoxFeatureProcessor::IsEnable() + bool SkyBoxFeatureProcessor::IsEnabled() { return m_enable; } @@ -238,6 +250,36 @@ namespace AZ m_skyboxMode = mode; } + void SkyBoxFeatureProcessor::SetFogSettings(const SkyBoxFogSettings& fogSettings) + { + m_fogSettings = fogSettings; + } + + void SkyBoxFeatureProcessor::SetFogEnabled(bool enable) + { + m_fogSettings.m_enable = enable; + } + + bool SkyBoxFeatureProcessor::IsFogEnabled() + { + return m_fogSettings.m_enable; + } + + void SkyBoxFeatureProcessor::SetFogColor(const AZ::Color& color) + { + m_fogSettings.m_color = color; + } + + void SkyBoxFeatureProcessor::SetFogTopHeight(float topHeight) + { + m_fogSettings.m_topHeight = topHeight; + } + + void SkyBoxFeatureProcessor::SetFogBottomHeight(float bottomHeight) + { + m_fogSettings.m_bottomHeight = bottomHeight; + } + void SkyBoxFeatureProcessor::SetSunPosition(SunPosition sunPosition) { m_skyNeedUpdate = true; diff --git a/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.h index ab019cfd9b..8c8157a614 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFeatureProcessor.h @@ -67,8 +67,14 @@ namespace AZ // SkyBoxFeatureProcessorInterface overrides ... void Enable(bool enable) override; - bool IsEnable() override; + bool IsEnabled() override; void SetSkyboxMode(SkyBoxMode mode) override; + void SetFogSettings(const SkyBoxFogSettings& fogSettings) override; + void SetFogEnabled(bool enable) override; + bool IsFogEnabled() override; + void SetFogColor(const AZ::Color& color) override; + void SetFogTopHeight(float topHeight) override; + void SetFogBottomHeight(float bottomHeight) override; void SetCubemapRotationMatrix(AZ::Matrix4x4 matrix) override; void SetCubemap(Data::Instance cubemap) override; @@ -145,6 +151,10 @@ namespace AZ RHI::ShaderInputNameIndex m_cubemapIndex = "m_skyboxCubemap"; RHI::ShaderInputNameIndex m_cubemapRotationMatrixIndex = "m_cubemapRotationMatrix"; RHI::ShaderInputNameIndex m_cubemapExposureIndex = "m_cubemapExposure"; + RHI::ShaderInputNameIndex m_fogEnableIndex = "m_fogEnable"; + RHI::ShaderInputNameIndex m_fogColorIndex = "m_fogColor"; + RHI::ShaderInputNameIndex m_fogTopHeightIndex = "m_fogTopHeight"; + RHI::ShaderInputNameIndex m_fogBottomHeightIndex = "m_fogBottomHeight"; bool m_skyNeedUpdate = true; bool m_sunNeedUpdate = true; @@ -152,6 +162,7 @@ namespace AZ bool m_enable = false; SkyBoxMode m_skyboxMode = SkyBoxMode::None; + SkyBoxFogSettings m_fogSettings; Data::Instance m_sceneSrg = nullptr; Data::Instance m_cubemapTexture = nullptr; diff --git a/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.cpp b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.cpp new file mode 100644 index 0000000000..a908be8b66 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.cpp @@ -0,0 +1,83 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#include +#include +#include +#include +#include + +namespace AZ +{ + namespace Render + { + void SkyBoxFogSettings::Reflect(ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(1) + ->Field("Enable", &SkyBoxFogSettings::m_enable) + ->Field("Color", &SkyBoxFogSettings::m_color) + ->Field("TopHeight", &SkyBoxFogSettings::m_topHeight) + ->Field("BottomHeight", &SkyBoxFogSettings::m_bottomHeight) + ; + + if (auto editContext = serializeContext->GetEditContext()) + { + editContext->Class("SkyBoxFogSettings", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->DataElement(AZ::Edit::UIHandlers::Default, &SkyBoxFogSettings::m_enable, "Enable Fog", "Toggle fog on or off") + ->DataElement(AZ::Edit::UIHandlers::Default, &SkyBoxFogSettings::m_color, "Fog Color", "Color of the fog") + ->Attribute(AZ::Edit::Attributes::ReadOnly, &SkyBoxFogSettings::IsFogDisabled) + ->DataElement(AZ::Edit::UIHandlers::Slider, &SkyBoxFogSettings::m_topHeight, "Fog Top Height", "Height of the fog upwards from the horizon") + ->Attribute(AZ::Edit::Attributes::ReadOnly, &SkyBoxFogSettings::IsFogDisabled) + ->Attribute(AZ::Edit::Attributes::Min, 0.0) + ->Attribute(AZ::Edit::Attributes::Max, 0.5) + ->Attribute(AZ::Edit::Attributes::Step, 0.01) + ->DataElement(AZ::Edit::UIHandlers::Slider, &SkyBoxFogSettings::m_bottomHeight, "Fog Bottom Height", "Height of the fog downwards from the horizon") + ->Attribute(AZ::Edit::Attributes::ReadOnly, &SkyBoxFogSettings::IsFogDisabled) + ->Attribute(AZ::Edit::Attributes::Min, 0.0) + ->Attribute(AZ::Edit::Attributes::Max, 0.3) + ->Attribute(AZ::Edit::Attributes::Step, 0.01) + ; + } + } + + if (auto behaviorContext = azrtti_cast(context)) + { + behaviorContext->EBus("SkyBoxFogRequestBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Category, "render") + ->Attribute(AZ::Script::Attributes::Module, "render") + ->Event("SetEnabled", &SkyBoxFogRequestBus::Events::SetEnabled) + ->Event("IsEnabled", &SkyBoxFogRequestBus::Events::IsEnabled) + ->Event("SetColor", &SkyBoxFogRequestBus::Events::SetColor) + ->Event("GetColor", &SkyBoxFogRequestBus::Events::GetColor) + ->Event("SetTopHeight", &SkyBoxFogRequestBus::Events::SetTopHeight) + ->Event("GetTopHeight", &SkyBoxFogRequestBus::Events::GetTopHeight) + ->Event("SetBottomHeight", &SkyBoxFogRequestBus::Events::SetBottomHeight) + ->Event("GetBottomHeight", &SkyBoxFogRequestBus::Events::GetBottomHeight) + ->VirtualProperty("Enable", "IsEnabled", "SetEnabled") + ->VirtualProperty("Color", "GetColor", "SetColor") + ->VirtualProperty("TopHeight", "GetTopHeight", "SetTopHeight") + ->VirtualProperty("BottomHeight", "GetTopHeight", "SetBottomHeight") + ; + } + } + + bool SkyBoxFogSettings::IsFogDisabled() const + { + return !m_enable; + } + } +} diff --git a/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.h b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.h new file mode 100644 index 0000000000..9c3d04aa7b --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.h @@ -0,0 +1,38 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include +#include + +namespace AZ +{ + namespace Render + { + struct SkyBoxFogSettings final + { + AZ_RTTI(AZ::Render::SkyBoxFogSettings, "{DB13027C-BA92-4E46-B428-BB77C2A80C51}"); + + static void Reflect(ReflectContext* context); + + SkyBoxFogSettings() = default; + + bool IsFogDisabled() const; + + AZ::Color m_color = AZ::Color::CreateOne(); + bool m_enable = false; + float m_topHeight = 0.01; + float m_bottomHeight = 0.0; + }; + } +} diff --git a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake index a656558abf..b97df65ad2 100644 --- a/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake +++ b/Gems/Atom/Feature/Common/Code/atom_feature_common_files.cmake @@ -32,6 +32,7 @@ set(FILES Include/Atom/Feature/PostProcessing/SMAAFeatureProcessorInterface.h Include/Atom/Feature/PostProcess/PostFxLayerCategoriesConstants.h Include/Atom/Feature/ReflectionProbe/ReflectionProbeFeatureProcessor.h + Include/Atom/Feature/SkyBox/SkyBoxFogBus.h Include/Atom/Feature/SkyBox/SkyboxConstants.h Include/Atom/Feature/SkyBox/SkyBoxLUT.h Include/Atom/Feature/SphericalHarmonics/SphericalHarmonicsUtility.h @@ -297,6 +298,8 @@ set(FILES Source/SkinnedMesh/SkinnedMeshVertexStreamProperties.h Source/SkyBox/SkyBoxFeatureProcessor.cpp Source/SkyBox/SkyBoxFeatureProcessor.h + Source/SkyBox/SkyBoxFogSettings.h + Source/SkyBox/SkyBoxFogSettings.cpp Source/TransformService/TransformServiceFeatureProcessor.cpp Source/Utils/GpuBufferHandler.cpp Source/LuxCore/LuxCoreTexturePass.cpp diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.cpp index c433a6f9cf..29dc91e2fa 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.cpp @@ -35,7 +35,6 @@ namespace AZ { m_device = device; m_srgLayout = srgLayout; - m_srgPool = srgPool; m_constantBufferSize = srgLayout->GetConstantDataSize(); if (m_constantBufferSize) @@ -93,9 +92,6 @@ namespace AZ //Attach the constant buffer AttachConstantBuffer(); - - m_samplerCache = [[NSCache alloc]init]; - [m_samplerCache setName:@"SamplerCache"]; } } } @@ -211,8 +207,8 @@ namespace AZ } else { - RHI::Ptr nullMtlBufferMemPtr = m_device->GetNullDescriptorManager().GetNullImage(shaderInputImage.m_type).GetMemory(); - mtlTextures[imageArrayLen] = nullMtlBufferMemPtr->GetGpuAddress>(); + RHI::Ptr nullMtlImagePtr = m_device->GetNullDescriptorManager().GetNullImage(shaderInputImage.m_type).GetMemory(); + mtlTextures[imageArrayLen] = nullMtlImagePtr->GetGpuAddress>(); } imageArrayLen++; } @@ -345,15 +341,20 @@ namespace AZ m_device->GetArgumentBufferAllocator().DeAllocate(m_argumentBuffer); } #endif - m_argumentBuffer = {}; - m_constantBuffer = {}; - [m_samplerCache removeAllObjects]; - [m_samplerCache release]; - m_samplerCache = nil; + if(m_argumentBuffer.IsValid()) + { + m_device->QueueForRelease(m_argumentBuffer); + } + if(m_constantBuffer.IsValid()) + { + m_device->QueueForRelease(m_constantBuffer); + } + [m_argumentEncoder release]; m_argumentEncoder = nil; + Base::Shutdown(); } @@ -374,23 +375,22 @@ namespace AZ id ArgumentBuffer::GetMtlSampler(MTLSamplerDescriptor* samplerDesc) { - id mtlSamplerState = [m_samplerCache objectForKey:samplerDesc]; + const NSCache* samplerCache = m_device->GetSamplerCache(); + id mtlSamplerState = [samplerCache objectForKey:samplerDesc]; if(mtlSamplerState == nil) { mtlSamplerState = [m_device->GetMtlDevice() newSamplerStateWithDescriptor:samplerDesc]; - [m_samplerCache setObject:mtlSamplerState forKey:samplerDesc]; + [samplerCache setObject:mtlSamplerState forKey:samplerDesc]; } return mtlSamplerState; } - void ArgumentBuffer::AddUntrackedResourcesToEncoder(id commandEncoder, const ShaderResourceGroupVisibility& srgResourcesVisInfo) const + void ArgumentBuffer::CollectUntrackedResources(id commandEncoder, + const ShaderResourceGroupVisibility& srgResourcesVisInfo, + ComputeResourcesToMakeResidentMap& resourcesToMakeResidentCompute, + GraphicsResourcesToMakeResidentMap& resourcesToMakeResidentGraphics) const { - //Map to cache all the resources based on the usage as we can batch all the resources for a given usage - ComputeResourcesToMakeResidentMap resourcesToMakeResidentCompute; - //Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage - GraphicsResourcesToMakeResidentMap resourcesToMakeResidentGraphics; - //Cache the constant buffer associated with a srg if (m_constantBufferSize) { @@ -434,25 +434,6 @@ namespace AZ } } } - - //Call UseResource on all resources for Compute stage - for (const auto& key : resourcesToMakeResidentCompute) - { - AZStd::vector> resourcesToProcessVec(key.second.begin(), key.second.end()); - [static_cast>(commandEncoder) useResources: &resourcesToProcessVec[0] - count: resourcesToProcessVec.size() - usage: key.first]; - } - - //Call UseResource on all resources for Vertex and Fragment stages - for (const auto& key : resourcesToMakeResidentGraphics) - { - AZStd::vector> resourcesToProcessVec(key.second.begin(), key.second.end()); - [static_cast>(commandEncoder) useResources: &resourcesToProcessVec[0] - count: resourcesToProcessVec.size() - usage: key.first.first - stages: key.first.second]; - } } void ArgumentBuffer::CollectResourcesForCompute(id encoder, diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.h index 29d7d5e239..d4d9222249 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/ArgumentBuffer.h @@ -97,7 +97,15 @@ namespace AZ id GetArgEncoderBuffer() const; size_t GetOffset() const; - void AddUntrackedResourcesToEncoder(id commandEncoder, const ShaderResourceGroupVisibility& srgResourcesVisInfo) const; + //Map to cache all the resources based on the usage as we can batch all the resources for a given usage. + using ComputeResourcesToMakeResidentMap = AZStd::unordered_map>>; + //Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage. + using GraphicsResourcesToMakeResidentMap = AZStd::unordered_map, AZStd::unordered_set>>; + + void CollectUntrackedResources(id commandEncoder, + const ShaderResourceGroupVisibility& srgResourcesVisInfo, + ComputeResourcesToMakeResidentMap& resourcesToMakeResidentCompute, + GraphicsResourcesToMakeResidentMap& resourcesToMakeResidentGraphics) const; void ClearResourceTracking(); @@ -120,11 +128,7 @@ namespace AZ ResourceBindingsMap m_resourceBindings; static const int MaxEntriesInArgTable = 31; - //Map to cache all the resources based on the usage as we can batch all the resources for a given usage. - using ComputeResourcesToMakeResidentMap = AZStd::unordered_map>>; - //Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage. - using GraphicsResourcesToMakeResidentMap = AZStd::unordered_map, AZStd::unordered_set>>; - + void CollectResourcesForCompute(id encoder, const ResourceBindingsSet& resourceBindingData, ComputeResourcesToMakeResidentMap& resourcesToMakeResidentMap) const; @@ -153,9 +157,6 @@ namespace AZ MemoryView m_argumentBuffer; MemoryView m_constantBuffer; #endif - - ShaderResourceGroupPool* m_srgPool = nullptr; - NSCache* m_samplerCache; }; } } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/BufferPoolResolver.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/BufferPoolResolver.cpp index b986b8ea75..da6665d9c3 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/BufferPoolResolver.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/BufferPoolResolver.cpp @@ -40,7 +40,7 @@ namespace AZ buffer->m_pendingResolves++; uploadRequest.m_attachmentBuffer = buffer; - uploadRequest.m_byteOffset = buffer->GetMemoryView().GetOffset() + request.m_byteOffset; + uploadRequest.m_byteOffset = request.m_byteOffset; uploadRequest.m_stagingBuffer = stagingBuffer; return stagingBuffer->GetMemoryView().GetCpuAddress(); @@ -51,6 +51,12 @@ namespace AZ void BufferPoolResolver::Compile() { + for (BufferUploadPacket& packet : m_uploadPackets) + { + Buffer* stagingBuffer = packet.m_stagingBuffer.get(); + //Inform the GPU that the CPU has modified the staging buffer. + Platform::SynchronizeBufferOnCPU(stagingBuffer->GetMemoryView().GetGpuAddress>(), stagingBuffer->GetMemoryView().GetOffset(), stagingBuffer->GetMemoryView().GetSize()); + } } void BufferPoolResolver::Resolve(CommandList& commandList) const @@ -62,15 +68,12 @@ namespace AZ Buffer* destBuffer = packet.m_attachmentBuffer; AZ_Assert(stagingBuffer, "Staging Buffer is null."); AZ_Assert(destBuffer, "Attachment Buffer is null."); - - //Inform the GPU that the CPU has modified the staging buffer. - Platform::SynchronizeBufferOnCPU(stagingBuffer->GetMemoryView().GetGpuAddress>(), stagingBuffer->GetMemoryView().GetOffset(), stagingBuffer->GetMemoryView().GetSize()); RHI::CopyBufferDescriptor copyDescriptor; copyDescriptor.m_sourceBuffer = stagingBuffer; copyDescriptor.m_sourceOffset = stagingBuffer->GetMemoryView().GetOffset(); copyDescriptor.m_destinationBuffer = destBuffer; - copyDescriptor.m_destinationOffset = static_cast(packet.m_byteOffset); + copyDescriptor.m_destinationOffset = destBuffer->GetMemoryView().GetOffset() + static_cast(packet.m_byteOffset); copyDescriptor.m_size = stagingBuffer->GetMemoryView().GetSize(); commandList.Submit(RHI::CopyItem(copyDescriptor)); diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandList.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandList.cpp index 7f65c9ea47..3c554c6128 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandList.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandList.cpp @@ -85,6 +85,7 @@ namespace AZ destinationOffset:descriptor.m_destinationOffset size:descriptor.m_size]; + Platform::SynchronizeBufferOnGPU(blitEncoder, destinationBuffer->GetMemoryView().GetGpuAddress>()); break; } case RHI::CopyItemType::Image: @@ -114,6 +115,8 @@ namespace AZ destinationSlice: descriptor.m_destinationSubresource.m_arraySlice destinationLevel: descriptor.m_destinationSubresource.m_mipSlice destinationOrigin: destinationOrigin]; + + Platform::SynchronizeTextureOnGPU(blitEncoder, destinationImage->GetMemoryView().GetGpuAddress>()); break; } case RHI::CopyItemType::BufferToImage: @@ -266,6 +269,11 @@ namespace AZ mtlVertexArgBufferOffsets.fill(0); mtlFragmentOrComputeArgBufferOffsets.fill(0); + //Map to cache all the resources based on the usage as we can batch all the resources for a given usage + ArgumentBuffer::ComputeResourcesToMakeResidentMap resourcesToMakeResidentCompute; + //Map to cache all the resources based on the usage and shader stage as we can batch all the resources for a given usage/shader usage + ArgumentBuffer::GraphicsResourcesToMakeResidentMap resourcesToMakeResidentGraphics; + for (uint32_t slot = 0; slot < RHI::Limits::Pipeline::ShaderResourceGroupCountMax; ++slot) { const ShaderResourceGroup* shaderResourceGroup = bindings.m_srgsBySlot[slot]; @@ -291,7 +299,6 @@ namespace AZ //For graphics and compute shader stages, cache all the argument buffers, offsets and track the min/max indices if(m_commandEncoderType == CommandEncoderType::Render) { - id renderEncoder = GetEncoder>(); uint8_t numBitsSet = RHI::CountBitsSet(static_cast(srgVisInfo)); if( numBitsSet > 1 || srgVisInfo == RHI::ShaderStageMask::Vertex) { @@ -334,11 +341,11 @@ namespace AZ //format compatible with the appropriate metal function. if(m_commandEncoderType == CommandEncoderType::Render) { - shaderResourceGroup->AddUntrackedResourcesToEncoder(m_encoder, srgResourcesVisInfo); + shaderResourceGroup->CollectUntrackedResources(m_encoder, srgResourcesVisInfo, resourcesToMakeResidentCompute, resourcesToMakeResidentGraphics); } else if(m_commandEncoderType == CommandEncoderType::Compute) { - shaderResourceGroup->AddUntrackedResourcesToEncoder(m_encoder, srgResourcesVisInfo); + shaderResourceGroup->CollectUntrackedResources(m_encoder, srgResourcesVisInfo, resourcesToMakeResidentCompute, resourcesToMakeResidentGraphics); } } } @@ -368,6 +375,32 @@ namespace AZ mtlFragmentOrComputeArgBufferOffsets); } + id renderEncoder = GetEncoder>(); + id computeEncoder = GetEncoder>(); + + //Call UseResource on all resources for Compute stage + for (const auto& key : resourcesToMakeResidentCompute) + { + AZStd::vector> resourcesToProcessVec(key.second.begin(), key.second.end()); + + [computeEncoder useResources: &resourcesToProcessVec[0] + count: resourcesToProcessVec.size() + usage: key.first]; + + } + + //Call UseResource on all resources for Vertex and Fragment stages + for (const auto& key : resourcesToMakeResidentGraphics) + { + + AZStd::vector> resourcesToProcessVec(key.second.begin(), key.second.end()); + + [renderEncoder useResources: &resourcesToProcessVec[0] + count: resourcesToProcessVec.size() + usage: key.first.first + stages: key.first.second]; + } + return true; } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp index c27be3344f..bdf9dcfd27 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp @@ -83,7 +83,7 @@ namespace AZ for (id residentHeap : *m_residentHeaps) { [renderEncoder useHeap : residentHeap - stages : MTLRenderStageFragment]; + stages : MTLRenderStageVertex | MTLRenderStageFragment]; } break; } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp index 6b40c8acd1..8eb9463afa 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp @@ -80,6 +80,9 @@ namespace AZ m_nullDescriptorManager.Init(*this); + m_samplerCache = [[NSCache alloc]init]; + [m_samplerCache setName:@"SamplerCache"]; + return RHI::ResultCode::Success; } @@ -101,6 +104,10 @@ namespace AZ m_releaseQueue.Shutdown(); m_pipelineLayoutCache.Shutdown(); + [m_samplerCache removeAllObjects]; + [m_samplerCache release]; + m_samplerCache = nil; + for (AZ::u32 i = 0; i < CommandEncoderTypeCount; ++i) { m_commandListPools[i].Shutdown(); diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h index c7df33b12f..6d108a0c3c 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.h @@ -144,6 +144,11 @@ namespace AZ return m_asyncUploadQueue; } + const NSCache* GetSamplerCache() const + { + return m_samplerCache; + } + BufferMemoryAllocator& GetArgBufferConstantBufferAllocator() { return m_argumentBufferConstantsAllocator;} BufferMemoryAllocator& GetArgumentBufferAllocator() { return m_argumentBufferAllocator;} @@ -194,6 +199,7 @@ namespace AZ RHI::HeapMemoryUsage m_argumentBufferAllocatorMemoryUsage; NullDescriptorManager m_nullDescriptorManager; + NSCache* m_samplerCache; }; } } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.cpp index 68c676d3c2..f36757054e 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.cpp @@ -11,6 +11,7 @@ */ #include "Atom_RHI_Metal_precompiled.h" +#include #include #include @@ -33,10 +34,12 @@ namespace AZ return *m_compiledArgBuffers[m_compiledDataIndex]; } - void ShaderResourceGroup::AddUntrackedResourcesToEncoder(id commandEncoder, - const ShaderResourceGroupVisibility& srgResourcesVisInfo) const + void ShaderResourceGroup::CollectUntrackedResources(id commandEncoder, + const ShaderResourceGroupVisibility& srgResourcesVisInfo, + ArgumentBuffer::ComputeResourcesToMakeResidentMap& resourcesToMakeResidentCompute, + ArgumentBuffer::GraphicsResourcesToMakeResidentMap& resourcesToMakeResidentGraphics) const { - GetCompiledArgumentBuffer().AddUntrackedResourcesToEncoder(commandEncoder, srgResourcesVisInfo); + GetCompiledArgumentBuffer().CollectUntrackedResources(commandEncoder, srgResourcesVisInfo, resourcesToMakeResidentCompute, resourcesToMakeResidentGraphics); } } } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.h index c20dc35a20..bb8f2d58d4 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/ShaderResourceGroup.h @@ -47,7 +47,10 @@ namespace AZ const ImageView* GetImageView(const int index) const; void UpdateCompiledDataIndex(); const ArgumentBuffer& GetCompiledArgumentBuffer() const; - void AddUntrackedResourcesToEncoder(id commandEncoder, const ShaderResourceGroupVisibility& srgResourcesVisInfo) const; + void CollectUntrackedResources(id commandEncoder, + const ShaderResourceGroupVisibility& srgResourcesVisInfo, + ArgumentBuffer::ComputeResourcesToMakeResidentMap& resourcesToMakeResidentCompute, + ArgumentBuffer::GraphicsResourcesToMakeResidentMap& resourcesToMakeResidentGraphics) const; private: ShaderResourceGroup() = default; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp index e3367b078a..9fd38aab93 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp @@ -62,12 +62,7 @@ namespace AZ { RHI::Ptr physicalDevice = aznew PhysicalDevice; physicalDevice->Init(device); - size_t gpuMemSize = physicalDevice->GetDescriptor().m_heapSizePerLevel[static_cast(RHI::HeapMemoryLevel::Device)]; - AZ_Warning("Vulkan", gpuMemSize >= MinGPUMemSize, "Rejecting GPU %s as it's gpu mem size of %zu bytes is less than min required size of %zu bytes for Vulkan API", physicalDevice->GetDescriptor().m_description.c_str(), gpuMemSize, MinGPUMemSize); - if (gpuMemSize >= MinGPUMemSize) - { - physicalDeviceList.emplace_back(physicalDevice); - } + physicalDeviceList.emplace_back(physicalDevice); } return physicalDeviceList; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h index eb4c4ed0aa..f22b5cf87f 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Specific/DownsampleMipChainPass.h @@ -30,6 +30,7 @@ namespace AZ //! It does this by recursively creating Compute Passes to write to each mip using the Compute Shader. class DownsampleMipChainPass : public ParentPass + , private ShaderReloadNotificationBus::Handler { AZ_RPI_PASS(DownsampleMipChainPass); @@ -39,6 +40,7 @@ namespace AZ //! Creates a new pass without a PassTemplate static Ptr Create(const PassDescriptor& descriptor); + virtual ~DownsampleMipChainPass(); protected: explicit DownsampleMipChainPass(const PassDescriptor& descriptor); @@ -49,6 +51,11 @@ namespace AZ void BuildInternal() override; void FrameBeginInternal(FramePrepareParams params) override; + // ShaderReloadNotificationBus::Handler overrides... + void OnShaderReinitialized(const Shader& shader) override; + void OnShaderAssetReinitialized(const Data::Asset& shaderAsset) override; + void OnShaderVariantReinitialized(const ShaderVariant& shaderVariant) override; + private: // Gets target height, width and mip levels from the input/output image attachment diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h index f3da349195..31aa28412f 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/ModelAsset.h @@ -103,10 +103,14 @@ namespace AZ AZStd::size_t CalculateTriangleCount() const; }; - class ModelAssetHandler : public AssetHandler + class ModelAssetHandler + : public AssetHandler { public: AZ_RTTI(ModelAssetHandler, "{993B8CE3-1BBF-4712-84A0-285DB9AE808F}", AssetHandler); + + // AZ::AssetTypeInfoBus::Handler overrides + bool HasConflictingProducts(const AZStd::vector& productAssetTypes) const override; }; } //namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp index 806310ef35..f06875a0ff 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp @@ -181,9 +181,19 @@ namespace AZ RHI::Size targetImageSize = outputAttachment->m_descriptor.m_image.m_size; - // Base viewport and scissor off of target attachment - m_viewportState = RHI::Viewport(0, static_cast(targetImageSize.m_width), 0, static_cast(targetImageSize.m_height)); - m_scissorState = RHI::Scissor(0, 0, targetImageSize.m_width, targetImageSize.m_height); + m_viewportState = params.m_viewportState; + if (m_viewportState.IsNull()) + { + // compute viewport from target attachment + m_viewportState = RHI::Viewport(0, static_cast(targetImageSize.m_width), 0, static_cast(targetImageSize.m_height)); + } + + m_scissorState = params.m_scissorState; + if (m_scissorState.IsNull()) + { + // compute scissor from target attachment + m_scissorState = RHI::Scissor(0, 0, targetImageSize.m_width, targetImageSize.m_height); + } RenderPass::FrameBeginInternal(params); } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp index 329247d4eb..d206a0db08 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Specific/DownsampleMipChainPass.cpp @@ -54,8 +54,14 @@ namespace AZ } m_passData = *passData; + ShaderReloadNotificationBus::Handler::BusConnect(passData->m_shaderReference.m_assetId); } + DownsampleMipChainPass::~DownsampleMipChainPass() + { + ShaderReloadNotificationBus::Handler::BusDisconnect(); + } + void DownsampleMipChainPass::ResetInternal() { RemoveChildren(); @@ -206,5 +212,19 @@ namespace AZ ParentPass::FrameBeginInternal(params); } + void DownsampleMipChainPass::OnShaderReinitialized([[maybe_unused]] const Shader& shader) + { + m_needToUpdateChildren = true; + } + + void DownsampleMipChainPass::OnShaderAssetReinitialized([[maybe_unused]] const Data::Asset& shaderAsset) + { + m_needToUpdateChildren = true; + } + + void DownsampleMipChainPass::OnShaderVariantReinitialized([[maybe_unused]] const ShaderVariant& shaderVariant) + { + m_needToUpdateChildren = true; + } } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp index 52fda0f56b..9e194078c1 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/ModelAsset.cpp @@ -315,5 +315,26 @@ namespace AZ return modelTriangleCount; } - } //namespace RPI + + bool ModelAssetHandler::HasConflictingProducts(const AZStd::vector& productAssetTypes) const + { + size_t modelAssetCount = 0; + size_t actorAssetCount = 0; + for (const AZ::Data::AssetType& assetType : productAssetTypes) + { + if (assetType == azrtti_typeid()) + { + modelAssetCount++; + } + else if (assetType == AZ::Data::AssetType("{F67CC648-EA51-464C-9F5D-4A9CE41A7F86}")) // ActorAsset + { + actorAssetCount++; + } + } + + // When dropping a well-defined character, consisting of a mesh and a skeleton/actor, + // do not create an entity with a mesh component. + return modelAssetCount == 1 && actorAssetCount == 1; + } + } // namespace RPI } // namespace AZ diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp index 420e2732d0..f2dc1fc3e4 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp @@ -10,6 +10,9 @@ * */ +#include +#include + #include #include #include @@ -223,7 +226,12 @@ namespace MaterialEditor } else if (inputChannelId == InputDeviceKeyboard::Key::AlphanumericZ && (m_keys & Ctrl) == None) { - Reset(); + // only reset camera if no other widget besides viewport is in focus + const auto focus = QApplication::focusWidget(); + if (!focus || focus->objectName() == "Viewport") + { + Reset(); + } } break; case InputChannel::State::Updated: diff --git a/Gems/AtomContent/Sponza/.src/objects/Test_Sponza_Materials.mb b/Gems/AtomContent/Sponza/.src/objects/Test_Sponza_Materials.mb new file mode 100644 index 0000000000..d5f12d2bca --- /dev/null +++ b/Gems/AtomContent/Sponza/.src/objects/Test_Sponza_Materials.mb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f4d124e84c8387f06b4b3a77bb3be1e7c3e0dcecb26a8934b89faa8203ed380 +size 84608 diff --git a/Gems/AtomContent/Sponza/Assets/Prefabs/test_sponza_material_conversion.prefab b/Gems/AtomContent/Sponza/Assets/Prefabs/test_sponza_material_conversion.prefab new file mode 100644 index 0000000000..b5aed9d14b --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/Prefabs/test_sponza_material_conversion.prefab @@ -0,0 +1,1240 @@ +{ + "Source": "Prefabs/test_sponza_material_conversion.prefab", + "ContainerEntity": { + "Id": "ContainerEntity", + "Name": "test_sponza_material_conversion", + "Components": { + "Component_[11355906858588942318]": { + "$type": "EditorEntitySortComponent", + "Id": 11355906858588942318 + }, + "Component_[12303631836799763574]": { + "$type": "EditorEntityIconComponent", + "Id": 12303631836799763574 + }, + "Component_[13884330903538620487]": { + "$type": "SelectionComponent", + "Id": 13884330903538620487 + }, + "Component_[14017626015546393905]": { + "$type": "EditorInspectorComponent", + "Id": 14017626015546393905 + }, + "Component_[15706249274315432595]": { + "$type": "EditorLockComponent", + "Id": 15706249274315432595 + }, + "Component_[17662098699702294917]": { + "$type": "EditorPendingCompositionComponent", + "Id": 17662098699702294917 + }, + "Component_[1984406083399463185]": { + "$type": "EditorOnlyEntityComponent", + "Id": 1984406083399463185 + }, + "Component_[3645983967515381372]": { + "$type": "EditorPrefabComponent", + "Id": 3645983967515381372 + }, + "Component_[7000715958539023355]": { + "$type": "EditorVisibilityComponent", + "Id": 7000715958539023355 + }, + "Component_[7182760741886065388]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 7182760741886065388, + "Parent Entity": "", + "Cached World Transform Parent": "" + }, + "Component_[7314978375961307600]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7314978375961307600 + } + }, + "IsDependencyReady": true + }, + "Entities": { + "Entity_[1220355829629]": { + "Id": "Entity_[1220355829629]", + "Name": "GiTestProbe", + "Components": { + "Component_[12581383605035992405]": { + "$type": "SelectionComponent", + "Id": 12581383605035992405 + }, + "Component_[14182862666898786767]": { + "$type": "AZ::Render::EditorReflectionProbeComponent", + "Id": 14182862666898786767, + "Controller": { + "Configuration": { + "OuterHeight": 8.0, + "OuterLength": 8.0, + "OuterWidth": 8.0, + "InnerHeight": 8.0, + "InnerLength": 8.0, + "InnerWidth": 8.0, + "BakedCubeMapRelativePath": "ReflectionProbes/GiTestProbe__0564394E-2435-488E-A30C-E999F79FB049__iblspecularcm256.dds", + "BakedCubeMapAsset": { + "assetId": { + "guid": "{B05482A4-7D4D-5C6D-96DD-54CB9A227307}", + "subId": 2000 + }, + "loadBehavior": "PreLoad", + "assetHint": "reflectionprobes/gitestprobe__0564394e-2435-488e-a30c-e999f79fb049__iblspecularcm256.dds.streamingimage" + }, + "EntityId": 12080580926711778904 + } + }, + "bakedCubeMapRelativePath": "ReflectionProbes/GiTestProbe__0564394E-2435-488E-A30C-E999F79FB049__iblspecularcm256.dds" + }, + "Component_[16557111097824744403]": { + "$type": "EditorBoxShapeComponent", + "Id": 16557111097824744403, + "BoxShape": { + "Configuration": { + "Dimensions": [ + 8.0, + 8.0, + 8.0 + ] + } + } + }, + "Component_[16623349159368925155]": { + "$type": "EditorPendingCompositionComponent", + "Id": 16623349159368925155 + }, + "Component_[17588593493138070858]": { + "$type": "EditorVisibilityComponent", + "Id": 17588593493138070858 + }, + "Component_[18332655128892032441]": { + "$type": "EditorOnlyEntityComponent", + "Id": 18332655128892032441 + }, + "Component_[344586797989012598]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 344586797989012598, + "Parent Entity": "Entity_[1250420600701]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + 4.0 + ] + }, + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 4.099999904632568 + ] + }, + "Cached World Transform Parent": "Entity_[1250420600701]" + }, + "Component_[5703653759245493769]": { + "$type": "EditorLockComponent", + "Id": 5703653759245493769 + }, + "Component_[7030857297912025340]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7030857297912025340, + "DisabledComponents": [ + { + "$type": "AZ::Render::EditorDiffuseProbeGridComponent", + "Id": 1614505811629141904, + "Controller": { + "Configuration": { + "ProbeSpacing": [ + 0.5, + 0.5, + 0.5 + ], + "Extents": [ + 8.0, + 8.0, + 8.0 + ] + } + }, + "probeSpacingX": 0.5, + "probeSpacingY": 0.5, + "probeSpacingZ": 0.5 + } + ] + }, + "Component_[7984183259827618750]": { + "$type": "EditorEntitySortComponent", + "Id": 7984183259827618750 + }, + "Component_[827806435204448771]": { + "$type": "EditorEntityIconComponent", + "Id": 827806435204448771 + }, + "Component_[8673278437899912468]": { + "$type": "EditorInspectorComponent", + "Id": 8673278437899912468 + } + }, + "IsDependencyReady": true + }, + "Entity_[1224650796925]": { + "Id": "Entity_[1224650796925]", + "Name": "Camera", + "Components": { + "Component_[10395754987446042279]": { + "$type": "AZ::Render::EditorPostFxLayerComponent", + "Id": 10395754987446042279 + }, + "Component_[11895140916889160460]": { + "$type": "EditorEntityIconComponent", + "Id": 11895140916889160460 + }, + "Component_[16880285896855930892]": { + "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent", + "Id": 16880285896855930892, + "Controller": { + "Configuration": { + "Field of View": 55.0, + "EditorEntityId": 8929576024571800510 + } + } + }, + "Component_[17187464423780271193]": { + "$type": "EditorLockComponent", + "Id": 17187464423780271193 + }, + "Component_[17495696818315413311]": { + "$type": "EditorEntitySortComponent", + "Id": 17495696818315413311 + }, + "Component_[1798550073623453489]": { + "$type": "AZ::Render::EditorExposureControlComponent", + "Id": 1798550073623453489, + "Controller": { + "Configuration": { + "ExposureControlType": 1 + } + } + }, + "Component_[18086214374043522055]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 18086214374043522055, + "Parent Entity": "Entity_[1250420600701]", + "Transform Data": { + "Translate": [ + 1.7387686967849732, + 1.752368450164795, + 5.225453853607178 + ], + "Rotate": [ + 34.95081329345703, + -29.21880340576172, + 145.06878662109376 + ] + }, + "Cached World Transform": { + "Translation": [ + 1.7387685775756837, + 1.7523683309555054, + 5.325453281402588 + ], + "Rotation": [ + -0.14265206456184388, + -0.3503122329711914, + 0.8573471903800964, + 0.3491239547729492 + ] + }, + "Cached World Transform Parent": "Entity_[1250420600701]" + }, + "Component_[18387556550380114975]": { + "$type": "SelectionComponent", + "Id": 18387556550380114975 + }, + "Component_[2654521436129313160]": { + "$type": "EditorVisibilityComponent", + "Id": 2654521436129313160 + }, + "Component_[5265045084611556958]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5265045084611556958 + }, + "Component_[7169798125182238623]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7169798125182238623 + }, + "Component_[8866210352157164042]": { + "$type": "EditorInspectorComponent", + "Id": 8866210352157164042 + }, + "Component_[9129253381063760879]": { + "$type": "EditorOnlyEntityComponent", + "Id": 9129253381063760879 + } + }, + "IsDependencyReady": true + }, + "Entity_[1228945764221]": { + "Id": "Entity_[1228945764221]", + "Name": "Global Sky", + "Components": { + "Component_[11231930600558681245]": { + "$type": "AZ::Render::EditorHDRiSkyboxComponent", + "Id": 11231930600558681245, + "Controller": { + "Configuration": { + "CubemapAsset": { + "assetId": { + "guid": "{874DA395-146F-5198-90AD-532F18954407}", + "subId": 1000 + }, + "assetHint": "testdata/white_latlong_iblskyboxcm.exr.streamingimage" + } + } + } + }, + "Component_[11980494120202836095]": { + "$type": "SelectionComponent", + "Id": 11980494120202836095 + }, + "Component_[1428633914413949476]": { + "$type": "EditorLockComponent", + "Id": 1428633914413949476 + }, + "Component_[14936200426671614999]": { + "$type": "AZ::Render::EditorImageBasedLightComponent", + "Id": 14936200426671614999, + "Controller": { + "Configuration": { + "diffuseImageAsset": { + "assetId": { + "guid": "{874DA395-146F-5198-90AD-532F18954407}", + "subId": 3000 + }, + "assetHint": "testdata/white_latlong_iblskyboxcm_ibldiffuse.exr.streamingimage" + }, + "specularImageAsset": { + "assetId": { + "guid": "{874DA395-146F-5198-90AD-532F18954407}", + "subId": 2000 + }, + "assetHint": "testdata/white_latlong_iblskyboxcm_iblspecular.exr.streamingimage" + } + } + } + }, + "Component_[14994774102579326069]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 14994774102579326069 + }, + "Component_[15417479889044493340]": { + "$type": "EditorPendingCompositionComponent", + "Id": 15417479889044493340 + }, + "Component_[15826613364991382688]": { + "$type": "EditorEntitySortComponent", + "Id": 15826613364991382688 + }, + "Component_[1665003113283562343]": { + "$type": "EditorOnlyEntityComponent", + "Id": 1665003113283562343 + }, + "Component_[3704934735944502280]": { + "$type": "EditorEntityIconComponent", + "Id": 3704934735944502280 + }, + "Component_[5698542331457326479]": { + "$type": "EditorVisibilityComponent", + "Id": 5698542331457326479 + }, + "Component_[6644513399057217122]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6644513399057217122, + "Parent Entity": "Entity_[1250420600701]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + -0.10000000149011612 + ] + }, + "Cached World Transform Parent": "Entity_[1250420600701]" + }, + "Component_[931091830724002070]": { + "$type": "EditorInspectorComponent", + "Id": 931091830724002070 + } + }, + "IsDependencyReady": true + }, + "Entity_[1233240731517]": { + "Id": "Entity_[1233240731517]", + "Name": "Shader Ball", + "Components": { + "Component_[10789351944715265527]": { + "$type": "EditorOnlyEntityComponent", + "Id": 10789351944715265527 + }, + "Component_[12037033284781049225]": { + "$type": "EditorEntitySortComponent", + "Id": 12037033284781049225 + }, + "Component_[13759153306105970079]": { + "$type": "EditorPendingCompositionComponent", + "Id": 13759153306105970079 + }, + "Component_[14135560884830586279]": { + "$type": "EditorInspectorComponent", + "Id": 14135560884830586279 + }, + "Component_[16247165675903986673]": { + "$type": "EditorVisibilityComponent", + "Id": 16247165675903986673 + }, + "Component_[18082433625958885247]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 18082433625958885247 + }, + "Component_[6472623349872972660]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6472623349872972660, + "Parent Entity": "Entity_[1250420600701]", + "Transform Data": { + "Rotate": [ + 0.0, + 0.10000000149011612, + 180.0 + ] + }, + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 0.10000000149011612 + ], + "Rotation": [ + 0.0008726645028218627, + 0.0, + 0.9999996423721314, + 0.0 + ] + }, + "Cached World Transform Parent": "Entity_[1250420600701]" + }, + "Component_[6495255223970673916]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 6495255223970673916, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}", + "subId": 281415304 + }, + "assetHint": "objects/shaderball/shaderball_default_1m.azmodel" + } + } + } + }, + "Component_[8056625192494070973]": { + "$type": "SelectionComponent", + "Id": 8056625192494070973 + }, + "Component_[8550141614185782969]": { + "$type": "EditorEntityIconComponent", + "Id": 8550141614185782969 + }, + "Component_[9439770997198325425]": { + "$type": "EditorLockComponent", + "Id": 9439770997198325425 + } + }, + "IsDependencyReady": true + }, + "Entity_[1237535698813]": { + "Id": "Entity_[1237535698813]", + "Name": "Sun", + "Components": { + "Component_[10440557478882592717]": { + "$type": "SelectionComponent", + "Id": 10440557478882592717 + }, + "Component_[13620450453324765907]": { + "$type": "EditorLockComponent", + "Id": 13620450453324765907 + }, + "Component_[2134313378593666258]": { + "$type": "EditorInspectorComponent", + "Id": 2134313378593666258 + }, + "Component_[234010807770404186]": { + "$type": "EditorVisibilityComponent", + "Id": 234010807770404186 + }, + "Component_[2970359110423865725]": { + "$type": "EditorEntityIconComponent", + "Id": 2970359110423865725 + }, + "Component_[3722854130373041803]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3722854130373041803 + }, + "Component_[5992533738676323195]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5992533738676323195 + }, + "Component_[7378860763541895402]": { + "$type": "AZ::Render::EditorDirectionalLightComponent", + "Id": 7378860763541895402, + "Controller": { + "Configuration": { + "Intensity": 0.0, + "CameraEntityId": "", + "ShadowFilterMethod": 1 + } + } + }, + "Component_[7892834440890947578]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 7892834440890947578, + "Parent Entity": "Entity_[1250420600701]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + 13.38704299926758 + ], + "Rotate": [ + -76.1310043334961, + -0.8469989895820618, + -15.8100004196167 + ] + }, + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 13.487043380737305 + ], + "Rotation": [ + -0.609886109828949, + -0.09055805951356888, + -0.10376212745904924, + 0.7804304361343384 + ] + }, + "Cached World Transform Parent": "Entity_[1250420600701]" + }, + "Component_[8599729549570828259]": { + "$type": "EditorEntitySortComponent", + "Id": 8599729549570828259 + }, + "Component_[952797371922080273]": { + "$type": "EditorPendingCompositionComponent", + "Id": 952797371922080273 + } + }, + "IsDependencyReady": true + }, + "Entity_[1241830666109]": { + "Id": "Entity_[1241830666109]", + "Name": "Ground", + "Components": { + "Component_[11701138785793981042]": { + "$type": "SelectionComponent", + "Id": 11701138785793981042 + }, + "Component_[12260880513256986252]": { + "$type": "EditorEntityIconComponent", + "Id": 12260880513256986252 + }, + "Component_[13711420870643673468]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 13711420870643673468 + }, + "Component_[138002849734991713]": { + "$type": "EditorOnlyEntityComponent", + "Id": 138002849734991713 + }, + "Component_[16578565737331764849]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 16578565737331764849, + "Parent Entity": "Entity_[1250420600701]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + -0.10000000149011612 + ] + }, + "Cached World Transform Parent": "Entity_[1250420600701]" + }, + "Component_[16919232076966545697]": { + "$type": "EditorInspectorComponent", + "Id": 16919232076966545697 + }, + "Component_[5182430712893438093]": { + "$type": "EditorMaterialComponent", + "Id": 5182430712893438093, + "materialSlots": [ + { + "id": { + "materialAssetId": { + "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}", + "subId": 803645540 + } + } + } + ], + "materialSlotsByLod": [ + [ + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}", + "subId": 803645540 + } + } + } + ] + ] + }, + "Component_[5675108321710651991]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 5675108321710651991, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}", + "subId": 277333723 + }, + "assetHint": "objects/groudplane/groundplane_521x521m.azmodel" + } + } + } + }, + "Component_[5681893399601237518]": { + "$type": "EditorEntitySortComponent", + "Id": 5681893399601237518 + }, + "Component_[592692962543397545]": { + "$type": "EditorPendingCompositionComponent", + "Id": 592692962543397545 + }, + "Component_[7090012899106946164]": { + "$type": "EditorLockComponent", + "Id": 7090012899106946164 + }, + "Component_[9410832619875640998]": { + "$type": "EditorVisibilityComponent", + "Id": 9410832619875640998 + } + }, + "IsDependencyReady": true + }, + "Entity_[1246125633405]": { + "Id": "Entity_[1246125633405]", + "Name": "Grid", + "Components": { + "Component_[11443347433215807130]": { + "$type": "EditorEntityIconComponent", + "Id": 11443347433215807130 + }, + "Component_[11779275529534764488]": { + "$type": "SelectionComponent", + "Id": 11779275529534764488 + }, + "Component_[14249419413039427459]": { + "$type": "EditorInspectorComponent", + "Id": 14249419413039427459 + }, + "Component_[15448581635946161318]": { + "$type": "AZ::Render::EditorGridComponent", + "Id": 15448581635946161318, + "Controller": { + "Configuration": { + "primarySpacing": 4.0, + "primaryColor": [ + 0.501960813999176, + 0.501960813999176, + 0.501960813999176 + ], + "secondarySpacing": 0.5, + "secondaryColor": [ + 0.250980406999588, + 0.250980406999588, + 0.250980406999588 + ] + } + } + }, + "Component_[1843303322527297409]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 1843303322527297409 + }, + "Component_[380249072065273654]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 380249072065273654, + "Parent Entity": "Entity_[1250420600701]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + -0.10000000149011612 + ] + }, + "Cached World Transform Parent": "Entity_[1250420600701]" + }, + "Component_[7476660583684339787]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7476660583684339787 + }, + "Component_[7557626501215118375]": { + "$type": "EditorEntitySortComponent", + "Id": 7557626501215118375 + }, + "Component_[7984048488947365511]": { + "$type": "EditorVisibilityComponent", + "Id": 7984048488947365511 + }, + "Component_[8118181039276487398]": { + "$type": "EditorOnlyEntityComponent", + "Id": 8118181039276487398 + }, + "Component_[9189909764215270515]": { + "$type": "EditorLockComponent", + "Id": 9189909764215270515 + } + }, + "IsDependencyReady": true + }, + "Entity_[1250420600701]": { + "Id": "Entity_[1250420600701]", + "Name": "test_sponza_material_conversion", + "Components": { + "Component_[11342679732910125733]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 11342679732910125733, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 273579101 + }, + "assetHint": "testdata/test_sponza_material_conversion.azmodel" + } + } + } + }, + "Component_[11482250315251448254]": { + "$type": "EditorEntityIconComponent", + "Id": 11482250315251448254 + }, + "Component_[12520362418832404237]": { + "$type": "EditorVisibilityComponent", + "Id": 12520362418832404237 + }, + "Component_[13922696236864086628]": { + "$type": "EditorInspectorComponent", + "Id": 13922696236864086628, + "ComponentOrderEntryArray": [ + { + "ComponentId": 9795135998007712828 + }, + { + "ComponentId": 11342679732910125733, + "SortIndex": 1 + }, + { + "ComponentId": 14504829236779989058, + "SortIndex": 2 + } + ] + }, + "Component_[14504829236779989058]": { + "$type": "EditorMaterialComponent", + "Id": 14504829236779989058, + "Controller": { + "Configuration": { + "materials": [ + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 40852248 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{1D8B391C-DEB3-549E-9A30-14A6989B1B50}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_floor.azmaterial" + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 842740826 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{F3C97FF0-8FC7-5207-9E97-21D680962068}" + } + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 1262202891 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{AF16DFCF-E1E9-57B9-8F01-A49AAC1962AE}" + } + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 2438226774 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{4310E0FE-532D-5436-A946-49B2E14B0375}" + } + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 2816279700 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{6339FEBB-4293-5CEF-809A-2BE072AC94D6}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_bricks.azmaterial" + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3157644117 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{3EF8BEDB-8DE0-5550-A994-D542086622B7}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_arch.azmaterial" + }, + "PropertyOverrides": { + "general.applySpecularAA": { + "$type": "bool", + "Value": true + } + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3208782114 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{CCA05CBE-2606-59A3-91A9-E46F97980A38}" + } + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3591631827 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{B45DCFD4-6B12-5212-AB92-B64E064155CE}" + } + } + } + }, + { + "Key": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3888291602 + } + }, + "Value": { + "MaterialAsset": { + "assetId": { + "guid": "{E6A159AA-989D-5534-8550-1E002148AC84}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_roof.azmaterial" + } + } + } + ] + } + }, + "materialSlots": [ + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 842740826 + } + }, + "materialAsset": { + "assetId": { + "guid": "{F3C97FF0-8FC7-5207-9E97-21D680962068}" + } + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3208782114 + } + }, + "materialAsset": { + "assetId": { + "guid": "{CCA05CBE-2606-59A3-91A9-E46F97980A38}" + } + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3157644117 + } + }, + "materialAsset": { + "assetId": { + "guid": "{3EF8BEDB-8DE0-5550-A994-D542086622B7}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_arch.azmaterial" + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 2816279700 + } + }, + "materialAsset": { + "assetId": { + "guid": "{6339FEBB-4293-5CEF-809A-2BE072AC94D6}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_bricks.azmaterial" + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 40852248 + } + }, + "materialAsset": { + "assetId": { + "guid": "{1D8B391C-DEB3-549E-9A30-14A6989B1B50}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_floor.azmaterial" + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3888291602 + } + }, + "materialAsset": { + "assetId": { + "guid": "{E6A159AA-989D-5534-8550-1E002148AC84}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_roof.azmaterial" + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 2438226774 + } + }, + "materialAsset": { + "assetId": { + "guid": "{4310E0FE-532D-5436-A946-49B2E14B0375}" + } + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 1262202891 + } + }, + "materialAsset": { + "assetId": { + "guid": "{AF16DFCF-E1E9-57B9-8F01-A49AAC1962AE}" + } + } + }, + { + "id": { + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3591631827 + } + }, + "materialAsset": { + "assetId": { + "guid": "{B45DCFD4-6B12-5212-AB92-B64E064155CE}" + } + } + } + ], + "materialSlotsByLod": [ + [ + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 842740826 + } + }, + "materialAsset": { + "assetId": { + "guid": "{F3C97FF0-8FC7-5207-9E97-21D680962068}" + } + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3208782114 + } + }, + "materialAsset": { + "assetId": { + "guid": "{CCA05CBE-2606-59A3-91A9-E46F97980A38}" + } + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3157644117 + } + }, + "materialAsset": { + "assetId": { + "guid": "{3EF8BEDB-8DE0-5550-A994-D542086622B7}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_arch.azmaterial" + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 2816279700 + } + }, + "materialAsset": { + "assetId": { + "guid": "{6339FEBB-4293-5CEF-809A-2BE072AC94D6}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_bricks.azmaterial" + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 40852248 + } + }, + "materialAsset": { + "assetId": { + "guid": "{1D8B391C-DEB3-549E-9A30-14A6989B1B50}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_floor.azmaterial" + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3888291602 + } + }, + "materialAsset": { + "assetId": { + "guid": "{E6A159AA-989D-5534-8550-1E002148AC84}" + }, + "assetHint": "testdata/test_sponza_material_conversion_mat_roof.azmaterial" + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 2438226774 + } + }, + "materialAsset": { + "assetId": { + "guid": "{4310E0FE-532D-5436-A946-49B2E14B0375}" + } + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 1262202891 + } + }, + "materialAsset": { + "assetId": { + "guid": "{AF16DFCF-E1E9-57B9-8F01-A49AAC1962AE}" + } + } + }, + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{7D2F89D6-2634-5EE6-A122-638377C0CB21}", + "subId": 3591631827 + } + }, + "materialAsset": { + "assetId": { + "guid": "{B45DCFD4-6B12-5212-AB92-B64E064155CE}" + } + } + } + ] + ] + }, + "Component_[16137637180608547307]": { + "$type": "EditorPendingCompositionComponent", + "Id": 16137637180608547307 + }, + "Component_[17072211258387308642]": { + "$type": "EditorOnlyEntityComponent", + "Id": 17072211258387308642 + }, + "Component_[2587501640342227295]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 2587501640342227295 + }, + "Component_[4820742733748380832]": { + "$type": "SelectionComponent", + "Id": 4820742733748380832 + }, + "Component_[5027382790057670521]": { + "$type": "EditorLockComponent", + "Id": 5027382790057670521 + }, + "Component_[7651519254420083868]": { + "$type": "EditorEntitySortComponent", + "Id": 7651519254420083868, + "ChildEntityOrderEntryArray": [ + { + "EntityId": "Entity_[1246125633405]" + }, + { + "EntityId": "Entity_[1228945764221]", + "SortIndex": 1 + }, + { + "EntityId": "Entity_[1220355829629]", + "SortIndex": 2 + }, + { + "EntityId": "Entity_[1224650796925]", + "SortIndex": 3 + }, + { + "EntityId": "Entity_[1233240731517]", + "SortIndex": 4 + }, + { + "EntityId": "Entity_[1237535698813]", + "SortIndex": 5 + }, + { + "EntityId": "Entity_[1241830666109]", + "SortIndex": 6 + } + ] + }, + "Component_[9795135998007712828]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 9795135998007712828, + "Parent Entity": "ContainerEntity", + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 0.10000000149011612 + ] + }, + "Cached World Transform Parent": "ContainerEntity" + } + }, + "IsDependencyReady": true + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion.fbx b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion.fbx new file mode 100644 index 0000000000..638828984a --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b936b72b5b45b52c188bf9f930d6066af65f0d79ff8abf5dc08927d97ac465e +size 55264 diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material new file mode 100644 index 0000000000..cc2c9e785b --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material @@ -0,0 +1,35 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "emissive": { + "color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "irradiance": { + "color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "opacity": { + "factor": 1.0 + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material new file mode 100644 index 0000000000..a4bfb73d12 --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material @@ -0,0 +1,35 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.0, + 1.0, + 0.0, + 1.0 + ] + }, + "emissive": { + "color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "irradiance": { + "color": [ + 0.0, + 1.0, + 0.0, + 1.0 + ] + }, + "opacity": { + "factor": 1.0 + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material new file mode 100644 index 0000000000..fe9c54bc02 --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material @@ -0,0 +1,49 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "textureMap": "Textures/arch_1k_basecolor.png" + }, + "general": { + "applySpecularAA": true + }, + "irradiance": { + "color": [ + 1.0, + 0.885053813457489, + 0.801281750202179, + 1.0 + ] + }, + "metallic": { + "textureMap": "Textures/arch_1k_metallic.png" + }, + "normal": { + "textureMap": "Textures/arch_1k_normal.jpg" + }, + "occlusion": { + "diffuseTextureMap": "Textures/arch_1k_ao.png" + }, + "opacity": { + "factor": 1.0 + }, + "parallax": { + "factor": 0.050999999046325687, + "pdo": true, + "quality": "High", + "useTexture": false + }, + "roughness": { + "textureMap": "Textures/arch_1k_roughness.png" + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material new file mode 100644 index 0000000000..a19afa33e2 --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material @@ -0,0 +1,54 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "textureMap": "Textures/bricks_1k_basecolor.png" + }, + "clearCoat": { + "factor": 0.5, + "normalMap": "Textures/bricks_1k_normal.jpg", + "roughness": 0.5 + }, + "general": { + "applySpecularAA": true + }, + "irradiance": { + "color": [ + 1.0, + 0.9703211784362793, + 0.9703211784362793, + 1.0 + ] + }, + "metallic": { + "textureMap": "Textures/bricks_1k_metallic.png" + }, + "normal": { + "textureMap": "Textures/bricks_1k_normal.jpg" + }, + "occlusion": { + "diffuseTextureMap": "Textures/bricks_1k_ao.png" + }, + "opacity": { + "factor": 1.0 + }, + "parallax": { + "algorithm": "ContactRefinement", + "factor": 0.03500000014901161, + "quality": "Medium", + "useTexture": false + }, + "roughness": { + "textureMap": "Textures/bricks_1k_roughness.png" + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material new file mode 100644 index 0000000000..0c1208d8fb --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material @@ -0,0 +1,51 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "textureMap": "Textures/floor_1k_basecolor.png" + }, + "clearCoat": { + "enable": true, + "influenceMap": "Textures/floor_1k_ao.png", + "normalMap": "Textures/floor_1k_normal.png", + "roughness": 0.25 + }, + "general": { + "applySpecularAA": true + }, + "irradiance": { + "color": [ + 1.0, + 0.9404135346412659, + 0.8688944578170776, + 1.0 + ] + }, + "normal": { + "textureMap": "Textures/floor_1k_normal.png" + }, + "occlusion": { + "diffuseTextureMap": "Textures/floor_1k_ao.png" + }, + "opacity": { + "factor": 1.0 + }, + "parallax": { + "factor": 0.012000000104308129, + "pdo": true, + "useTexture": false + }, + "roughness": { + "textureMap": "Textures/floor_1k_roughness.png" + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material new file mode 100644 index 0000000000..6aad4d644a --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material @@ -0,0 +1,44 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.800000011920929, + 0.800000011920929, + 0.800000011920929, + 1.0 + ], + "textureBlendMode": "Lerp", + "textureMap": "Textures/roof_1k_basecolor.png" + }, + "general": { + "applySpecularAA": true + }, + "metallic": { + "useTexture": false + }, + "normal": { + "factor": 0.5, + "flipY": true, + "textureMap": "Textures/roof_1k_normal.jpg" + }, + "occlusion": { + "diffuseTextureMap": "Textures/roof_1k_ao.png" + }, + "opacity": { + "factor": 1.0 + }, + "parallax": { + "algorithm": "ContactRefinement", + "factor": 0.019999999552965165, + "quality": "Medium", + "useTexture": false + }, + "roughness": { + "textureMap": "Textures/roof_1k_roughness.png" + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material new file mode 100644 index 0000000000..302589dc85 --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material @@ -0,0 +1,35 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.0, + 0.0, + 1.0, + 1.0 + ] + }, + "emissive": { + "color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "irradiance": { + "color": [ + 0.0, + 0.0, + 1.0, + 1.0 + ] + }, + "opacity": { + "factor": 1.0 + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material new file mode 100644 index 0000000000..5217a4e4be --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material @@ -0,0 +1,35 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.800000011920929, + 0.0, + 0.0, + 1.0 + ] + }, + "emissive": { + "color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "irradiance": { + "color": [ + 1.0, + 0.0, + 0.0, + 1.0 + ] + }, + "opacity": { + "factor": 1.0 + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material new file mode 100644 index 0000000000..dba44f7b49 --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material @@ -0,0 +1,19 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "emissive": { + "color": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "opacity": { + "factor": 1.0 + } + } +} \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Assets/TestData/white_latlong_iblskyboxcm.exr b/Gems/AtomContent/Sponza/Assets/TestData/white_latlong_iblskyboxcm.exr new file mode 100644 index 0000000000..56d66de7fc --- /dev/null +++ b/Gems/AtomContent/Sponza/Assets/TestData/white_latlong_iblskyboxcm.exr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9c14dc81887be7647d9afa9e5481634eded0b1d0285b59bb76bb2a91326ca8a +size 3369 diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.rc b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.rc index 5f348297ad..c426156806 100644 --- a/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.rc +++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/AtomFont.rc @@ -81,10 +81,10 @@ BEGIN BEGIN BLOCK "000904b0" BEGIN - VALUE "CompanyName", "Amazon.com, Inc." + VALUE "CompanyName", "Open 3D Foundation" VALUE "FileVersion", "1, 0, 0, 1" VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Lumberyard" + VALUE "ProductName", "O3DE" VALUE "ProductVersion", "1, 0, 0, 1" END END diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/SkyBox/PhysicalSkyComponentConfig.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/SkyBox/PhysicalSkyComponentConfig.h index bf16207a80..c7f82dde2c 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/SkyBox/PhysicalSkyComponentConfig.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/SkyBox/PhysicalSkyComponentConfig.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace AZ { @@ -35,6 +36,8 @@ namespace AZ int m_turbidity = 1; float m_sunRadiusFactor = 1.0f; + SkyBoxFogSettings m_skyBoxFogSettings; + //! Returns characters for a suffix for the light type including a space. " lm" for lumens for example. const char* GetIntensitySuffix() const; @@ -45,6 +48,8 @@ namespace AZ //! Returns the maximum intensity value allowed depending on the m_intensityMode float GetSkyIntensityMax() const; float GetSunIntensityMax() const; + + bool IsFogDisabled() const { return !m_skyBoxFogSettings.m_enable; } }; } } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.cpp index 29f7b56282..981eef159c 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.cpp @@ -79,7 +79,11 @@ namespace AZ // Add the current view which can potentially be the editor view auto atomViewportRequests = AZ::Interface::Get(); const AZ::Name contextName = atomViewportRequests->GetDefaultViewportContextName(); - allSceneViews.insert(atomViewportRequests->GetCurrentView(contextName).get()); + auto currentView = atomViewportRequests->GetCurrentView(contextName); + if (IsEditorView(currentView)) + { + allSceneViews.insert(currentView.get()); + } // calculate blend weights for all cameras PostProcessSettingsInterface::ViewBlendWeightMap perViewBlendWeights; @@ -146,6 +150,13 @@ namespace AZ { m_cameraEntities.insert(cameraId); } + + AZ::RPI::ViewPtr view = nullptr; + AZ::RPI::ViewProviderBus::EventResult(view, cameraId, &AZ::RPI::ViewProvider::GetView); + if (view != nullptr) + { + m_allCameraViews.insert(view.get()); + } } void PostFxLayerComponentController::OnCameraRemoved(const AZ::EntityId& cameraId) @@ -176,6 +187,11 @@ namespace AZ } } + bool PostFxLayerComponentController::IsEditorView(const AZ::RPI::ViewPtr view) + { + return m_allCameraViews.find(view.get()) == m_allCameraViews.end() ? true : false; + } + bool PostFxLayerComponentController::HasTags(const AZ::EntityId& entityId, const AZStd::vector& tags) const { bool hasTag = false; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.h index 6cfa1fe015..05825b4255 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/PostFxLayerComponentController.h @@ -73,13 +73,15 @@ namespace AZ void BusConnectToTags(); const AZStd::unordered_set& GetCameraEntityList() const; - + bool IsEditorView(const AZ::RPI::ViewPtr view); bool HasTags(const AZ::EntityId& entityId, const AZStd::vector& tags) const; // list of entities containing tags set in this component's property. AZStd::unordered_set m_taggedCameraEntities; // a list of cameras tracked by this component. This is used if no camera tags are specified. AZStd::unordered_set m_cameraEntities; + // a list of camera views in the scene. This is used to test if a view is an editor view. + AZStd::unordered_set m_allCameraViews; PostProcessFeatureProcessorInterface* m_featureProcessorInterface = nullptr; PostProcessSettingsInterface* m_postProcessInterface = nullptr; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/EditorPhysicalSkyComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/EditorPhysicalSkyComponent.cpp index 8f9b98c15c..265053a9e1 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/EditorPhysicalSkyComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/EditorPhysicalSkyComponent.cpp @@ -68,13 +68,17 @@ namespace AZ ->Attribute(AZ::Edit::Attributes::Min, 1) ->Attribute(AZ::Edit::Attributes::Max, 10) ->Attribute(AZ::Edit::Attributes::Step, 1) + ->DataElement(AZ::Edit::UIHandlers::Default, &PhysicalSkyComponentConfig::m_skyBoxFogSettings, "Fog", "Fog settings for rendering on top of physical sky") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; } } if (auto behaviorContext = azrtti_cast(context)) { - behaviorContext->Class()->RequestBus("PhysicalSkyRequestBus"); + behaviorContext->Class() + ->RequestBus("PhysicalSkyRequestBus") + ->RequestBus("SkyBoxFogRequestBus"); behaviorContext->ConstantProperty("EditorPhysicalSkyComponentTypeId", BehaviorConstant(Uuid(EditorPhysicalSkyComponentTypeId))) ->Attribute(AZ::Script::Attributes::Module, "render") diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp index 72cc765238..7ab8267986 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/HDRiSkyboxComponentController.cpp @@ -69,7 +69,7 @@ namespace AZ m_featureProcessorInterface = RPI::Scene::GetFeatureProcessorForEntity(entityId); // only activate if there is no other skybox activate - if (!m_featureProcessorInterface->IsEnable()) + if (!m_featureProcessorInterface->IsEnabled()) { m_featureProcessorInterface->SetSkyboxMode(SkyBoxMode::Cubemap); m_featureProcessorInterface->Enable(true); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponent.cpp index 024abc13cf..558cf09f65 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponent.cpp @@ -34,7 +34,9 @@ namespace AZ if (auto behaviorContext = azrtti_cast(context)) { - behaviorContext->Class()->RequestBus("PhysicalSkyRequestBus"); + behaviorContext->Class() + ->RequestBus("PhysicalSkyRequestBus") + ->RequestBus("SkyBoxFogRequestBus"); behaviorContext->ConstantProperty("PhysicalSkyComponentTypeId", BehaviorConstant(Uuid(PhysicalSkyComponentTypeId))) ->Attribute(AZ::Script::Attributes::Module, "render") diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentConfig.cpp index e0c07fe0ec..b2fe88756f 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentConfig.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentConfig.cpp @@ -29,6 +29,7 @@ namespace AZ ->Field("SunIntensity", &PhysicalSkyComponentConfig::m_sunIntensity) ->Field("Turbidity", &PhysicalSkyComponentConfig::m_turbidity) ->Field("SunRadiusFactor", &PhysicalSkyComponentConfig::m_sunRadiusFactor) + ->Field("FogSettings", &PhysicalSkyComponentConfig::m_skyBoxFogSettings) ; } } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp index 192c1ad509..189a338967 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.cpp @@ -12,8 +12,6 @@ #include #include - - #include namespace AZ @@ -34,6 +32,9 @@ namespace AZ if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->EBus("PhysicalSkyRequestBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Category, "render") + ->Attribute(AZ::Script::Attributes::Module, "render") ->Event("SetTurbidity", &PhysicalSkyRequestBus::Events::SetTurbidity) ->Event("GetTurbidity", &PhysicalSkyRequestBus::Events::GetTurbidity) ->Event("SetSunRadiusFactor", &PhysicalSkyRequestBus::Events::SetSunRadiusFactor) @@ -76,7 +77,7 @@ namespace AZ m_featureProcessorInterface = RPI::Scene::GetFeatureProcessorForEntity(entityId); // only activate if there is no other skybox activate - if (!m_featureProcessorInterface->IsEnable()) + if (!m_featureProcessorInterface->IsEnabled()) { m_featureProcessorInterface->SetSkyboxMode(SkyBoxMode::PhysicalSky); m_featureProcessorInterface->Enable(true); @@ -95,8 +96,10 @@ namespace AZ const AZ::Transform& transform = m_transformInterface ? m_transformInterface->GetWorldTM() : Transform::Identity(); m_featureProcessorInterface->SetSunPosition(GetSunTransform(transform)); + m_featureProcessorInterface->SetFogSettings(m_configuration.m_skyBoxFogSettings); PhysicalSkyRequestBus::Handler::BusConnect(m_entityId); + SkyBoxFogRequestBus::Handler::BusConnect(m_entityId); TransformNotificationBus::Handler::BusConnect(m_entityId); m_isActive = true; @@ -113,8 +116,9 @@ namespace AZ // Run deactivate if this skybox is activate if (m_isActive) { - PhysicalSkyRequestBus::Handler::BusDisconnect(m_entityId); - TransformNotificationBus::Handler::BusDisconnect(m_entityId); + PhysicalSkyRequestBus::Handler::BusDisconnect(); + SkyBoxFogRequestBus::Handler::BusDisconnect(); + TransformNotificationBus::Handler::BusDisconnect(); m_featureProcessorInterface->Enable(false); m_featureProcessorInterface = nullptr; @@ -229,5 +233,49 @@ namespace AZ return SunPosition(atan2(sunPosition.GetZ(), sunPosition.GetX()), asin(sunPosition.GetY())); } + + void PhysicalSkyComponentController::SetEnabled(bool enable) + { + m_configuration.m_skyBoxFogSettings.m_enable = enable; + m_featureProcessorInterface->SetFogEnabled(enable); + } + + bool PhysicalSkyComponentController::IsEnabled() const + { + return m_configuration.m_skyBoxFogSettings.m_enable; + } + + void PhysicalSkyComponentController::SetColor(const AZ::Color& color) + { + m_configuration.m_skyBoxFogSettings.m_color = color; + m_featureProcessorInterface->SetFogColor(color); + } + + const AZ::Color& PhysicalSkyComponentController::GetColor() const + { + return m_configuration.m_skyBoxFogSettings.m_color; + } + + void PhysicalSkyComponentController::SetTopHeight(float topHeight) + { + m_configuration.m_skyBoxFogSettings.m_topHeight = topHeight; + m_featureProcessorInterface->SetFogTopHeight(topHeight); + } + + float PhysicalSkyComponentController::GetTopHeight() const + { + return m_configuration.m_skyBoxFogSettings.m_topHeight; + } + + void PhysicalSkyComponentController::SetBottomHeight(float bottomHeight) + { + m_configuration.m_skyBoxFogSettings.m_bottomHeight = bottomHeight; + m_featureProcessorInterface->SetFogBottomHeight(bottomHeight); + } + + float PhysicalSkyComponentController::GetBottomHeight() const + { + return m_configuration.m_skyBoxFogSettings.m_bottomHeight; + } } } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.h index ddd17183ea..0a5f3aac41 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/SkyBox/PhysicalSkyComponentController.h @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace AZ @@ -25,6 +26,7 @@ namespace AZ class PhysicalSkyComponentController final : public TransformNotificationBus::Handler , public PhysicalSkyRequestBus::Handler + , public SkyBoxFogRequestBus::Handler { public: friend class EditorPhysicalSkyComponent; @@ -63,7 +65,17 @@ namespace AZ float GetSunIntensity(PhotometricUnit unit) override; float GetSunIntensity() override; - //! Get Sun azimuth and altitude from entity transfom, without scale + // SkyBoxFogRequestBus::Handler overrides ... + void SetEnabled(bool enable) override; + bool IsEnabled() const override; + void SetColor(const AZ::Color& color) override; + const AZ::Color& GetColor() const override; + void SetTopHeight(float topHeight) override; + float GetTopHeight() const override; + void SetBottomHeight(float bottomHeight) override; + float GetBottomHeight() const override; + + //! Get Sun azimuth and altitude from entity transform, without scale SunPosition GetSunTransform(const AZ::Transform& world); TransformInterface* m_transformInterface = nullptr; diff --git a/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.cpp b/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.cpp index c9ab5a135e..b21c008353 100644 --- a/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.cpp +++ b/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -540,11 +541,10 @@ namespace AudioControls } //-------------------------------------------------------------------------------------------// - AZStd::string CAudioSystemEditor_wwise::GetDataPath() const + AZ::IO::FixedMaxPath CAudioSystemEditor_wwise::GetDataPath() const { - AZStd::string path(Path::GetEditingGameDataFolder()); - AZ::StringFunc::Path::Join(path.c_str(), "sounds/wwise_project/", path); - return path; + auto projectPath = AZ::IO::FixedMaxPath{ AZ::Utils::GetProjectPath() }; + return (projectPath / "sounds" / "wwise_project"); } } // namespace AudioControls diff --git a/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h b/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h index ee7b54217d..e2a9fdf5d7 100644 --- a/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h +++ b/Gems/AudioEngineWwise/Code/Source/Editor/AudioSystemEditor_wwise.h @@ -86,7 +86,7 @@ namespace AudioControls const AZStd::string_view GetTypeIcon(TImplControlType type) const override; const AZStd::string_view GetTypeIconSelected(TImplControlType type) const override; AZStd::string GetName() const override; - AZStd::string GetDataPath() const; + AZ::IO::FixedMaxPath GetDataPath() const override; void DataSaved() override {} void ConnectionRemoved(IAudioSystemControl* control) override; ////////////////////////////////////////////////////////// diff --git a/Gems/AudioEngineWwise/Code/Source/Editor/AudioWwiseLoader.cpp b/Gems/AudioEngineWwise/Code/Source/Editor/AudioWwiseLoader.cpp index 074e25d39a..3f2aac2b98 100644 --- a/Gems/AudioEngineWwise/Code/Source/Editor/AudioWwiseLoader.cpp +++ b/Gems/AudioEngineWwise/Code/Source/Editor/AudioWwiseLoader.cpp @@ -54,12 +54,12 @@ namespace AudioControls void CAudioWwiseLoader::Load(CAudioSystemEditor_wwise* audioSystemImpl) { m_audioSystemImpl = audioSystemImpl; - const AZStd::string wwiseProjectFullPath(m_audioSystemImpl->GetDataPath()); - LoadControlsInFolder(wwiseProjectFullPath + WwiseStrings::GameParametersFolder); - LoadControlsInFolder(wwiseProjectFullPath + WwiseStrings::GameStatesFolder); - LoadControlsInFolder(wwiseProjectFullPath + WwiseStrings::SwitchesFolder); - LoadControlsInFolder(wwiseProjectFullPath + WwiseStrings::EventsFolder); - LoadControlsInFolder(wwiseProjectFullPath + WwiseStrings::EnvironmentsFolder); + const AZ::IO::FixedMaxPath wwiseProjectFullPath{ m_audioSystemImpl->GetDataPath() }; + LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::GameParametersFolder }.Native()); + LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::GameStatesFolder }.Native()); + LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::SwitchesFolder }.Native()); + LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::EventsFolder }.Native()); + LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::EnvironmentsFolder }.Native()); LoadSoundBanks(Audio::Wwise::GetBanksRootPath(), "", false); } diff --git a/Gems/AudioSystem/Code/Include/Editor/IAudioSystemEditor.h b/Gems/AudioSystem/Code/Include/Editor/IAudioSystemEditor.h index ac2bc8c0b8..0ccd1390af 100644 --- a/Gems/AudioSystem/Code/Include/Editor/IAudioSystemEditor.h +++ b/Gems/AudioSystem/Code/Include/Editor/IAudioSystemEditor.h @@ -14,6 +14,7 @@ #pragma once #include +#include #include #include @@ -151,7 +152,7 @@ namespace AudioControls //! Gets the folder where the implementation specific controls data are stored. //! This is used by the ACE to update if controls are changed while the editor is open. //! @return String with the path to the folder where the implementation specific controls are stored. - virtual AZStd::string GetDataPath() const = 0; + virtual AZ::IO::FixedMaxPath GetDataPath() const = 0; //! Informs the plugin that the ACE has saved the data in case it needs to do any clean up. virtual void DataSaved() = 0; diff --git a/Gems/AudioSystem/Code/Source/Editor/AudioControlsEditorWindow.cpp b/Gems/AudioSystem/Code/Source/Editor/AudioControlsEditorWindow.cpp index 7e3528362e..68d5a30af9 100644 --- a/Gems/AudioSystem/Code/Source/Editor/AudioControlsEditorWindow.cpp +++ b/Gems/AudioSystem/Code/Source/Editor/AudioControlsEditorWindow.cpp @@ -218,7 +218,7 @@ namespace AudioControls IAudioSystemEditor* pAudioSystemImpl = CAudioControlsEditorPlugin::GetAudioSystemEditorImpl(); if (pAudioSystemImpl) { - StartWatchingFolder(pAudioSystemImpl->GetDataPath()); + StartWatchingFolder(pAudioSystemImpl->GetDataPath().LexicallyNormal().Native()); m_pMiddlewareDockWidget->setWindowTitle(QString(pAudioSystemImpl->GetName().c_str()) + " Controls"); } } diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.cpp index bd0d998737..4bc6d51d94 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.cpp @@ -10,6 +10,7 @@ * */ +#include #include #include #include @@ -717,7 +718,7 @@ namespace EMotionFX const size_t shapeCount = nodeConfig->m_shapes.size(); if (m_colliderIndex >= shapeCount) { - outResult = AZStd::string::format("Cannot remove collider. The joint '%s' is only holding %zu colliders and the index %zu is out of range.", m_jointName.c_str(), shapeCount, m_colliderIndex); + outResult = AZStd::string::format("Cannot remove collider. The joint '%s' is only holding %zu colliders and the index %llu is out of range.", m_jointName.c_str(), shapeCount, m_colliderIndex); return false; } diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.h b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.h index bb84e955ef..51608e3055 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.h +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/ColliderCommands.h @@ -222,7 +222,7 @@ namespace EMotionFX private: PhysicsSetup::ColliderConfigType m_configType; - size_t m_colliderIndex; + AZ::u64 m_colliderIndex; bool m_oldIsDirty; AZStd::string m_oldContents; diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MorphTargetRule.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MorphTargetRule.h index e2a86116d0..99075d4903 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MorphTargetRule.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MorphTargetRule.h @@ -73,7 +73,7 @@ namespace EMotionFX static size_t DetectMorphTargetAnimations(const AZ::SceneAPI::Containers::Scene& scene); protected: - size_t m_morphAnimationCount; + AZ::u64 m_morphAnimationCount; AZStd::string m_descriptionText; }; diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionAdditiveRule.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionAdditiveRule.h index 40839cc5b8..718ab04529 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionAdditiveRule.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionAdditiveRule.h @@ -42,7 +42,7 @@ namespace EMotionFX static void Reflect(AZ::ReflectContext* context); protected: - size_t m_sampleFrameIndex; + AZ::u64 m_sampleFrameIndex; }; } // Rule } // Pipeline diff --git a/Gems/GraphModel/Code/Include/GraphModel/Integration/GraphCanvasMetadata.h b/Gems/GraphModel/Code/Include/GraphModel/Integration/GraphCanvasMetadata.h index d08acd0b17..1937341cd2 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Integration/GraphCanvasMetadata.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Integration/GraphCanvasMetadata.h @@ -14,6 +14,7 @@ // AZ #include +#include #include // Graph Model diff --git a/Gems/GraphModel/Code/Include/GraphModel/Model/Graph.h b/Gems/GraphModel/Code/Include/GraphModel/Model/Graph.h index 50c1287080..f3dd85575f 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Model/Graph.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Model/Graph.h @@ -14,10 +14,10 @@ // AZ #include #include -#include #include // Graph Model +#include #include #include @@ -136,9 +136,9 @@ namespace GraphModel //! Set/gets a bundle of generic metadata that is provided by the node graph UI //! system. This may include node positions, comment blocks, node groupings, and //! bookmarks, for example. - void SetUiMetadata(const AZStd::any& uiMetadata); - const AZStd::any& GetUiMetadata() const; - AZStd::any& GetUiMetadata(); + void SetUiMetadata(const GraphModelIntegration::GraphCanvasMetadata& uiMetadata); + const GraphModelIntegration::GraphCanvasMetadata& GetUiMetadata() const; + GraphModelIntegration::GraphCanvasMetadata& GetUiMetadata(); AZStd::shared_ptr FindSlot(const Endpoint& endpoint); @@ -157,7 +157,7 @@ namespace GraphModel ConnectionList m_connections; //! Used to store and serialize metadata from the graph UI, like node positions, comments, group boxes, etc. - AZStd::any m_uiMetadata; + GraphModelIntegration::GraphCanvasMetadata m_uiMetadata; //! Used to store all of our node <-> wrapper node mappings NodeWrappingMap m_nodeWrappings; diff --git a/Gems/GraphModel/Code/Include/GraphModel/Model/Slot.h b/Gems/GraphModel/Code/Include/GraphModel/Model/Slot.h index 0ce02ffa9d..0b012fd2cd 100644 --- a/Gems/GraphModel/Code/Include/GraphModel/Model/Slot.h +++ b/Gems/GraphModel/Code/Include/GraphModel/Model/Slot.h @@ -12,6 +12,7 @@ #pragma once // AZ +#include #include #include #include @@ -165,6 +166,32 @@ namespace GraphModel ExtendableSlotConfiguration m_extendableSlotConfiguration; }; + //! Custom JSON serializer for Slot because we use an AZStd::any for m_value + class JsonSlotSerializer + : public AZ::BaseJsonSerializer + { + public: + AZ_RTTI(JsonSlotSerializer, "{8AC96D70-7BCD-4D68-8813-269938982D51}", AZ::BaseJsonSerializer); + AZ_CLASS_ALLOCATOR(JsonSlotSerializer, AZ::SystemAllocator, 0); + + AZ::JsonSerializationResult::Result Load( + void* outputValue, const AZ::Uuid& outputValueTypeId, const rapidjson::Value& inputValue, + AZ::JsonDeserializerContext& context) override; + + AZ::JsonSerializationResult::Result Store( + rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const AZ::Uuid& valueTypeId, + AZ::JsonSerializerContext& context) override; + + private: + template + bool LoadAny( + AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context, + AZ::JsonSerializationResult::ResultCode& result); + template + bool StoreAny( + const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context, + AZ::JsonSerializationResult::ResultCode& result); + }; //!!! Start in Graph.h for high level GraphModel documentation !!! @@ -180,6 +207,7 @@ namespace GraphModel class Slot : public GraphElement, public AZStd::enable_shared_from_this { friend class Graph; // So the Graph can update the Slot's cache of Connection pointers + friend class JsonSlotSerializer; // So we can set the m_value and m_subId directly from the serializer public: AZ_CLASS_ALLOCATOR(Slot, AZ::SystemAllocator, 0); diff --git a/Gems/GraphModel/Code/Source/Integration/GraphController.cpp b/Gems/GraphModel/Code/Source/Integration/GraphController.cpp index f6ce6282f4..bb5291637e 100644 --- a/Gems/GraphModel/Code/Source/Integration/GraphController.cpp +++ b/Gems/GraphModel/Code/Source/Integration/GraphController.cpp @@ -1338,11 +1338,7 @@ namespace GraphModelIntegration GraphCanvasMetadata* GraphController::GetGraphMetadata() { - if (!m_graph->GetUiMetadata().is()) - { - m_graph->SetUiMetadata(AZStd::any(GraphCanvasMetadata())); - } - GraphCanvasMetadata* graphCanvasMetadata = AZStd::any_cast(&m_graph->GetUiMetadata()); + GraphCanvasMetadata* graphCanvasMetadata = &m_graph->GetUiMetadata(); AZ_Assert(graphCanvasMetadata, "GraphCanvasMetadata not initialized"); return graphCanvasMetadata; } diff --git a/Gems/GraphModel/Code/Source/Model/Graph.cpp b/Gems/GraphModel/Code/Source/Model/Graph.cpp index 809679e9f6..e82b5d8e15 100644 --- a/Gems/GraphModel/Code/Source/Model/Graph.cpp +++ b/Gems/GraphModel/Code/Source/Model/Graph.cpp @@ -37,7 +37,7 @@ namespace GraphModel if (serializeContext) { serializeContext->Class() - ->Version(1) + ->Version(2) ->Field("m_nodes", &Graph::m_nodes) ->Field("m_connections", &Graph::m_connections) ->Field("m_uiMetadata", &Graph::m_uiMetadata) @@ -312,19 +312,19 @@ namespace GraphModel } - void Graph::SetUiMetadata(const AZStd::any& uiMetadata) + void Graph::SetUiMetadata(const GraphModelIntegration::GraphCanvasMetadata& uiMetadata) { m_uiMetadata = uiMetadata; } - const AZStd::any& Graph::GetUiMetadata() const + const GraphModelIntegration::GraphCanvasMetadata& Graph::GetUiMetadata() const { return m_uiMetadata; } - AZStd::any& Graph::GetUiMetadata() + GraphModelIntegration::GraphCanvasMetadata& Graph::GetUiMetadata() { return m_uiMetadata; } diff --git a/Gems/GraphModel/Code/Source/Model/Slot.cpp b/Gems/GraphModel/Code/Source/Model/Slot.cpp index e5fb9f8cb8..6433129af8 100644 --- a/Gems/GraphModel/Code/Source/Model/Slot.cpp +++ b/Gems/GraphModel/Code/Source/Model/Slot.cpp @@ -11,9 +11,14 @@ */ // AZ +#include +#include +#include +#include #include #include #include +#include #include // Graph Model @@ -294,13 +299,164 @@ namespace GraphModel ///////////////////////////////////////////////////////// // Slot + AZ::JsonSerializationResult::Result JsonSlotSerializer::Load( + void* outputValue, const AZ::Uuid& outputValueTypeId, const rapidjson::Value& inputValue, + AZ::JsonDeserializerContext& context) + { + namespace JSR = AZ::JsonSerializationResult; + + AZ_Assert( + azrtti_typeid() == outputValueTypeId, + "Unable to deserialize Slot from json because the provided type is %s.", + outputValueTypeId.ToString().c_str()); + + Slot* slot = reinterpret_cast(outputValue); + AZ_Assert(slot, "Output value for JsonSlotSerializer can't be null."); + + JSR::ResultCode result(JSR::Tasks::ReadField); + + auto serializedSlotValue = inputValue.FindMember("m_value"); + if (serializedSlotValue != inputValue.MemberEnd()) + { + AZStd::any slotValue; + if (LoadAny(slotValue, serializedSlotValue->value, context, result) || + LoadAny(slotValue, serializedSlotValue->value, context, result) || + LoadAny(slotValue, serializedSlotValue->value, context, result) || + LoadAny(slotValue, serializedSlotValue->value, context, result) || + LoadAny(slotValue, serializedSlotValue->value, context, result) || + LoadAny(slotValue, serializedSlotValue->value, context, result) || + LoadAny(slotValue, serializedSlotValue->value, context, result) || + LoadAny(slotValue, serializedSlotValue->value, context, result)) + { + slot->m_value = slotValue; + } + } + + // Load m_subId normally because it's just an int + { + SlotSubId slotSubId = 0; + result.Combine(ContinueLoadingFromJsonObjectField( + &slotSubId, azrtti_typeid(), inputValue, + "m_subId", context)); + slot->m_subId = slotSubId; + } + + return context.Report( + result, + result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded Slot information." + : "Failed to load Slot information."); + } + + AZ::JsonSerializationResult::Result JsonSlotSerializer::Store( + rapidjson::Value& outputValue, const void* inputValue, [[maybe_unused]] const void* defaultValue, const AZ::Uuid& valueTypeId, + AZ::JsonSerializerContext& context) + { + namespace JSR = AZ::JsonSerializationResult; + + AZ_Assert( + azrtti_typeid() == valueTypeId, + "Unable to Serialize Slot because the provided type is %s.", valueTypeId.ToString().c_str()); + + const Slot* slot = reinterpret_cast(inputValue); + AZ_Assert(slot, "Input value for JsonSlotSerializer can't be null."); + + outputValue.SetObject(); + + JSR::ResultCode result(JSR::Tasks::WriteValue); + + { + AZ::ScopedContextPath subPathPropertyOverrides(context, "m_value"); + + if (!slot->m_value.empty()) + { + rapidjson::Value outputPropertyValue; + if (StoreAny(slot->m_value, outputPropertyValue, context, result) || + StoreAny(slot->m_value, outputPropertyValue, context, result) || + StoreAny(slot->m_value, outputPropertyValue, context, result) || + StoreAny(slot->m_value, outputPropertyValue, context, result) || + StoreAny(slot->m_value, outputPropertyValue, context, result) || + StoreAny(slot->m_value, outputPropertyValue, context, result) || + StoreAny(slot->m_value, outputPropertyValue, context, result) || + StoreAny(slot->m_value, outputPropertyValue, context, result)) + { + outputValue.AddMember("m_value", outputPropertyValue, context.GetJsonAllocator()); + } + } + } + + { + AZ::ScopedContextPath subSlotId(context, "m_subId"); + SlotSubId defaultSubId = 0; + + result.Combine(ContinueStoringToJsonObjectField( + outputValue, "m_subId", &slot->m_subId, &defaultSubId, + azrtti_typeid(), context)); + } + + return context.Report( + result, + result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored MaterialAssignment information." + : "Failed to store MaterialAssignment information."); + } + + template + bool JsonSlotSerializer::LoadAny( + AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context, + AZ::JsonSerializationResult::ResultCode& result) + { + auto valueItr = inputPropertyValue.FindMember("Value"); + auto typeItr = inputPropertyValue.FindMember("$type"); + if ((valueItr != inputPropertyValue.MemberEnd()) && (typeItr != inputPropertyValue.MemberEnd())) + { + // Requiring explicit type info to differentiate between colors versus vectors and numeric types + const AZ::Uuid baseTypeId = azrtti_typeid(); + AZ::Uuid typeId = AZ::Uuid::CreateNull(); + result.Combine(LoadTypeId(typeId, inputPropertyValue, context, &baseTypeId)); + + if (typeId == azrtti_typeid()) + { + T value; + result.Combine(ContinueLoadingFromJsonObjectField(&value, azrtti_typeid(), inputPropertyValue, "Value", context)); + propertyValue = value; + return true; + } + } + return false; + } + + template + bool JsonSlotSerializer::StoreAny( + const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context, + AZ::JsonSerializationResult::ResultCode& result) + { + if (propertyValue.is()) + { + outputPropertyValue.SetObject(); + + // Storing explicit type info to differentiate between colors versus vectors and numeric types + rapidjson::Value typeValue; + result.Combine(StoreTypeId(typeValue, azrtti_typeid(), context)); + outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator()); + + T value = AZStd::any_cast(propertyValue); + result.Combine( + ContinueStoringToJsonObjectField(outputPropertyValue, "Value", &value, nullptr, azrtti_typeid(), context)); + return true; + } + return false; + } + void Slot::Reflect(AZ::ReflectContext* context) { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) + if (auto jsonContext = azrtti_cast(context)) + { + jsonContext->Serializer()->HandlesType(); + } + + if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(0) + ->Version(1) ->Field("m_value", &Slot::m_value) ->Field("m_subId", &Slot::m_subId) // m_slotDescription is not reflected because that data is populated procedurally by each node diff --git a/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.cpp b/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.cpp index 3879cd2597..2f3a7d7ab4 100644 --- a/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.cpp +++ b/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.cpp @@ -460,10 +460,10 @@ namespace LandscapeCanvasEditor GraphCanvas::StyleManagerRequestBus::Event(editorId, &GraphCanvas::StyleManagerRequests::RegisterDataPaletteStyle, LandscapeCanvas::AreaTypeId, "VegetationAreaDataColorPalette"); LandscapeCanvas::LandscapeCanvasRequestBus::Handler::BusConnect(); - AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect(); AzToolsFramework::EditorPickModeNotificationBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId()); AzToolsFramework::EntityCompositionNotificationBus::Handler::BusConnect(); AzToolsFramework::ToolsApplicationNotificationBus::Handler::BusConnect(); + AzToolsFramework::Prefab::PrefabPublicNotificationBus::Handler::BusConnect(); CrySystemEventBus::Handler::BusConnect(); AZ::EntitySystemBus::Handler::BusConnect(); @@ -480,6 +480,7 @@ namespace LandscapeCanvasEditor { AZ::EntitySystemBus::Handler::BusDisconnect(); CrySystemEventBus::Handler::BusDisconnect(); + AzToolsFramework::Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect(); AzToolsFramework::ToolsApplicationNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect(); @@ -883,6 +884,10 @@ namespace LandscapeCanvasEditor if (landscapeCanvasComponent) { landscapeCanvasComponent->m_graph = *m_serializeContext->CloneObject(graph.get()); + + // Mark the Landscape Canvas entity as dirty so the changes to the graph will be picked up on the next save + AzToolsFramework::ScopedUndoBatch undo("Update Landscape Canvas Graph"); + AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::Bus::Events::AddDirtyEntity, rootEntityId); } } } @@ -1572,7 +1577,7 @@ namespace LandscapeCanvasEditor void MainWindow::HandleEditorEntityCreated(const AZ::EntityId& entityId, GraphCanvas::GraphId graphId) { - if (m_ignoreGraphUpdates) + if (m_ignoreGraphUpdates || m_prefabPropagationInProgress) { return; } @@ -1622,6 +1627,11 @@ namespace LandscapeCanvasEditor void MainWindow::OnEditorEntityDeleted(const AZ::EntityId& entityId) { + if (m_prefabPropagationInProgress) + { + return; + } + m_queuedEntityDeletes.push_back(entityId); QTimer::singleShot(0, [this, entityId]() { @@ -2456,6 +2466,11 @@ namespace LandscapeCanvasEditor void MainWindow::EntityParentChanged(AZ::EntityId entityId, AZ::EntityId newParentId, AZ::EntityId oldParentId) { + if (m_prefabPropagationInProgress) + { + return; + } + GraphCanvas::GraphId oldGraphId = FindGraphContainingEntity(oldParentId); GraphCanvas::GraphId newGraphId = FindGraphContainingEntity(newParentId); @@ -2482,6 +2497,20 @@ namespace LandscapeCanvasEditor } } + void MainWindow::OnPrefabInstancePropagationBegin() + { + // Ignore graph updates during prefab propagation because the entities will be + // deleted and re-created, which would inadvertantly trigger our logic to close + // the graph when the corresponding entity is deleted. + m_prefabPropagationInProgress = true; + } + + void MainWindow::OnPrefabInstancePropagationEnd() + { + // See comment above in OnPrefabInstancePropagationBegin + m_prefabPropagationInProgress = false; + } + void MainWindow::OnCryEditorEndCreate() { UpdateGraphEnabled(); @@ -2490,6 +2519,15 @@ namespace LandscapeCanvasEditor void MainWindow::OnCryEditorEndLoad() { UpdateGraphEnabled(); + + AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect(); + } + + void MainWindow::OnCryEditorCloseScene() + { + UpdateGraphEnabled(); + + AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect(); } void MainWindow::OnCryEditorSceneClosed() diff --git a/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.h b/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.h index eddf998d8d..e6887eecfd 100644 --- a/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.h +++ b/Gems/LandscapeCanvas/Code/Source/Editor/MainWindow.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,7 @@ namespace LandscapeCanvasEditor , private AzToolsFramework::EntityCompositionNotificationBus::Handler , private AzToolsFramework::PropertyEditorEntityChangeNotificationBus::MultiHandler , private AzToolsFramework::ToolsApplicationNotificationBus::Handler + , private AzToolsFramework::Prefab::PrefabPublicNotificationBus::Handler , private CrySystemEventBus::Handler { Q_OBJECT @@ -183,10 +185,15 @@ namespace LandscapeCanvasEditor void EntityParentChanged(AZ::EntityId entityId, AZ::EntityId newParentId, AZ::EntityId oldParentId) override; //////////////////////////////////////////////////////////////////////// + //! PrefabPublicNotificationBus overrides + void OnPrefabInstancePropagationBegin() override; + void OnPrefabInstancePropagationEnd() override; + //////////////////////////////////////////////////////////////////////// // CrySystemEventBus overrides void OnCryEditorEndCreate() override; void OnCryEditorEndLoad() override; + void OnCryEditorCloseScene() override; void OnCryEditorSceneClosed() override; //////////////////////////////////////////////////////////////////////// @@ -246,6 +253,7 @@ namespace LandscapeCanvasEditor AZ::SerializeContext* m_serializeContext = nullptr; bool m_ignoreGraphUpdates = false; + bool m_prefabPropagationInProgress = false; bool m_inObjectPickMode = false; using DeletedNodePositionsMap = AZStd::unordered_map; diff --git a/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake b/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake index 715762b58c..4d5680a30d 100644 --- a/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake +++ b/Gems/LmbrCentral/Code/Platform/Mac/lrelease_mac.cmake @@ -8,12 +8,3 @@ # remove or modify any license notices. This file is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # - -add_custom_command(TARGET LmbrCentral.Editor POST_BUILD - COMMAND "${CMAKE_COMMAND}" -P "${LY_ROOT_FOLDER}/cmake/Platform/Mac/RPathChange.cmake" - "$/lrelease" - @loader_path/../lib - "${QT_PATH}/lib" - COMMENT "Patching lrelease..." - VERBATIM -) diff --git a/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake b/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake index 73e1fb82c1..4d5680a30d 100644 --- a/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake +++ b/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake @@ -8,19 +8,3 @@ # remove or modify any license notices. This file is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # - -add_custom_command(TARGET LmbrCentral.Editor POST_BUILD - COMMAND "${CMAKE_COMMAND}" - -DLY_TIMESTAMP_REFERENCE=$/lrelease.exe - -DLY_LOCK_FILE=$/qtdeploy.lock - -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake - EXEC_COMMAND "${CMAKE_COMMAND}" -E - env PATH="${QT_PATH}/bin" - ${WINDEPLOYQT_EXECUTABLE} - $<$:--pdb> - --verbose 0 - --no-compiler-runtime - $/lrelease.exe - COMMENT "Patching lrelease..." - VERBATIM -) diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h index 19689171c5..9f2f9f4804 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/MultiplayerComponent.h @@ -63,10 +63,10 @@ namespace Multiplayer //! @} NetEntityId GetNetEntityId() const; - bool IsAuthority() const; - bool IsAutonomous() const; - bool IsServer() const; - bool IsClient() const; + bool IsNetEntityRoleAuthority() const; + bool IsNetEntityRoleAutonomous() const; + bool IsNetEntityRoleServer() const; + bool IsNetEntityRoleClient() const; ConstNetworkEntityHandle GetEntityHandle() const; NetworkEntityHandle GetEntityHandle(); void MarkDirty(); diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h index 7d9b7d4086..dd4b9588e4 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h @@ -64,10 +64,23 @@ namespace Multiplayer //! @} NetEntityRole GetNetEntityRole() const; - bool IsAuthority() const; - bool IsAutonomous() const; - bool IsServer() const; - bool IsClient() const; + + //! IsNetEntityRoleAuthority + //! @return true if this network entity is an authoritative proxy on a server (full authority); otherwise false. + bool IsNetEntityRoleAuthority() const; + + //! IsNetEntityRoleAutonomous + //! @return true if this network entity is an autonomous proxy on a client (can execute local prediction) or if this network entity is an authoritative proxy on a server but has autonomous privileges (ie: a host who is also a player); otherwise false. + bool IsNetEntityRoleAutonomous() const; + + //! IsNetEntityRoleServer + //! @return true if this network entity is a simulated proxy on a server (ie: a different server may have authority for this entity, but the entity has been replicated on this server; otherwise false. + bool IsNetEntityRoleServer() const; + + //! IsNetEntityRoleClient + //! @return true if this network entity is a simulated proxy on a client; otherwise false. + bool IsNetEntityRoleClient() const; + bool HasController() const; NetEntityId GetNetEntityId() const; const PrefabEntityId& GetPrefabEntityId() const; diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 44472422c7..ac3f4e5956 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -30,13 +30,13 @@ namespace Multiplayer //! Collection of types of Multiplayer Connections enum class MultiplayerAgentType { - Uninitialized, ///< Agent is uninitialized. - Client, ///< A Client connected to either a server or host. - ClientServer, ///< A Client that also hosts and is the authority of the session - DedicatedServer ///< A Dedicated Server which does not locally host any clients + Uninitialized, //!< Agent is uninitialized. + Client, //!< A Client connected to either a server or host. + ClientServer, //!< A Client that also hosts and is the authority of the session + DedicatedServer //!< A Dedicated Server which does not locally host any clients }; - //! Payload detailing aspects of a Connection other services may be interested in + //! @brief Payload detailing aspects of a Connection other services may be interested in struct MultiplayerAgentDatum { bool m_isInvited; @@ -50,7 +50,22 @@ namespace Multiplayer using SessionInitEvent = AZ::Event; using SessionShutdownEvent = AZ::Event; - //! IMultiplayer provides insight into the Multiplayer session and its Agents + //! @class IMultiplayer + //! @brief IMultiplayer provides insight into the Multiplayer session and its Agents + //! + //! IMultiplayer is an AZ::Interface that provides applications access to + //! multiplayer session information and events. IMultiplayer is implemented on the + //! MultiplayerSystemComponent and is used to define and access information about + //! the type of session and the role held by the current agent. An Agent is defined + //! here as an actor in a session. Types of Agents included by default are a Client, + //! a Client Server and a Dedicated Server. + //! + //! IMultiplayer also provides events to allow developers to receive and respond to + //! notifications relating to the session. These include Session Init and Shutdown + //! and on acquisition of a new connection. These events are only fired on Client + //! Server or Dedicated Server. These events are useful for services that talk to + //! matchmaking services that may run in an entirely different layer which may need + //! insight to the gameplay session. class IMultiplayer { public: diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h index c621808f7a..92c8cf3456 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayerTools.h @@ -16,7 +16,11 @@ namespace Multiplayer { - //! IMultiplayer provides insight into the Multiplayer session and its Agents + //! @class IMultiplayerTools + //! @brief IMultiplayerTools provides interfacing between the Editor and Multiplayer Gem. + //! + //! IMultiplayerTools is an AZ::Interface that provides information about + //! O3DE Editor and Tools integrations with the Multiplayer Gem. class IMultiplayerTools { public: @@ -27,8 +31,8 @@ namespace Multiplayer virtual ~IMultiplayerTools() = default; - //! Returns if network prefab processing has created currently active or pending spawnables - //! @return If network prefab processing has created currently active or pending spawnables + //! @brief Whether or not network prefab processing has created active or pending spawnable prefabs. + //! @return `true` if network prefab processing has created currently active or pending spawnables. virtual bool DidProcessNetworkPrefabs() = 0; private: diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp index 8542288b23..2ad883c7e7 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerComponent.cpp @@ -46,24 +46,24 @@ namespace Multiplayer return m_netBindComponent ? m_netBindComponent->GetNetEntityId() : InvalidNetEntityId; } - bool MultiplayerComponent::IsAuthority() const + bool MultiplayerComponent::IsNetEntityRoleAuthority() const { - return m_netBindComponent ? m_netBindComponent->IsAuthority() : false; + return m_netBindComponent ? m_netBindComponent->IsNetEntityRoleAuthority() : false; } - bool MultiplayerComponent::IsAutonomous() const + bool MultiplayerComponent::IsNetEntityRoleAutonomous() const { - return m_netBindComponent ? m_netBindComponent->IsAutonomous() : false; + return m_netBindComponent ? m_netBindComponent->IsNetEntityRoleAutonomous() : false; } - bool MultiplayerComponent::IsServer() const + bool MultiplayerComponent::IsNetEntityRoleServer() const { - return m_netBindComponent ? m_netBindComponent->IsServer() : false; + return m_netBindComponent ? m_netBindComponent->IsNetEntityRoleServer() : false; } - bool MultiplayerComponent::IsClient() const + bool MultiplayerComponent::IsNetEntityRoleClient() const { - return m_netBindComponent ? m_netBindComponent->IsClient() : false; + return m_netBindComponent ? m_netBindComponent->IsNetEntityRoleClient() : false; } ConstNetworkEntityHandle MultiplayerComponent::GetEntityHandle() const diff --git a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp b/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp index b0bafccf79..071dfd4ee2 100644 --- a/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp +++ b/Gems/Multiplayer/Code/Source/Components/MultiplayerController.cpp @@ -29,12 +29,12 @@ namespace Multiplayer bool MultiplayerController::IsAuthority() const { - return GetNetBindComponent() ? GetNetBindComponent()->IsAuthority() : false; + return GetNetBindComponent() ? GetNetBindComponent()->IsNetEntityRoleAuthority() : false; } bool MultiplayerController::IsAutonomous() const { - return GetNetBindComponent() ? GetNetBindComponent()->IsAutonomous() : false; + return GetNetBindComponent() ? GetNetBindComponent()->IsNetEntityRoleAutonomous() : false; } AZ::Entity* MultiplayerController::GetEntity() const diff --git a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp index 0847d42dd6..352bc92d1c 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp @@ -54,69 +54,72 @@ namespace Multiplayer ->Attribute(AZ::Script::Attributes::Module, "multiplayer") ->Attribute(AZ::Script::Attributes::Category, "Multiplayer") - ->Method("IsAuthority", [](AZ::EntityId id) -> bool { + ->Method("IsNetEntityRoleAuthority", [](AZ::EntityId id) -> bool { AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); if (!entity) { - AZ_Warning( "NetBindComponent", false, "NetBindComponent IsAuthority failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleAuthority failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) return false; } NetBindComponent* netBindComponent = entity-> FindComponent(); if (!netBindComponent) { - AZ_Warning( "NetBindComponent", false, "NetBindComponent IsAuthority failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) + AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleAuthority failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) return false; } - return netBindComponent->IsAuthority(); + return netBindComponent->IsNetEntityRoleAuthority(); }) - ->Method("IsAutonomous", [](AZ::EntityId id) -> bool { + + ->Method("IsNetEntityRoleAutonomous", [](AZ::EntityId id) -> bool { AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); if (!entity) { - AZ_Warning( "NetBindComponent", false, "NetBindComponent IsAutonomous failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleAutonomous failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) return false; } NetBindComponent* netBindComponent = entity->FindComponent(); if (!netBindComponent) { - AZ_Warning("NetBindComponent", false, "NetBindComponent IsAutonomous failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) + AZ_Warning("NetBindComponent", false, "NetBindComponent IsNetEntityRoleAutonomous failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) return false; } - return netBindComponent->IsAutonomous(); + return netBindComponent->IsNetEntityRoleAutonomous(); }) - ->Method("IsClient", [](AZ::EntityId id) -> bool { + + ->Method("IsNetEntityRoleClient", [](AZ::EntityId id) -> bool { AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); if (!entity) { - AZ_Warning( "NetBindComponent", false, "NetBindComponent IsClient failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleClient failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) return false; } NetBindComponent* netBindComponent = entity->FindComponent(); if (!netBindComponent) { - AZ_Warning("NetBindComponent", false, "NetBindComponent IsClient failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) + AZ_Warning("NetBindComponent", false, "NetBindComponent IsNetEntityRoleClient failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) return false; } - return netBindComponent->IsClient(); + return netBindComponent->IsNetEntityRoleClient(); }) - ->Method("IsServer", [](AZ::EntityId id) -> bool { + + ->Method("IsNetEntityRoleServer", [](AZ::EntityId id) -> bool { AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); if (!entity) { - AZ_Warning( "NetBindComponent", false, "NetBindComponent IsServer failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleServer failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) return false; } NetBindComponent* netBindComponent = entity->FindComponent(); if (!netBindComponent) { - AZ_Warning("NetBindComponent", false, "NetBindComponent IsServer failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) + AZ_Warning("NetBindComponent", false, "NetBindComponent IsNetEntityRoleServer failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str()) return false; } - return netBindComponent->IsServer(); + return netBindComponent->IsNetEntityRoleServer(); }) ; } @@ -179,23 +182,23 @@ namespace Multiplayer return m_netEntityRole; } - bool NetBindComponent::IsAuthority() const + bool NetBindComponent::IsNetEntityRoleAuthority() const { return (m_netEntityRole == NetEntityRole::Authority); } - bool NetBindComponent::IsAutonomous() const + bool NetBindComponent::IsNetEntityRoleAutonomous() const { return (m_netEntityRole == NetEntityRole::Autonomous) || (m_netEntityRole == NetEntityRole::Authority) && m_allowAutonomy; } - bool NetBindComponent::IsServer() const + bool NetBindComponent::IsNetEntityRoleServer() const { return (m_netEntityRole == NetEntityRole::Server); } - bool NetBindComponent::IsClient() const + bool NetBindComponent::IsNetEntityRoleClient() const { return (m_netEntityRole == NetEntityRole::Client); } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index b0f1b221e8..3405abdc57 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -96,7 +96,7 @@ namespace Multiplayer { AZ_Assert(entityHandle.GetNetBindComponent(), "No NetBindComponent found on networked entity"); [[maybe_unused]] const bool isClientOnlyEntity = false;// (ServerIdFromEntityId(it->first) == InvalidHostId); - AZ_Assert(entityHandle.GetNetBindComponent()->IsAuthority() || isClientOnlyEntity, "Trying to delete a proxy entity, this will lead to issues deserializing entity updates"); + AZ_Assert(entityHandle.GetNetBindComponent()->IsNetEntityRoleAuthority() || isClientOnlyEntity, "Trying to delete a proxy entity, this will lead to issues deserializing entity updates"); } m_removeList.push_back(entityHandle.GetNetEntityId()); m_removeEntitiesEvent.Enqueue(AZ::TimeMs{ 0 }); diff --git a/Gems/MultiplayerCompression/Code/multiplayercompression.waf_files b/Gems/MultiplayerCompression/Code/multiplayercompression.waf_files deleted file mode 100644 index f961725685..0000000000 --- a/Gems/MultiplayerCompression/Code/multiplayercompression.waf_files +++ /dev/null @@ -1,22 +0,0 @@ -{ - "none": { - "Source": [ - "Source/MultiplayerCompression_precompiled.cpp", - "Source/MultiplayerCompression_precompiled.h" - ] - }, - "auto": { - "Include": [ - "Include/MultiplayerCompression/MultiplayerCompressionBus.h" - ], - "Source": [ - "Source/LZ4Compressor.cpp", - "Source/LZ4Compressor.h", - "Source/MultiplayerCompressionFactory.cpp", - "Source/MultiplayerCompressionFactory.h", - "Source/MultiplayerCompressionModule.cpp", - "Source/MultiplayerCompressionSystemComponent.cpp", - "Source/MultiplayerCompressionSystemComponent.h" - ] - } -} diff --git a/Gems/MultiplayerCompression/Code/multiplayercompression_tests.waf_files b/Gems/MultiplayerCompression/Code/multiplayercompression_tests.waf_files deleted file mode 100644 index 9750bb9de1..0000000000 --- a/Gems/MultiplayerCompression/Code/multiplayercompression_tests.waf_files +++ /dev/null @@ -1,7 +0,0 @@ -{ - "auto": { - "Tests": [ - "Tests/MultiplayerCompressionTest.cpp" - ] - } -} diff --git a/Gems/MultiplayerCompression/Code/wscript b/Gems/MultiplayerCompression/Code/wscript deleted file mode 100644 index a455ca3c7b..0000000000 --- a/Gems/MultiplayerCompression/Code/wscript +++ /dev/null @@ -1,23 +0,0 @@ - -######################################################################################## -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# -######################################################################################## - -def build(bld): - bld.DefineGem( - # Add custom build options here - includes = [bld.Path('Code/CryEngine/CryAction'), - bld.Path('Code/CryEngine/CryCommon')], - export_includes = [bld.Path('Gems/MultiplayerCompression/Code/Include')], - uselib = ['LZ4'], - defines = ['ENABLE_MULTIPLAYER_COMPRESSION'], - file_list = ['multiplayercompression.waf_files'], - ) diff --git a/Gems/NvCloth/Code/Platform/Android/PAL_android.cmake b/Gems/NvCloth/Code/Platform/Android/PAL_android.cmake index 6afc02a90d..9be24de90b 100644 --- a/Gems/NvCloth/Code/Platform/Android/PAL_android.cmake +++ b/Gems/NvCloth/Code/Platform/Android/PAL_android.cmake @@ -9,6 +9,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev1-multiplatform TARGETS NvCloth PACKAGE_HASH 05fc62634ca28644e7659a89e97f4520d791e6ddf4b66f010ac669e4e2ed4454) +ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev2-multiplatform TARGETS NvCloth PACKAGE_HASH 535d927782fa5d3086c5f813c46392ee3c294fc117dcd87b055d469c3f034356) set(PAL_TRAIT_NVCLOTH_USE_STUB FALSE) diff --git a/Gems/NvCloth/Code/Platform/Linux/PAL_linux.cmake b/Gems/NvCloth/Code/Platform/Linux/PAL_linux.cmake index 6afc02a90d..9be24de90b 100644 --- a/Gems/NvCloth/Code/Platform/Linux/PAL_linux.cmake +++ b/Gems/NvCloth/Code/Platform/Linux/PAL_linux.cmake @@ -9,6 +9,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev1-multiplatform TARGETS NvCloth PACKAGE_HASH 05fc62634ca28644e7659a89e97f4520d791e6ddf4b66f010ac669e4e2ed4454) +ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev2-multiplatform TARGETS NvCloth PACKAGE_HASH 535d927782fa5d3086c5f813c46392ee3c294fc117dcd87b055d469c3f034356) set(PAL_TRAIT_NVCLOTH_USE_STUB FALSE) diff --git a/Gems/NvCloth/Code/Platform/Mac/PAL_mac.cmake b/Gems/NvCloth/Code/Platform/Mac/PAL_mac.cmake index 6afc02a90d..9be24de90b 100644 --- a/Gems/NvCloth/Code/Platform/Mac/PAL_mac.cmake +++ b/Gems/NvCloth/Code/Platform/Mac/PAL_mac.cmake @@ -9,6 +9,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev1-multiplatform TARGETS NvCloth PACKAGE_HASH 05fc62634ca28644e7659a89e97f4520d791e6ddf4b66f010ac669e4e2ed4454) +ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev2-multiplatform TARGETS NvCloth PACKAGE_HASH 535d927782fa5d3086c5f813c46392ee3c294fc117dcd87b055d469c3f034356) set(PAL_TRAIT_NVCLOTH_USE_STUB FALSE) diff --git a/Gems/NvCloth/Code/Platform/Windows/PAL_windows.cmake b/Gems/NvCloth/Code/Platform/Windows/PAL_windows.cmake index 5a4d953220..56e593c4e8 100644 --- a/Gems/NvCloth/Code/Platform/Windows/PAL_windows.cmake +++ b/Gems/NvCloth/Code/Platform/Windows/PAL_windows.cmake @@ -11,4 +11,4 @@ set(PAL_TRAIT_NVCLOTH_USE_STUB FALSE) -ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev1-multiplatform TARGETS NvCloth PACKAGE_HASH 05fc62634ca28644e7659a89e97f4520d791e6ddf4b66f010ac669e4e2ed4454) +ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev2-multiplatform TARGETS NvCloth PACKAGE_HASH 535d927782fa5d3086c5f813c46392ee3c294fc117dcd87b055d469c3f034356) diff --git a/Gems/NvCloth/Code/Platform/iOS/PAL_ios.cmake b/Gems/NvCloth/Code/Platform/iOS/PAL_ios.cmake index 6afc02a90d..9be24de90b 100644 --- a/Gems/NvCloth/Code/Platform/iOS/PAL_ios.cmake +++ b/Gems/NvCloth/Code/Platform/iOS/PAL_ios.cmake @@ -9,6 +9,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev1-multiplatform TARGETS NvCloth PACKAGE_HASH 05fc62634ca28644e7659a89e97f4520d791e6ddf4b66f010ac669e4e2ed4454) +ly_associate_package(PACKAGE_NAME NvCloth-1.1.6-rev2-multiplatform TARGETS NvCloth PACKAGE_HASH 535d927782fa5d3086c5f813c46392ee3c294fc117dcd87b055d469c3f034356) set(PAL_TRAIT_NVCLOTH_USE_STUB FALSE) diff --git a/Gems/PhysX/Code/Editor/DebugDraw.cpp b/Gems/PhysX/Code/Editor/DebugDraw.cpp index 829b776e28..1f1c24b9ad 100644 --- a/Gems/PhysX/Code/Editor/DebugDraw.cpp +++ b/Gems/PhysX/Code/Editor/DebugDraw.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,15 @@ namespace PhysX return false; } + bool IsDrawColliderReadOnly() + { + bool helpersVisible = false; + AzToolsFramework::EditorRequestBus::BroadcastResult(helpersVisible, + &AzToolsFramework::EditorRequests::DisplayHelpersVisible); + // if helpers are visible, draw colliders is NOT read only and can be changed. + return !helpersVisible; + } + static void BuildAABBVerts(const AZ::Aabb& aabb, AZStd::vector& verts, AZStd::vector& points, @@ -145,28 +155,42 @@ namespace PhysX "PhysX Collider Debug Draw", "Manages global and per-collider debug draw settings and logic") ->DataElement(AZ::Edit::UIHandlers::CheckBox, &Collider::m_locallyEnabled, "Draw collider", "Shows the geometry for the collider in the viewport") - ->Attribute(AZ::Edit::Attributes::CheckboxTooltip, - "If set, the geometry of this collider is visible in the viewport") - ->Attribute(AZ::Edit::Attributes::Visibility, - VisibilityFunc{ []() { return IsGlobalColliderDebugCheck(GlobalCollisionDebugState::Manual); } }) + ->Attribute(AZ::Edit::Attributes::CheckboxTooltip, + "If set, the geometry of this collider is visible in the viewport. 'Draw Helpers' needs to be enabled to use.") + ->Attribute(AZ::Edit::Attributes::Visibility, + VisibilityFunc{ []() { return IsGlobalColliderDebugCheck(GlobalCollisionDebugState::Manual); } }) + ->Attribute(AZ::Edit::Attributes::ReadOnly, &IsDrawColliderReadOnly) ->DataElement(AZ::Edit::UIHandlers::Button, &Collider::m_globalButtonState, "Draw collider", "Shows the geometry for the collider in the viewport") - ->Attribute(AZ::Edit::Attributes::ButtonText, "Global override") - ->Attribute(AZ::Edit::Attributes::ButtonTooltip, - "A global setting is overriding this property (to disable the override, " - "set the Global Collision Debug setting to \"Set manually\" in the PhysX Configuration)") - ->Attribute(AZ::Edit::Attributes::Visibility, - VisibilityFunc{ []() { return !IsGlobalColliderDebugCheck(GlobalCollisionDebugState::Manual); } }) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &OpenPhysXSettingsWindow) + ->Attribute(AZ::Edit::Attributes::ButtonText, "Global override") + ->Attribute(AZ::Edit::Attributes::ButtonTooltip, + "A global setting is overriding this property (to disable the override, " + "set the Global Collision Debug setting to \"Set manually\" in the PhysX Configuration)." + "'Draw Helpers' needs to be enabled to use.") + ->Attribute(AZ::Edit::Attributes::Visibility, + VisibilityFunc{ []() { return !IsGlobalColliderDebugCheck(GlobalCollisionDebugState::Manual); } }) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &OpenPhysXSettingsWindow) + ->Attribute(AZ::Edit::Attributes::ReadOnly, &IsDrawColliderReadOnly) ; } } } + Collider::Collider() + : m_debugDisplayDataChangedEvent( + [this]([[maybe_unused]] const PhysX::Debug::DebugDisplayData& data) + { + this->RefreshTreeHelper(); + }) + { + + } + void Collider::Connect(AZ::EntityId entityId) { m_entityId = entityId; AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityId); + AzToolsFramework::EntitySelectionEvents::Bus::Handler::BusConnect(m_entityId); } void Collider::SetDisplayCallback(const DisplayCallback* callback) @@ -176,6 +200,11 @@ namespace PhysX void Collider::Disconnect() { + if (AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Handler::BusIsConnected()) + { + AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Handler::BusDisconnect(); + } + AzToolsFramework::EntitySelectionEvents::Bus::Handler::BusDisconnect(); AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(); m_displayCallback = nullptr; m_entityId = AZ::EntityId(); @@ -731,6 +760,33 @@ namespace PhysX } } + void Collider::OnDrawHelpersChanged([[maybe_unused]] bool enabled) + { + RefreshTreeHelper(); + } + + void Collider::OnSelected() + { + AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Handler::BusConnect( + AzFramework::g_defaultSceneEntityDebugDisplayId); + if (auto* physXDebug = AZ::Interface::Get()) + { + physXDebug->RegisterDebugDisplayDataChangedEvent(m_debugDisplayDataChangedEvent); + } + } + + void Collider::OnDeselected() + { + AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Handler::BusDisconnect(); + m_debugDisplayDataChangedEvent.Disconnect(); + } + + void Collider::RefreshTreeHelper() + { + AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( + &AzToolsFramework::ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues); + } + AZStd::string Collider::GetEntityName() const { AZStd::string entityName; diff --git a/Gems/PhysX/Code/Editor/DebugDraw.h b/Gems/PhysX/Code/Editor/DebugDraw.h index c43634717a..34b3b57667 100644 --- a/Gems/PhysX/Code/Editor/DebugDraw.h +++ b/Gems/PhysX/Code/Editor/DebugDraw.h @@ -15,8 +15,11 @@ #include #include #include +#include +#include #include #include +#include namespace PhysX { @@ -40,13 +43,15 @@ namespace PhysX class Collider : protected AzFramework::EntityDebugDisplayEventBus::Handler + , protected AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Handler + , protected AzToolsFramework::EntitySelectionEvents::Bus::Handler { public: AZ_CLASS_ALLOCATOR(Collider, AZ::SystemAllocator, 0); AZ_RTTI(Collider, "{7DE9CA01-DF1E-4D72-BBF4-76C9136BE6A2}"); static void Reflect(AZ::ReflectContext* context); - Collider() = default; + Collider(); void Connect(AZ::EntityId entityId); void SetDisplayCallback(const DisplayCallback* callback); @@ -109,11 +114,20 @@ namespace PhysX const AZStd::vector& GetIndices(AZ::u32 geomIndex) const; protected: - // AzFramework::EntityDebugDisplayEventBus + // AzFramework::EntityDebugDisplayEventBus overrides ... void DisplayEntityViewport( const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; + // AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Handler overrides ... + void OnDrawHelpersChanged(bool enabled) override; + + // AzToolsFramework::EntitySelectionEvents::Bus::Handler overrides ... + void OnSelected() override; + void OnDeselected() override; + + void RefreshTreeHelper(); + // Internal mesh drawing subroutines void DrawTriangleMesh( AzFramework::DebugDisplayRequests& debugDisplay, const Physics::ColliderConfiguration& colliderConfig, AZ::u32 geomIndex, @@ -143,6 +157,8 @@ namespace PhysX }; mutable AZStd::vector m_geometry; + + PhysX::Debug::DebugDisplayDataChangedEvent::Handler m_debugDisplayDataChangedEvent; }; } // namespace DebugDraw } // namespace PhysX diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 356ee22ba3..88bd5292d6 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -2177,7 +2177,10 @@ namespace ScriptCanvas { for (auto& latent : nodeableParse.second->m_latents) { - roots.push_back(AZStd::const_pointer_cast(latent.second)); + if (latent.second) + { + roots.push_back(AZStd::const_pointer_cast(latent.second)); + } } } @@ -2185,23 +2188,35 @@ namespace ScriptCanvas { for (auto& event : eventHandlerParse.second->m_events) { - roots.push_back(AZStd::const_pointer_cast(event.second)); + if (event.second) + { + roots.push_back(AZStd::const_pointer_cast(event.second)); + } } } for (auto& eventHandlerParse : m_eventHandlingByNode) { - roots.push_back(AZStd::const_pointer_cast(eventHandlerParse.second->m_eventHandlerFunction)); + if (eventHandlerParse.second->m_eventHandlerFunction) + { + roots.push_back(AZStd::const_pointer_cast(eventHandlerParse.second->m_eventHandlerFunction)); + } } for (auto variableWriteHandling : m_variableWriteHandlingBySlot) { - roots.push_back(AZStd::const_pointer_cast(variableWriteHandling.second->m_function)); + if (variableWriteHandling.second->m_function) + { + roots.push_back(AZStd::const_pointer_cast(variableWriteHandling.second->m_function)); + } } for (auto function : m_functions) { - roots.push_back(AZStd::const_pointer_cast(function)); + if (function) + { + roots.push_back(AZStd::const_pointer_cast(function)); + } } return roots; diff --git a/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake b/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake index a0b2185190..a48714849b 100644 --- a/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake +++ b/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake @@ -23,7 +23,7 @@ ly_associate_package(PACKAGE_NAME lux_core-2.2-rev5-multiplatform TARGETS lux # platform-specific: ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-android TARGETS freetype PACKAGE_HASH 74dd75382688323c3a2a5090f473840b5d7e9d2aed1a4fcdff05ed2a09a664f2) ly_associate_package(PACKAGE_NAME tiff-4.2.0.14-android TARGETS tiff PACKAGE_HASH a9b30a1980946390c2fad0ed94562476a1d7ba8c1f36934ae140a89c54a8efd0) -ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev3-android TARGETS AWSNativeSDK PACKAGE_HASH e2192157534cc8c4e22769545d88dff03ec6c1031599716ef63de3ebbb8c9a44) +ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev4-android TARGETS AWSNativeSDK PACKAGE_HASH 9d163696591a836881fc22dac3c94e57b0278771b6c6cec807ff6a5e96f2669d) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-android TARGETS Lua PACKAGE_HASH 1f638e94a17a87fe9e588ea456d5893876094b4db191234380e4c4eb9e06c300) ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-android TARGETS PhysX PACKAGE_HASH b8cb6aa46b2a21671f6cb1f6a78713a3ba88824d0447560ff5ce6c01014b9f43) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-android TARGETS mikkelsen PACKAGE_HASH 075e8e4940884971063b5a9963014e2e517246fa269c07c7dc55b8cf2cd99705) diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake index 2f001cf7ee..7e45fa6bba 100644 --- a/cmake/Packaging.cmake +++ b/cmake/Packaging.cmake @@ -28,7 +28,7 @@ set(CPACK_DESIRED_CMAKE_VERSION 3.20.2) # pre/post build set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") set(CPACK_PACKAGE_FULL_NAME "Open3D Engine") -set(CPACK_PACKAGE_VENDOR "TBD") +set(CPACK_PACKAGE_VENDOR "O3DE Binary Project a Series of LF Projects, LLC") set(CPACK_PACKAGE_VERSION "${LY_VERSION_STRING}") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Installation Tool") diff --git a/cmake/Platform/Common/Clang/Configurations_clang.cmake b/cmake/Platform/Common/Clang/Configurations_clang.cmake index 4f9b3154e6..2c20e4636b 100644 --- a/cmake/Platform/Common/Clang/Configurations_clang.cmake +++ b/cmake/Platform/Common/Clang/Configurations_clang.cmake @@ -54,6 +54,8 @@ ly_append_configurations_options( -g # debug symbols COMPILATION_RELEASE -O2 + LINK_NON_STATIC + -Wl,-undefined,error ) include(cmake/Platform/Common/TargetIncludeSystemDirectories_supported.cmake) diff --git a/cmake/Platform/Linux/Configurations_linux.cmake b/cmake/Platform/Linux/Configurations_linux.cmake index cca363590e..d3e639e714 100644 --- a/cmake/Platform/Linux/Configurations_linux.cmake +++ b/cmake/Platform/Linux/Configurations_linux.cmake @@ -21,8 +21,6 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") COMPILATION -fPIC -msse4.1 - LINK_NON_STATIC - -Wl,--no-undefined ) ly_set(CMAKE_CXX_EXTENSIONS OFF) else() diff --git a/cmake/Platform/Mac/Configurations_mac.cmake b/cmake/Platform/Mac/Configurations_mac.cmake index 007c13cd6d..85b0b7e92e 100644 --- a/cmake/Platform/Mac/Configurations_mac.cmake +++ b/cmake/Platform/Mac/Configurations_mac.cmake @@ -20,7 +20,6 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") __APPLE__ DARWIN LINK_NON_STATIC - -Wl,-undefined,error -headerpad_max_install_names -lpthread -lncurses diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 6ad428c08d..25418bf6cf 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -105,12 +105,10 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") endif() endif() if(anything_new) + unset(fixup_bundle_ignore) # LYN-4505: Patch dxc, is configured in the wrong folder in 3p if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) - # we copy to not invalidate the copy check from above - file(COPY ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/lib/libdxcompiler.3.7.dylib - DESTINATION ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin - ) + list(APPEND fixup_bundle_ignore dxc-3.7) endif() # Python.framework being copied by fixup_bundle #if(EXISTS ${bundle_path}/Contents/Frameworks/Python.framework) @@ -139,8 +137,17 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") #endif() list(REMOVE_DUPLICATES plugin_libs) list(REMOVE_DUPLICATES plugin_dirs) - fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}") + fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}" IGNORE_ITEM ${fixup_bundle_ignore}) file(TOUCH "${bundle_path}") file(TOUCH "${fixup_timestamp_file}") + + # fixup bundle ends up removing the rpath of dxc (despite we exclude it) + if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) + find_program(LY_INSTALL_NAME_TOOL install_name_tool) + if (NOT LY_INSTALL_NAME_TOOL) + message(FATAL_ERROR "Unable to locate 'install_name_tool'") + endif() + execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) + endif() endif() endif() diff --git a/cmake/Platform/Windows/Packaging/Shortcuts.wxs b/cmake/Platform/Windows/Packaging/Shortcuts.wxs index fb9d359b5a..283a3c08ea 100644 --- a/cmake/Platform/Windows/Packaging/Shortcuts.wxs +++ b/cmake/Platform/Windows/Packaging/Shortcuts.wxs @@ -7,7 +7,7 @@ - + @@ -46,10 +46,20 @@ - + + + + + Name="$(var.CPACK_PACKAGE_NAME) Project Manager" /> diff --git a/scripts/build/Platform/Linux/build_config.json b/scripts/build/Platform/Linux/build_config.json index 59b72ec4b0..0e388e712c 100644 --- a/scripts/build/Platform/Linux/build_config.json +++ b/scripts/build/Platform/Linux/build_config.json @@ -83,7 +83,7 @@ "CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "all", - "CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSCore.Editor.Tests) -LE SUITE_sandbox -L FRAMEWORK_googletest" + "CTEST_OPTIONS": "-E Gem::EMotionFX.Editor.Tests -LE SUITE_sandbox -L FRAMEWORK_googletest" } }, "test_profile_nounity": { @@ -95,7 +95,7 @@ "CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "all", - "CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSCore.Editor.Tests) -LE SUITE_sandbox -L FRAMEWORK_googletest" + "CTEST_OPTIONS": "-E Gem::EMotionFX.Editor.Tests -LE SUITE_sandbox -L FRAMEWORK_googletest" } }, "asset_profile": { diff --git a/scripts/migration/non_uniform_scale.py b/scripts/migration/non_uniform_scale.py new file mode 100644 index 0000000000..038cb1144b --- /dev/null +++ b/scripts/migration/non_uniform_scale.py @@ -0,0 +1,68 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +import sys +import azlmbr +from pathlib import Path + +def fixup_current_level(threshold): + nonUniformScaleComponentId = azlmbr.editor.EditorNonUniformScaleComponentTypeId + + # iterate over all entities in the level + entityIdList = azlmbr.entity.SearchBus(azlmbr.bus.Broadcast, 'SearchEntities', azlmbr.entity.SearchFilter()) + for entityId in entityIdList: + name = azlmbr.editor.EditorEntityInfoRequestBus(azlmbr.bus.Event, 'GetName', entityId) + local = azlmbr.components.TransformBus(azlmbr.bus.Event, 'GetLocalScale', entityId) + + # only process entities where the non-uniformity is greater than the threshold + local_max = max(local.x, local.y, local.z) + local_min = min(local.x, local.y, local.z) + if local_max / local_min > 1 + threshold: + + # check if there is already a Non-uniform Scale component + getComponentOutcome = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'GetComponentOfType', entityId, nonUniformScaleComponentId) + if getComponentOutcome.IsSuccess(): + print(f"skipping {name} as it already has a Non-uniform Scale component") + + else: + # add Non-uniform Scale component and set it to the non-uniform part of the local scale + azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast,'AddComponentsOfType', entityId, [nonUniformScaleComponentId]) + vec = azlmbr.math.Vector3(local.x / local_max, local.y / local_max, local.z / local_max) + azlmbr.entity.NonUniformScaleRequestBus(azlmbr.bus.Event, 'SetScale', entityId, vec) + print(f"added non-uniform scale component for {name}: {local.x}, {local.y}, {local.z}") + +if __name__ == '__main__': + # handle the arguments manually since argparse causes problems when run through EditorPythonBindings + process_all_levels = "--all" in sys.argv + + # ignore entities where the relative difference between the min and max scale values is less than this threshold + threshold = 0.001 + for i in range(len(sys.argv) - 1): + if sys.argv[i] == "--threshold": + try: + threshold = float(sys.argv[i + 1]) + except ValueError: + print(f"invalid threshold value {sys.argv[i + 1]}, using default value {threshold}") + pass + + if process_all_levels: + game_folder = Path(azlmbr.legacy.general.get_game_folder()) + level_folder = game_folder / 'Levels' + levels = [str(level) for level in level_folder.rglob('*.ly')] + [str(level) for level in level_folder.rglob('*.cry')] + for level in levels: + if "_savebackup" not in level: + print(f'loading level {level}') + azlmbr.legacy.general.open_level_no_prompt(level) + azlmbr.legacy.general.idle_wait(2.0) + fixup_current_level(threshold) + azlmbr.legacy.general.save_level() + else: + fixup_current_level(threshold)